For a standard 5V Arduino Uno (ATmega328P, 10-bit resolution), an Arduino A to D converter raw reading of 512 converts to exactly 2.50V. The step size is 4.88 mV per unit. If you are using a 3.3V ESP32 (12-bit resolution), that same physical 2.50V input yields a raw reading of 3103. The exact conversion is entirely fixed by two hardware assumptions: the reference voltage ($V_{ref}$) and the bit-resolution of the specific microcontroller's silicon.
The ADC to Voltage Conversion Formula
To convert the dimensionless integer returned by analogRead() into a real-world voltage, you must multiply the raw value by the voltage per step (the least significant bit, or LSB). The universal formula is:
Voltage = Raw_ADC × (V_ref / 2^n)
Where n is the bit-resolution of the ADC. For the classic Arduino Uno, n = 10, meaning there are $2^{10} = 1024$ discrete steps. Substituting the values for a mid-scale reading:
Voltage = 512 × (5.0V / 1024) = 512 × 0.0048828V = 2.50V
Many tutorials divide by 1023 because 1023 is the maximum integer the 10-bit ADC can output. However, the Microchip ATmega328P datasheet specifies 1024 total steps. The voltage represented by 1023 is actually 4.995V, not 5.000V. Dividing by 1024 yields the mathematically correct step size (4.88 mV) for all calculations.
Neighboring Values Reference Table (±20% Range)
When debugging sensor noise or mapping a specific voltage window (like a 2.0V to 3.0V battery monitor), it helps to see how raw integers map to voltages across different architectures. Below is a ±20% spread around our 512 baseline, comparing the 5V/10-bit Uno against the 3.3V/12-bit ESP32.
| Raw ADC (10-bit) | Voltage (5.0V Ref) | Raw ADC (12-bit) | Voltage (3.3V Ref) |
|---|---|---|---|
| 410 | 2.00V | 2484 | 2.00V |
| 450 | 2.20V | 2730 | 2.20V |
| 491 | 2.40V | 2975 | 2.40V |
| 512 | 2.50V | 3103 | 2.50V |
| 532 | 2.60V | 3224 | 2.60V |
| 573 | 2.80V | 3470 | 2.80V |
| 614 | 3.00V | 3720 | 3.00V |
How the Answer Shifts: From 5V Logic to 120V/230V Mains
The conversion formula assumes the voltage at the microcontroller pin is the actual system voltage. This holds true for low-voltage DC sensors, but shifts dramatically when scaling up to higher voltages or different architectures.
1. 3.3V vs 5V Logic Shifts: If you migrate code from an Uno to a 3.3V board (like the Nano 33 IoT) without updating the $V_{ref}$ variable in your formula, a 2.5V input will calculate as 1.65V. Always define $V_{ref}$ as a constant at the top of your sketch.
2. The 120V / 230V / 3-Phase Shift: You cannot wire 120V AC, 230V AC, or 3-phase mains directly to an Arduino A to D converter—doing so will instantly destroy the silicon and pose a lethal shock hazard. To measure mains voltage, you must use a step-down transformer or an isolation amplifier (like the Texas Instruments AMC1301). The conversion formula must then be multiplied by the hardware scaling ratio. For example, if a 230V RMS mains signal is stepped down to 1.0V RMS via a 230:1 transformer and rectified to 1.414V peak, your software must multiply the ADC result by 230 to reflect the true primary-side voltage.
Never connect AC mains directly to a microcontroller. Always use isolated measurement circuits, double-insulated enclosures, and properly rated fuses. NEC-style guidance requires that any permanent wiring interfacing with service panels be performed or inspected by a licensed electrician.
When the Conversion Becomes Meaningless
An ADC reading is only as good as the analog signal conditioning feeding it. The mathematical conversion becomes entirely meaningless under these three common bench conditions:
- Floating Pins: If an analog pin is not connected to a defined voltage or ground, it acts as an antenna. Readings will scatter randomly from 0 to 1023 due to electromagnetic interference. Always use a pull-down resistor (e.g., 10kΩ to GND) if a sensor might be disconnected.
- Source Impedance > 10kΩ: The ATmega328P ADC uses an internal 14pF sample-and-hold capacitor. If your sensor (like a high-value thermistor divider) has an output impedance greater than 10kΩ, the capacitor cannot fully charge during the sampling window. The ADC will consistently read lower than the actual voltage. Fix this by adding a 100nF ceramic capacitor between the analog pin and GND, or buffer the signal with an op-amp voltage follower.
- Exceeding $V_{ref}$: If you feed 5.5V into an Uno pin referenced to 5.0V, the ADC saturates and outputs 1023. The formula will tell you the voltage is 5.0V, masking the overvoltage condition and potentially damaging the chip's internal clamping diodes.
Frequently Asked Questions
How do I change the Arduino A to D converter reference voltage?
By default, the Uno uses the 5V USB/Barrel jack supply as $V_{ref}$. You can switch to the internal 1.1V reference for higher resolution when measuring small signals (like shunt resistors) by calling analogReference(INTERNAL) in your setup. If you need a precise external reference, feed a clean voltage (e.g., 4.096V from an LM4040) into the AREF pin and use analogReference(EXTERNAL). Never feed more than 5V into AREF.
Why is my ESP32 ADC reading non-linear at the top end?
The ESP32's internal 12-bit ADC is notoriously non-linear, particularly above 2.5V, and suffers from significant unit-to-unit variance. According to the Espressif ADC documentation, you must configure the attenuation to 11dB to read up to ~3.1V, and rely on the ESP-IDF's built-in ADC calibration eFuse data or software lookup tables to linearize the output. For precision DC measurement on an ESP32, bypass the internal ADC entirely and use an I2C external ADC like the ADS1115.
What is the maximum sampling rate for the Arduino Uno ADC?
The ATmega328P ADC requires 13 clock cycles per conversion. With the default prescaler of 128 (which yields a 125kHz ADC clock from the 16MHz system clock), the maximum theoretical sampling rate is roughly 9,600 samples per second (9.6 kS/s). If you lower the prescaler to 16 to achieve a 1MHz ADC clock, you can push the sampling rate to ~76 kS/s, though you will sacrifice roughly 1-2 bits of effective resolution due to increased noise.






