Skip to content

File espos_adc.h

File List > espos_sensors > include > espos_adc.h

Go to the documentation of this file

/*
 * SPDX-FileCopyrightText: 2026 Dirk Wahrheit
 * SPDX-License-Identifier: Apache-2.0
 *
 * espos_adc — one analog input, calibrated, in volts.
 *
 * The SAR ADC on an ESP32 is not a voltmeter out of the box. Raw counts are
 * several percent off from chip to chip, so the factory burns per-chip
 * coefficients into eFuse and a calibration scheme applies them; WHICH scheme
 * exists is a property of the SoC (curve fitting on the C6/S3/P4, line
 * fitting on the original ESP32), which is why every example that reads an
 * ADC carries the same #if. That belongs in one place, and this is it.
 *
 * The output is volts, never raw counts: counts are meaningless without the
 * attenuation and bit width that produced them, and a calibration a user
 * types into a web UI ("multiply by 1.7") is only stable if what it multiplies
 * is a voltage.
 */
#pragma once

#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct espos_adc *espos_adc_handle_t;

typedef enum {
    ESPOS_ADC_ATTEN_0DB = 0,  /* ~0.95 V full scale */
    ESPOS_ADC_ATTEN_2_5DB,    /* ~1.25 V */
    ESPOS_ADC_ATTEN_6DB,      /* ~1.75 V */
    ESPOS_ADC_ATTEN_12DB,     /* ~3.1 V  -- the default, and what a divider to 3V3 needs */
} espos_adc_atten_t;

typedef struct {
    int gpio;                  /* the pin. Must be an ADC1 GPIO -- see the note below */
    espos_adc_atten_t atten;   /* ESPOS_ADC_ATTEN_12DB when zero-initialised... see cfg_default */
    uint8_t samples;           /* readings averaged per call; 0 = 16. The SAR ADC is noisy by a few LSB */
} espos_adc_cfg_t;

esp_err_t espos_adc_open(const espos_adc_cfg_t *cfg, espos_adc_handle_t *out);
void espos_adc_close(espos_adc_handle_t h);

esp_err_t espos_adc_read_volts(espos_adc_handle_t h, float *out_volts);

esp_err_t espos_adc_read_raw(espos_adc_handle_t h, int *out_raw);

bool espos_adc_calibrated(espos_adc_handle_t h);

#ifdef __cplusplus
}
#endif