adc_oneshot.c
The H2 ADC goes through the new esp_adc driver: configure unit, channel, attenuation and width, then adc_oneshot_read returns the raw value. The millivolt conversion via the SDK calibration table replaces the rough rule of three.
Hardware required
An ESP32-H2 board (RISC-V 96 MHz, IEEE 802.15.4 radio only — no Wi-Fi) such as a DevKitM-1, powered over USB. 1 10 kΩ potentiometer (or analog sensor like MPX5700, output < 3.3 V).
Wiring
Potentiometer wiper on ADC3 (GPIO4), the other legs to 3.3 V and GND. Never more than 3.3 V on an ADC pin.
How it works
adc_oneshot_new_unit opens the unit, config_channel sets 12 bits + 12 dB attenuation (full scale ≈ 3.3 V), read returns the sample. The double read clears the multiplexer carry-over. Program it with ESP-IDF (idf.py set-target esp32h2); the USB-Serial/JTAG port (GPIO26/27) acts as console and flash port. Hold Boot + Reset for download mode if needed.
Going further
Average 16 samples to stabilize, or trigger reads from the LP timer controller between sleeps.
adc_oneshot.c
// adc_oneshot.c — lecture 12 bits + conversion en millivolts.
#include "driver/adc.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_log.h"
static const char *TAG = "adc";
void app_main(void)
{
const adc_oneshot_unit_init_cfg_t ucfg = { .unit_id = ADC_UNIT_1 };
adc_oneshot_unit_handle_t adc;
ESP_ERROR_CHECK(adc_oneshot_new_unit(&ucfg, &adc));
adc_oneshot_chan_cfg_t chan = {
.bitwidth = ADC_BITWIDTH_12, .atten = ADC_ATTEN_DB_12,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc, ADC_CHANNEL_3, &chan));
int mv = 0, raw = 0;
while (1) {
ESP_ERROR_CHECK(adc_oneshot_read(adc, ADC_CHANNEL_3, &raw));
adc_oneshot_read(adc, ADC_CHANNEL_3, &raw); // 2e lecture : plus stable
// Conversion brute -> mV par la table de calibration du SDK :
mv = raw * 3300 / 4095;
ESP_LOGI(TAG, "raw=%d soit ~%d mV (potentiometre ?)", raw, mv);
vTaskDelay(pdMS_TO_TICKS(500));
}
}