For a standard 5V Arduino Uno (ATmega328P, 10-bit resolution), an ADC raw reading of 512 converts exactly to 2.502V. Conversely, to measure a 2.50V DC signal, the ADC returns a raw value of 511. The universal formula used to derive this is Voltage = (ADC_raw * V_ref) / (2^n - 1). Substituting our baseline values: Voltage = (512 * 5.0) / 1023 = 2.502V. This direct conversion assumes a perfectly stable 5.000V reference and a DC signal within the 0V to 5V bounds.
The Core Conversion Formula & Neighboring Values
The ATmega328P maps the 0V to 5V range across 1,024 discrete steps (0 to 1023). Each step, or Least Significant Bit (LSB), represents approximately 4.88mV. When you are debugging sensor outputs on the bench, it is highly useful to know the voltage equivalents for the mid-scale range without doing the math every time. Below is a reference table covering a ±20% range around the 512 mid-point.
| ADC Raw Value | Calculated Voltage (5V Ref) | Calculated Voltage (3.3V Ref) | Typical Sensor Equivalent |
|---|---|---|---|
| 410 | 2.003V | 1.322V | Low-end potentiometer wiper |
| 460 | 2.248V | 1.484V | Mid-range TMP36 temp sensor |
| 512 | 2.502V | 1.651V | Perfect mid-scale bias (Vref/2) |
| 563 | 2.751V | 1.816V | High-range light dependent resistor |
| 614 | 3.000V | 1.980V | Li-Ion cell at ~75% State of Charge |
What Fixes the Answer: Vref, Resolution, and Hardware Shifts
The conversion math is absolute, but the physical answer shifts entirely based on three fixed assumptions: the Reference Voltage (Vref), the Bit Resolution (n), and the Analog Ground stability.
5.0 in your formula while the rail is at 4.7V, your calculated 2.50V reading is actually 2.35V. For precision work, always measure your actual VCC rail with a multimeter and hardcode that exact value (e.g., 4.92) into your sketch.
How the answer shifts across platforms:
- 5V Systems (Arduino Uno/Mega): Uses a 10-bit ADC (0-1023). Default Vref is 5V. LSB = 4.88mV.
- 3.3V Systems (Arduino Due / Pro Mini 3.3V): Still 10-bit (0-1023) on the Pro Mini, but Vref is 3.3V. LSB shrinks to 3.22mV. A raw reading of 512 now equals 1.651V.
- ESP32 (Internal ADC): Nominally 12-bit (0-4095) with a 3.3V reference. However, the ESP32's internal SAR ADC is notoriously non-linear at the extremes (below 0.15V and above 3.1V). A raw reading of 2048 theoretically equals 1.65V, but real-world bench tests often show a ±50mV deviation without software calibration.
- External Vref (e.g., 2.048V Precision Reference): If you use the
analogReference(EXTERNAL)function on an Uno with a 2.048V reference IC, a reading of 512 equals exactly 1.024V. This is a common trick to maximize resolution for low-voltage sensors like shunt monitors.
AC Mains (120V/230V) and 3-Phase: When the Conversion Fails
If you are attempting to use an Arduino ADC converter to measure 120V or 230V AC mains, the direct DC conversion formula is meaningless and physically dangerous. The Arduino ADC can only read positive DC voltages between 0V and Vref. Feeding AC into the pin will destroy the microcontroller's internal clamping diodes.
To measure AC mains, the conversion requires a hardware front-end (like a ZMPT101B voltage transformer module) that steps the voltage down and applies a DC bias offset (usually shifting the 0V AC center-point to 2.5V). In this scenario, your formula shifts to: V_ac = (ADC_raw - Bias_Offset) * Scaling_Factor.
For 3-Phase systems: You must sample three isolated channels simultaneously. The ATmega328P's multiplexed ADC and 9.6kHz maximum sample rate are insufficient for capturing three 50/60Hz waveforms with accurate phase-angle relationships. At that point, the single-channel ADC conversion becomes meaningless for power-factor calculations, and you must shift to a dedicated 3-phase energy monitoring IC like the ADE9000.
When the Conversion is Meaningless (Edge Cases & Noise)
Even with perfect DC signals, your calculated voltage will be garbage if you hit these physical limitations:
- Floating Inputs: An unconnected analog pin acts as an antenna. Readings will bounce randomly from 0 to 1023. Always tie unused analog pins to GND via a 10kΩ pulldown resistor.
- High Source Impedance: The ATmega328P ADC uses an internal sample-and-hold capacitor (approx 14pF). If your sensor's output impedance is greater than 10kΩ (common with high-value voltage dividers), the capacitor cannot charge fully before the conversion triggers. The ADC will consistently read lower than the actual voltage. Fix: Add a 100nF ceramic capacitor between the analog pin and GND to act as a local charge reservoir.
- Noise Exceeding 1 LSB: If your environment has heavy EMI (like switching a relay nearby) and your noise floor is 15mV peak-to-peak, any ADC resolution finer than 15mV is mathematically meaningless. You are just digitizing noise.
Decision Tree: Upgrading Your Arduino ADC Converter
When the internal 10-bit or 12-bit ADC fails to provide the precision or speed your project demands, you must add an external ADC. Use this decision matrix to select the exact part number for your bench.
| Your Constraint / Requirement | If True... | Concrete Part Pick |
|---|---|---|
| Need >10-bit precision on a 5V Uno, but sample rate < 1kHz is acceptable? | Use a 16-bit I2C ADC with internal programmable gain. | Texas Instruments ADS1115 (Adafruit Product ID: 1085) |
| Need 8 channels of 12-bit resolution on an ESP32 via SPI? | Use an 8-channel 12-bit SPI ADC. Do not rely on ESP32 internal multiplexing. | Microchip MCP3008 (DIP-16 package) |
| Need high-speed sampling (>100kHz) for audio or vibration FFT? | Use a parallel or high-speed SPI ADC. I2C is too slow. | Analog Devices AD7928 (12-bit, 1MSPS SPI) |
| Need to measure bipolar signals (-5V to +5V) directly? | Use an ADC with built-in dual-supply or true bipolar input support. | Maxim MAX11205 (16-bit, handles bipolar natively) |
Frequently Asked Questions
Why does my Arduino ADC reading fluctuate by ±3 counts when the multimeter reads a steady voltage?
A ±3 count fluctuation on a 10-bit ADC represents roughly ±15mV. This is normal thermal and quantization noise. To stabilize the reading in software, oversample by taking 16 rapid readings and bit-shift the average down, or implement a simple exponential moving average (EMA) filter in your loop.
Can I use the Arduino 3.3V pin as the AREF for better precision on a 3.3V sensor?
Yes, but with a caveat. On the Arduino Uno, the 3.3V pin is generated by an onboard linear regulator that can be noisy if the USB power is dirty. If you use it as AREF via analogReference(EXTERNAL), place a 100nF decoupling capacitor directly between the AREF pin and GND to filter out high-frequency switching noise.
What happens if my input voltage slightly exceeds 5V on a 5V Arduino?
The ADC will hard-clip at 1023 for any voltage at or above Vref (5V). More importantly, if the voltage exceeds VCC + 0.5V (e.g., 5.5V), current will flow backward through the microcontroller's internal ESD protection diodes, potentially bricking the ATmega328P. Always use a clamping diode or a voltage divider to ensure the signal never exceeds Vref.






