For a standard 5V, 10-bit Arduino (like the classic Uno R3), an analog input of 2.5V converts to a digital value of 512. On a 3.3V, 12-bit board (like the Nano 33 BLE), that same 2.5V signal converts to 3102. The universal formula used to derive this is: Digital Value = (Analog Voltage / Reference Voltage) × (2^Resolution - 1). Substituting our baseline values: (2.5V / 5.0V) × (1023) = 511.5, which the microcontroller rounds to 512. Getting this math right is the difference between a precision sensor array and a board that thinks your 50°C motor is running at 120°C.
The Core ADC Conversion Formula & Neighboring Values
The Texas Instruments SLAA013 application note on understanding ADCs highlights that resolution and reference voltage dictate your step size. For a 10-bit ADC at 5V, each digital step represents 4.88mV. For a 12-bit ADC at 3.3V, each step is 0.8mV. Below is a spec-sheet-table showing how neighboring voltages (a ±20% range around our 2.5V baseline) map to digital values across three common microcontroller architectures.
| Analog Input (Vin) | 5V / 10-bit (Uno R3) | 3.3V / 12-bit (Nano 33 BLE) | 5V / 14-bit (Uno R4 Minima) |
|---|---|---|---|
| 2.0V (-20%) | 409 | 2481 | 6552 |
| 2.25V (-10%) | 460 | 2792 | 7371 |
| 2.5V (Baseline) | 512 | 3102 | 8190 |
| 2.75V (+10%) | 563 | 3412 | 9010 |
| 3.0V (+20%) | 614 | 3723 | 9830 |
val >> 4) to emulate the classic 10-bit 0-1023 range, or update your voltage conversion math to divide by 16383 instead of 1023.
How Reference Voltages and Mains Scaling Shift the Answer
The assumption that fixes your conversion answer is always your Reference Voltage (Vref) and your bit resolution. If you assume 5V but your USB port is sagging to 4.6V, your calculated sensor voltage will be 8% lower than reality. But how does this shift when dealing with higher voltages or different logic levels?
3.3V Logic vs 5V Logic
When moving from a 5V Uno to a 3.3V ESP32 or Teensy 4.1, the maximum readable voltage drops. Feeding 4.0V into a 3.3V ADC pin won't just peg the reading at the maximum digital value (e.g., 4095); it can permanently damage the silicon. You must use a voltage divider to scale the signal down.
Scaling for 120V vs 230V vs 3-Phase Mains
If your project involves monitoring mains power, the raw ADC formula shifts from direct measurement to a scaled ratio calculation. A microcontroller ADC cannot read 120V, 230V, or 3-phase power directly—doing so is fatal to the board and a severe shock hazard.
- 120V AC: Requires a step-down transformer or a ZMPT101B voltage sensor module to scale the peak voltage (~170V) down to a safe 0-3.3V range, centered around a 1.65V DC bias.
- 230V AC: The peak voltage is ~325V. Your voltage divider or sensor module must have a higher step-down ratio to keep the output within the 0-3.3V ADC window.
- 3-Phase: Requires three isolated ADC channels, each with its own scaling network and DC bias, ensuring the phase-to-neutral voltage (often 230V) is properly attenuated.
When Analog-to-Digital Conversion is Meaningless
In AC power theory, calculating true power is meaningless if the power factor (pf) is unknown. In microcontroller ADCs, the digital conversion is equally meaningless under three specific conditions:
- Floating Pins (The Antenna Effect): If an analog pin is not tied to a defined voltage or ground, it acts as an antenna. Reading it will yield random noise (often fluctuating between 200 and 800 on a 10-bit scale). Always use a pull-down resistor (e.g., 10kΩ) on unused analog pins or sensor lines that might disconnect.
- Unconditioned AC Signals: Microcontrollers cannot read negative voltages. If you feed a raw AC sine wave into an ADC, it will clip the negative half-cycle (reading 0) and only sample the positive half. Without a DC bias circuit to shift the entire waveform above 0V, the digital conversion is meaningless for calculating RMS or true power.
- Unregulated Vref: If your code assumes
analogRead()is based on a perfect 5.0V reference, but you are powering the board via a USB hub that outputs 4.7V, every subsequent voltage calculation in your project will be skewed. For precision work, use theanalogReference(INTERNAL)function to lock the ADC to the chip's stable internal bandgap reference (usually 1.1V or 2.5V, depending on the board).
FAQ: Common Arduino ADC Conversion Questions
How do I convert a 0-1023 ADC reading back to voltage in code?
Multiply the reading by the reference voltage, then divide by the maximum step value. For a standard 5V 10-bit Arduino, the code is: float voltage = sensorValue * (5.0 / 1023.0);. Note the use of 1023.0 (floating point) rather than 1023 (integer) to prevent integer division truncation in C++, which would otherwise force all your readings to either 0 or 5.
Why does my ESP32 analogRead() max out at 4095 but the voltage is only 2.45V?
The Espressif ESP32 hardware reference documents that the internal ADC reference voltage is approximately 2.45V, not 3.3V, and the ADC is notoriously non-linear at the extremes of its range. A reading of 4095 (12-bit max) corresponds to ~2.45V. If you need to read up to 3.3V on an ESP32, you must use an external ADC (like the ADS1115) or apply a voltage divider to scale 3.3V down to 2.4V before it hits the GPIO pin.
Can I use analogRead() to measure 120V AC directly?
No. The absolute maximum voltage on any Arduino or ESP32 ADC pin is VCC + 0.5V (usually 5.5V or 3.8V). Connecting 120V AC will instantly destroy the microcontroller and poses a lethal electrocution risk. You must use an isolated voltage sensor module, a potential transformer, or an AC-to-DC RMS converter chip (like the LTC1966) to safely step the voltage down to a 0-5V DC envelope before it reaches your analog pin.






