
Lesson 2: Analog input
What you need
- Arduino UNO R3
- USB cable
- A potentiometer (knob)
- Three jumper wires
Wire it, then check it
Attach the knob’s middle pin to A0 and its outer pins to 5V and GND5.
Not working on a real board? Start with the wiring checklist.
Arduino version
l2-read-arduino.ino// Lesson 2, Arduino version: read the knob on A0 and
// print the reading.
void setup() {
Serial.begin(115200);
}
void loop() {
int reading = analogRead(A0); // 0 to 1023 on the UNO R3
Serial.println(reading);
delay(20);
}analogRead(A0) starts a conversion on A0 and waits until it finishes3.
Register version
l2-read-registers.ino// Lesson 2, register version: the same reading, done with
// the ADC registers.
void setup() {
Serial.begin(115200);
// Reference AVCC, input ADC0 (A0), result right-adjusted
ADMUX = (1 << REFS0);
// Turn the ADC on, with its clock at 16 MHz / 128
ADCSRA = (1 << ADEN)
| (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
void loop() {
ADCSRA |= (1 << ADSC); // start one conversion
while (ADCSRA & (1 << ADSC)) {} // ADSC stays 1 until done
uint8_t low = ADCL; // read ADCL first
uint8_t high = ADCH;
int reading = (high << 8) | low;
Serial.println(reading);
delay(20);
}In ADMUX, REFS1:0 = 01 selects AVCC as the reference, and MUX3:0 = 0000 selects input ADC0. In ADCSRA, ADEN turns the ADC on, ADPS2:0 = 111 divides its clock by 128, and writing 1 to ADSC starts a conversion. ADSC reads as 1 until the conversion finishes2. The result is ADC = VIN × 1024 / VREF. Read ADCL first, then ADCH2.
Registers in this lesson (ATmega328P data-space addresses)2
| Register | Address | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|---|---|
| ADMUX | 0x7C | REFS1 | REFS0 | ADLAR | – | MUX3 | MUX2 | MUX1 | MUX0 |
| ADCSRA | 0x7A | ADEN | ADSC | ADATE | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 |
| ADCH | 0x79 | – | – | – | – | – | – | ADC9 | ADC8 |
| ADCL | 0x78 | ADC7 | ADC6 | ADC5 | ADC4 | ADC3 | ADC2 | ADC1 | ADC0 |
Run it in the lab
Turn the knob and watch ADCH and ADCL change. At 2.5 V both programs print 5122.
Drill
What is the largest number
analogRead()returns on an UNO R3?With the knob at 2.5 V, what does the sketch print?
Show the answer
512. ADC = VIN × 1024 / VREF = 2.5 × 1024 / 5. 2
Why read ADCL before ADCH?
Show the answer
So both halves come from the same conversion. Arduino’s own
analogReadreads ADCL first. 3
Sources
- Arduino reference: analogRead
- Microchip ATmega328P datasheet DS40002061A: §24.7 ADC conversion result (p256); Table 24-3 (p257); ADEN and ADSC (p258)
- ArduinoCore-avr, cores/arduino/wiring_analog.c
- Bedillion & Muci-Küchler, ASEE 2018: SDSM&T ME-265, 25 students
- Arduino example: AnalogReadSerial: potentiometer wiring
- Arduino reference: analogWrite: values 0 to 255