adc-12bits.ino
The ESP32-S3 ADC reaches 12 bits but is moody: non-linear at the low end, noisy, attenuation-dependent. This sketch sets the advised options (11 dB, APB clock), averages 32 readings and applies a home-made two-point calibration.
Hardware
An Arduino Nano ESP32 (dual-core ESP32-S3, 2.4 GHz Wi-Fi + Bluetooth Low Energy, Nano-compatible physical pinout, native USB, 3.3 V pins only). Nano ESP32, 0-3.3 V analog source on A0; multimeter to calibrate.
Wiring
Signal on A0 and common GND; real full scale is ~3.1-3.3 V depending on attenuation, never exceed 3.3 V.
How it works
analogSetPinAttenuation(ADC_11db) covers 0-3.3 V; the APB clock avoids ADC_80M drift. Numeric averaging divides noise, the two-point calibration corrects gain/offset.
Running it
Install the Arduino ESP32 Boards package (or follow the official Nano ESP32 guide), select Arduino Nano ESP32, upload. Pins are 3.3 V: never feed 5 V into an input. The serial monitor uses native USB.
Variants
For precision, move to an external ADS1115 on I2C, or use esp_adc_cal (low-level API) with the factory calibration eFuse.
adc-12bits.ino
// ADC de l'ESP32-S3 : 12 bits natifs, mais non lineaire en bas
// d'echelle. attenuation 11 dB = pleine echelle ~3,3 V.
const int CANAL = A0;
void setup() {
Serial.begin(115200);
analogReadResolution(12); // 0..4095
analogSetPinAttenuation(CANAL, ADC_11db);
analogSetPixelClockSource(ADC_PIXEL_CLOCK_APB); // horloge stable
}
void loop() {
// moyenne sur 32 lectures : l'ADC ESP32 est bruité
uint32_t somme = 0;
for (int i = 0; i < 32; i++) somme += analogRead(CANAL);
float brut = somme / 32.0;
// calibration lineaire par deux points (bricolage maison)
const float A = 3.3 / 4095.0 * 1.02f;
const float B = -0.02;
float tension = brut * A + B;
Serial.print("brut=");
Serial.print(brut, 0);
Serial.print(" -> ");
Serial.print(tension, 3);
Serial.println(" V");
delay(500);
}