Calculator
ADC reference ā common platforms
| Platform | ADC ref | Resolution | Max counts | Notes |
|---|---|---|---|---|
| Arduino Uno / Nano | 5.0 V | 10-bit | 1023 | analogRead() returns 0ā1023 |
| Arduino Mega | 5.0 V | 10-bit | 1023 | Same as Uno |
| Arduino Due | 3.3 V | 12-bit | 4095 | analogReadResolution(12) needed |
| ESP32 | 3.3 V | 12-bit | 4095 | Effective ~11-bit due to non-linearity. Max safe input: 3.3 V |
| ESP8266 | 1.0 V | 10-bit | 1023 | NodeMCU has on-board 220k/100k divider ā max 3.3 V |
| Raspberry Pi Pico | 3.3 V | 12-bit | 4095 | ADC pins: GP26, GP27, GP28 |
| STM32 (typical) | 3.3 V | 12-bit | 4095 | Configurable 8/10/12-bit |
Design guide
Formula
Vout = Vin Ć R2/(R1+R2)
R1/R2 = Vin/Vout ā 1
ADC = Vout / Vref Ć (2āæā1)
Vin = ADC Ć Vref / (2āæā1)
Ć (R1+R2)/R2
Choosing R values
- Too low (āŖ1 kĪ©) ā high current, heats up, loads source
- Too high (ā«100 kĪ©) ā ADC input impedance causes error
- Sweet spot: 10ā100 kĪ© for most MCU ADCs
- ESP32 ADC input impedance ~80 kĪ© ā keep R2 ⤠10 kĪ©
- Add small cap (100 nF) across R2 to reduce noise
Protection
- Always ensure Vout ⤠Vref under all conditions
- Add a Zener diode across R2 for overvoltage protection
- Add series resistor (1 kΩ) between divider and ADC pin to limit fault current
- For automotive (up to 40V): use 100 kΩ / 10 kΩ divider
Reading in code
// Arduino (10-bit, 5V)
int raw = analogRead(A0);
float v = raw * (5.0/1023.0);
float vin = v * (R1+R2)/R2;
// ESP32 (12-bit, 3.3V)
int raw = analogRead(34);
float v = raw * (3.3/4095.0);
float vin = v * (R1+R2)/R2;