Skip to content

Embedded Systems

How Arduino analogRead works

analogRead(A0) measures the voltage on pin A0 and returns a whole number from 0 to 1023: 0 for 0 V, up to 1023 for 5 V on an Arduino Uno. The chip's analog-to-digital converter (ADC) does it, comparing the voltage against a ruler of 1024 marks about 4.88 mV apart.

A ruler with 1024 marks

digitalRead only says HIGH or LOW. The six pins A0 to A5 can do better: they hold a voltage against a ruler and report the mark it reached. The Uno's ADC has 10 bits, and 2¹⁰ = 1024 steps:

reading = V × 1024 over 5 V

The board rounds down to a whole mark. So 1.25 V reads 256, and 2.5 V reads 512. At 5 V the formula gives 1024, but the largest 10-bit number is 1023, so it stops there.

Live experiment

Turn the knob on A0

A knob's wiper feeds A0. Turn it and watch analogRead's number follow from 0 to 1023, then map() squeeze it into 0–255 for Pip on pin 9. The two rulers keep step.

Try it yourself: free lesson

“Turn a knob” is lesson 6 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. Lessons unlock in order, so you’ll do the 5 before it first.

A knob gives any voltage

A knob, or potentiometer, is a resistor with a slider on it. Its two ends sit at 5 V and GND, and the slider, the wiper, picks up any voltage in between: it's an adjustable voltage divider. Wire the wiper to A0 and turning the knob turns the reading.

Readings to volts, and to brightness

To go back from a reading to volts, divide by the marks and multiply by the range:

V ≈ reading × 5 V over 1024

analogWrite wants 0–255, but analogRead gives 0–1023. map() rescales one range to the other, keeping the fraction:

void setup() {
  Serial.begin(9600);
}

void loop() {
  int reading = analogRead(A0);              // 0 to 1023
  float volts = reading * 5.0 / 1024;        // 5.0 keeps the decimals
  int level = map(reading, 0, 1023, 0, 255); // 0 to 255
  analogWrite(9, level);
  Serial.println(volts);
  delay(200);
}

map() uses whole numbers and rounds down: 256 becomes 63, because 256 × 255 ÷ 1023 ≈ 63.8.

Resolution, not range

Rounding to a mark loses up to 4.88 mV. That's quantisation. More bits mean finer steps, not a bigger range: a 12-bit ADC splits the same 5 V into 4096 steps of about 1.22 mV. To measure more than 5 V, scale it down first with a voltage divider, and never put more than 5 V on the pin itself.

Read the knob inside loop(), not once in setup(), so every pass picks up where it's turned to now.

Free lesson

Now build it yourself

Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.

Try it yourself: free lesson

“Turn a knob” is lesson 6 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. Lessons unlock in order, so you’ll do the 5 before it first.

Or start from the very first lesson, no account needed

Work it out

Practice questions

Three quick questions from the lessons. Pick an answer to check it.

  1. Question 1 of 3analogRead(A0) gives a number between…
    Show the answer

    Answer: 0 and 1023. The ruler has 1024 marks, so the reading runs from 0 for 0 V up to 1023 for 5 V.

    • Why not “0 and 255”? 0 to 255 is analogWrite's range. An Uno's analogRead has 10 bits, so it gives 1024 steps, 0 to 1023.
    • Why not “HIGH and LOW”? HIGH and LOW are what digitalRead gives. analogRead measures the voltage in between and returns a number.
    • Why not “0 and 5”? analogRead gives a step count, not volts. 5 V comes back as 1023, so you convert the reading to volts yourself.
  2. Question 2 of 3Which pins can analogRead measure?
    Show the answer

    Answer: A0 to A5. Only the six analog pins, A0 to A5, are wired to the board's voltage ruler. The others only say HIGH or LOW.

    • Why not “The pins marked ~”? The ~ marks the PWM pins, the ones analogWrite can dim. Measuring a voltage is a different job, done on A0 to A5.
    • Why not “Only pin 13”? Pin 13 is a digital pin, with the built-in L LED on it. It can only read HIGH or LOW, not measure a voltage.
    • Why not “Any pin”? Most pins are digital only: they can just say HIGH or LOW. Only A0 to A5 are wired to the analog-to-digital converter.
  3. Question 3 of 3The knob is halfway round, so analogRead(A0) gives about 512. About what does map(reading, 0, 1023, 0, 255) give?
    Show the answer

    Answer: About 127. map keeps the fraction. Halfway up 0 to 1023 becomes halfway up 0 to 255, about 127, so the LED glows about half bright.

    • Why not “About 512”? 512 is the reading before scaling. map() moves it into 0 to 255 and keeps the fraction, so halfway stays halfway: about 127.
    • Why not “1023”? 1023 is the top of analogRead's range, and map() turns it into 255. Halfway, 512, becomes about 127.
    • Why not “0”? 0 would mean the knob was turned all the way down. Halfway up 0 to 1023 maps to halfway up 0 to 255.
Keep practising: free lesson

“Turn a knob” is lesson 6 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. Lessons unlock in order, so you’ll do the 5 before it first.

Questions people ask

What does analogRead return on an Arduino Uno?

A whole number from 0 to 1023 for a voltage from 0 to 5 V. The Uno's analog-to-digital converter has 10 bits, so it splits the range into 1024 steps of about 4.88 mV each.

How do I convert an analogRead value to volts?

Multiply by 5 and divide by 1024: volts ≈ reading × 5 ÷ 1024. In code, write the 5 as 5.0 so the maths keeps its decimals. A reading of 512 is about 2.5 V.

Why does my LED flicker when I pass analogRead to analogWrite?

analogRead gives 0–1023 but analogWrite takes 0–255. A real Uno uses only the lowest 8 bits, so 256 acts like 0 and the LED goes bright and dark four times as you turn the knob. Scale first with map(reading, 0, 1023, 0, 255), or divide by 4.

Which Arduino pins can use analogRead?

On an Uno, the six analog pins A0 to A5. They're the ones wired to the analog-to-digital converter; the other pins only read HIGH or LOW.

Every topic