If you are feeding a 1.65V analog signal into a 12-bit ADC with a 3.3V reference, the exact converted digital output is 2048 counts (hex 0x800). This is the fundamental unit conversion in any application of AD converter circuits: translating continuous analog voltage into discrete digital steps. Whether you are reading a temperature sensor with an Arduino or scaling a 0-10V industrial pressure transducer, knowing how to convert volts to bits—and understanding the physical limits of that conversion—is the difference between a working prototype and a noisy, unreliable system.
The Volts-to-Bits Conversion Formula
The core math governing any unipolar ADC is a simple ratio of the input voltage to the reference voltage, scaled by the total number of discrete steps the ADC can resolve.
Digital_Code = floor( (V_in / V_ref) × 2^n )Where n is the bit-resolution of the ADC.
Worked Substitution:
For a 12-bit ADC (n = 12, so 2^12 = 4096 steps), a 3.3V reference, and a 1.65V input:
Digital_Code = (1.65V / 3.300V) × 4096 = 0.5 × 4096 = 2048
This also gives us our
Neighboring Values Reference Table (±20% Range)
On the bench, signals rarely sit perfectly still. Here is how the digital output code shifts across a ±20% voltage band centered on our 1.65V target, assuming an ideal 12-bit ADC with a 3.3V Vref.
| Analog Input (V_in) | Variance from Target | Digital Code (Decimal) | Digital Code (Hex) | Measured Voltage (Reconstructed) |
|---|---|---|---|---|
| 1.320 V | -20% | 1638 | 0x666 | 1.319 V |
| 1.485 V | -10% | 1843 | 0x733 | 1.484 V |
| 1.650 V | 0% (Target) | 2048 | 0x800 | 1.650 V |
| 1.815 V | +10% | 2252 | 0x8CC | 1.814 V |
| 1.980 V | +20% | 2457 | 0x999 | 1.979 V |
Note: The reconstructed voltage is calculated by multiplying the digital code by the LSB size (805.66 µV). The slight discrepancy is the quantization error inherent to all ADC resolution limits.
What Assumptions Fix This Answer?
The calculation above yields exactly 2048, but that answer is only as solid as the physical assumptions holding it up. Here is what fixes the math, how it shifts, and when the conversion becomes meaningless.
1. The Vref Assumption (The Anchor)
The math assumes Vref is exactly 3.300V. In reality, if you are powering an ESP32 or Arduino via USB, your VCC (and thus your default Vref) might actually be 3.24V due to cable voltage drop. If Vref is 3.24V, a 1.65V input yields 2085 counts, not 2048. Fix: Always use a dedicated precision voltage reference IC (like the LM4040) for the Vref pin in precision applications.
2. How the Answer Shifts Across Architectures
- Shift to 5V Vref: 1.65V on a 12-bit ADC with a 5.0V reference drops to 1351 counts. The LSB size worsens to 1.22 mV.
- Shift to 16-bit Resolution: 1.65V on a 16-bit ADC (65,536 steps) with a 3.3V reference yields 32768 counts. The LSB size tightens to 50 µV.
- Shift to Bipolar: If using a bipolar ADC (measuring -Vref to +Vref), the formula shifts to include an offset:
Code = ((V_in / V_ref) + 1) × 2^(n-1).
3. When the Conversion is Meaningless
- Clipping (Overvoltage): If V_in exceeds Vref (e.g., 3.5V into a 3.3V ADC), the output hard-pegs at the maximum code (4095). You lose all data about how far over the limit the signal actually is.
- Aliasing (Nyquist Violation): If you are sampling a 10 kHz AC waveform but your ADC sampling rate is only 15 kHz (below the 20 kHz Nyquist minimum), the digital codes you read will mathematically reconstruct as a lower-frequency "ghost" signal. The unit conversion is mathematically correct, but physically meaningless.
- Internal MCU ADC Non-Linearity: As of 2026, while newer chips like the ESP32-S3 have improved greatly, the original ESP32-WROOM internal ADC is notoriously non-linear above 2.5V. Feeding 3.0V into GPIO 34 will not yield 3727 counts; it will saturate and read erratically.
Decision Path: Picking Your ADC for the Application
Don't just default to your microcontroller's internal ADC. Use this decision tree to select the right silicon for your specific application of AD converter requirements.
| Signal Type & Requirement | Required Resolution | Interface | Concrete Part Pick |
|---|---|---|---|
| General purpose DC (potentiometers, basic sensors), cost-sensitive | 10-bit to 12-bit | Internal / SPI | Microchip MCP3008 (8-channel, 10-bit SPI) or internal MCU ADC |
| Precision DC (battery monitoring, 4-20mA industrial loops) | 16-bit | I2C | Texas Instruments ADS1115 (Includes internal PGA and precision Vref) |
| High-resolution slow DC (strain gauges, load cells, thermocouples) | 24-bit | Proprietary / SPI | Avia Semiconductor HX711 (Integrated PGA specifically for bridge sensors) |
| High-speed AC / Audio / Waveform capture (>100 kSPS) | 12-bit to 14-bit | SPI / Parallel | Analog Devices AD9226 (12-bit, 65 MSPS CCD signal processor) |
FAQ: Edge Cases in ADC Unit Conversion
Q: Why does my multimeter read 1.650V, but my Arduino reads 1.68V after conversion?
A: You are likely using the microcontroller's VCC as the Vref. If your USB port is sagging to 5.05V (on a 5V board) or 3.25V (on a 3.3V board), your LSB multiplier is wrong. Measure your actual VCC pin with the multimeter and use that exact number as Vref in your software formula, rather than assuming a perfect 5.0 or 3.3.
Q: Can I just average multiple 12-bit readings to get 16-bit resolution?
A: Yes, through a technique called oversampling and decimation. To gain 1 additional bit of resolution, you must sample 4 times and average. To gain 4 bits (jumping from 12-bit to 16-bit), you must sample 256 times (4^4) and divide by 16. This only works if there is at least 1 LSB worth of natural Gaussian noise in your signal to dither the readings; otherwise, you just get the same 12-bit number repeated 256 times.
Q: How do I handle negative voltages on a unipolar ADC?
A: You cannot feed negative voltage directly into a unipolar ADC—it will clamp to 0 or damage the silicon. You must use an op-amp level-shifter circuit to offset the signal. For example, shift a ±5V signal up by 5V so it rides between 0V and 10V, then use a voltage divider to scale it down to your ADC's 0-3.3V range. You then reverse the math in software: True_Voltage = (Calculated_Voltage × Divider_Ratio) - Offset.






