For a standard 10-bit analog to digital converter Arduino setup (like the Uno R3 with an ATmega328P) using the default 5.0V reference, an ADC raw reading of 512 converts directly to 2.50V. The exact formula used with values substituted is: Voltage = (512 / 1024) * 5.0V = 2.50V. This calculation assumes a 10-bit resolution (yielding 1024 discrete steps from 0 to 1023) and a perfectly stable 5.0V VREF. If you are using a 3.3V board like the Arduino Due or an ESP32, that same raw reading of 512 converts to 1.65V using the formula (512 / 1024) * 3.3V.
Neighboring Values Reference Table (±20% Range)
When debugging sensor outputs, it helps to know the expected voltage envelope around your target reading. Here is the conversion for a ±20% window around a center raw value of 512.
| Raw ADC Value | Voltage (5.0V VREF) | Voltage (3.3V VREF) |
|---|---|---|
| 410 | 2.00V | 1.32V |
| 461 | 2.25V | 1.48V |
| 512 | 2.50V | 1.65V |
| 563 | 2.75V | 1.81V |
| 614 | 3.00V | 1.97V |
How Reference Voltage and Mains Scaling Shift the Math
The single assumption that fixes your ADC answer is the Reference Voltage (VREF). By default, the Arduino Uno ties VREF to the USB/BARREL power rail (nominally 5V, but often 4.7V to 4.9V depending on USB droop). If you do not measure your actual VREF pin with a multimeter and substitute that exact value into your formula, your converted voltage will drift.
But how does the answer shift when you move beyond low-voltage DC and use the Arduino analogRead() function to measure AC mains via a voltage transformer module (like the ZMPT101B)? The math shifts from absolute DC to scaled RMS AC:
- 120V AC Nominal: The AC waveform peaks at ~170V. Your scaling factor shifts to center around the 512 bias point. The formula becomes
V_RMS = (Raw_ADC - 512) * 0.098(assuming standard ZMPT101B calibration). - 230V AC Nominal: The waveform peaks at ~325V. The transformer core approaches saturation unless you adjust the onboard trimpot. The scaling factor shifts to
V_RMS = (Raw_ADC - 512) * 0.156. - 3-Phase Systems: You cannot use a single internal ADC channel for 3-phase. Sampling three channels sequentially using the internal 10-bit ADC introduces a ~300µs delay between phases. At 60Hz, this creates a 6.48-degree phase-angle error. For 3-phase, the internal conversion math is invalid; you must shift to a simultaneous-sampling external ADC.
When This ADC Conversion Becomes Meaningless
Blindly applying the (Raw / 1024) * VREF formula will yield mathematically correct but physically meaningless numbers under three specific bench conditions:
2. Source Impedance Exceeds 10kΩ: The ATmega328P datasheet specifies that the internal sample-and-hold (S/H) capacitor (approx. 14pF) requires a specific charging time. If your sensor's output impedance is higher than 10kΩ (common with raw thermistors or high-value voltage dividers), the S/H cap won't fully charge before the conversion triggers. The raw ADC value will read artificially low. Fix: Add a 100nF ceramic capacitor between the analog pin and GND to act as a local charge reservoir.
3. ESP32 ADC Non-Linearity: If you are using an ESP32, the internal 12-bit ADC is notoriously non-linear. Readings below 100mV often peg at 0, and readings above 3.1V saturate at 4095. Furthermore, if you are using ADC2 pins while WiFi is active, the readings will fail entirely because the WiFi radio hijacks the ADC2 hardware. For ESP32, the internal conversion is meaningless for precision work; use ADC1 pins only, or switch to an external I2C ADC.
Decision Tree: Upgrading Your Arduino ADC Setup
Use this decision path to determine if the internal 10-bit/12-bit ADC is sufficient, or if you need to buy an external chip. Follow the path until you hit a concrete part recommendation.
| Condition / Requirement | Action / Hardware Pick |
|---|---|
| Measuring 0-5V DC, basic user input (pots, joysticks), ±50mV accuracy is acceptable. | Use internal ATmega328P 10-bit ADC. No extra hardware needed. |
| Measuring 0-3.3V DC on ESP32, WiFi is required. | Use internal ESP32 ADC1 pins (GPIO 32-39). Avoid ADC2. |
| Measuring signals < 100mV (shunt resistors, thermocouples) or need >12-bit precision. | Internal ADC is useless due to noise floor. Buy the Adafruit ADS1115 (Product ID: 1085). |
| Measuring 3-phase AC or requiring simultaneous sampling of 4+ channels. | Internal sequential sampling fails. Buy the Texas Instruments ADS131E08 (8-channel simultaneous). |
Default Recommendation: If your project requires measuring millivolt-level changes (like a 50A current shunt outputting 75mV), stop fighting the internal 10-bit ADC's 4.88mV noise floor. Wire up an I2C ADS1115 breakout board. It gives you 16-bit resolution (0.18mV per step at 6.144V FSR) and an internal Programmable Gain Amplifier (PGA) that makes the math vastly more reliable.
Frequently Asked Questions
Why do some tutorials divide by 1023 instead of 1024?
The ADC has 1024 discrete steps (0 through 1023). Technically, the voltage range is divided into 1024 bins, making 1024 the electrically correct divisor. However, because the maximum output integer is 1023, dividing by 1023 ensures the math maps exactly to 5.00V when the pin is shorted to VCC. For 99% of hobbyist applications, the 0.004mV difference between the two divisors is buried in the noise floor. Use 1024 for datasheet accuracy, or 1023 if you are using the Arduino map() function.
How do I stabilize noisy ADC readings without adding hardware?
Implement software oversampling. Read the pin 16 times in a tight loop, sum the values, and divide by 16 (or bit-shift right by 4). This effectively adds 2 bits of resolution and acts as a low-pass digital filter, smoothing out high-frequency EMI from nearby switching regulators or breadboard parasitics.
Can I change the Arduino Uno VREF to 1.1V?
Yes. By calling analogReference(INTERNAL), you switch the VREF to the ATmega328P's internal 1.1V bandgap reference. This shifts your math to Voltage = (Raw / 1024) * 1.1V, giving you an LSB of 1.07mV. This is ideal for reading low-voltage sensors directly, but warning: applying more than 1.1V to the analog pin while this reference is active will not damage the pin, but the ADC will saturate at 1023 and the reading will be meaningless.






