What the number means
The number analogRead returns is a fraction of the ADC's range, not a voltage. Its top is 1023 on a 10-bit ADC and 4095 on a 12-bit one, and on an Uno, where the ADC measures against the same 5 V that feeds the block, the fraction is the wheel's position whatever that 5 V really is.
A fraction, not a voltage
An ADC, an analog-to-digital converter, compares the voltage on its pin with a reference voltage and reports where the pin sits between 0 V and that reference, as a whole number. The number of steps is set by its bits. The Uno's ADC is 10-bit, so it has 1024 steps and full scale is 1023. The ESP32's and the ESP32-S3's are 12-bit, so full scale is 4095. The Pico's is 12-bit too, but the Arduino core reads it as 10-bit unless you ask for more.
That is the whole reason ADC_MAX is in every sketch here. A sketch written
for 1023 on an ESP32 thinks it has reached the top a quarter of the way round.
One written for 4095 on an Uno never gets past a quarter.
Why the Uno does not care what 5 V is
Move your board's supply today in the figure with the Uno picked. A USB port that gives 4.8 V instead of 5.0 V lowers the block's VCC, so SIGNAL drops. But the Uno's ADC measures against its own supply by default, and that dropped by the same proportion. The reading does not move.
This is called a ratiometric reading: the block and the ADC share one reference, so the number is the wheel's position as a fraction, and the supply's exact value cancels out. It only works if VCC comes from the same supply the ADC measures against, which is one more reason to put VCC on the Uno's 5V rather than its 3V3.
The volts are another matter. Work them out as reading * 5.0 / 1023 and they
are wrong by exactly as much as the supply is wrong. For a position you do not
need them.
The Pico is similar: its ADC's reference is the board's own 3.3 V supply, filtered on the board, so a block on the Pico's 3V3 pin reads close to a pure ratio too.
Why the ESP32 does
The two ESP32s measure against a reference inside the chip, not against their
3.3 V supply. So when the supply moves, SIGNAL moves and the reading follows
it. For a pot the difference is small, a rail that is a few percent off moves
the reading a few percent. For measuring an actual voltage it is the better
arrangement, and analogReadMilliVolts() turns the reading into millivolts
using calibration stored in the chip. Reading the
ADC covers it.
When it does not work
Multiply by the ADC's full-scale voltage and divide by ADC_MAX: on an Uno, reading × 5.0 / 1023. It is only as right as the 5.0, and a USB port's 5 V is rarely exactly that. On an ESP32, analogReadMilliVolts() uses the chip's own calibration and is the better answer.
Yes. The RP2040's ADC is 12-bit, and arduino-pico's analogRead returns 10 bits unless you call analogReadResolution(12) in setup(). Then set ADC_MAX to 4095. The Uno cannot: its ADC is 10-bit.
On an Uno they should not, as long as VCC is on the Uno's own 5V: the reading is a ratio and both ends moved together. On an ESP32 a small difference is expected, because its ADC measures against a reference inside the chip and the 3.3 V rail can differ a little between supplies.
An ADC can only give whole numbers. A 10-bit one divides its range into 1024 steps, about 4.9 mV each on an Uno; a 12-bit one into 4096. Turning the wheel by less than one step does not change the number.
Dividing by ADC_MAX, and sending the result to an LED.
A percentage and a brightness →Edit this page — content/books/disc-potentiometer/what-the-number-means.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Disc Potentiometer
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.