Continuous ADC
The ContinuousAdc provides a mechanism for high-frequency, continuous, deterministic sampling of analog voltages for multiple channels (potentially across multiple ADC units, depending on the ESP32 chip used). It does this be enabling the continuous ADC DMA mode and then running its own task which retrieves the data and filters it. When the user calls get_mv(adc_channel_t), it simply returns the most recent filtered value for that channel, if it was configured.
API Reference
Header File
Classes
-
class ContinuousAdc : public espp::BaseComponent
ContinuousAdc provides a wrapper around the ESP-IDF continuous adc subsystem, enabling high-frequency, filtered measurements of analog values. The
get_mv()
function will always return the most up to date value, without needing to perform additional reads (therefore it is non-blocking).Continuous ADC Example
std::vector<espp::AdcConfig> channels{ {.unit = ADC_UNIT_1, .channel = ADC_CHANNEL_6, .attenuation = ADC_ATTEN_DB_12}, {.unit = ADC_UNIT_1, .channel = ADC_CHANNEL_7, .attenuation = ADC_ATTEN_DB_12}}; // this initailizes the DMA and filter task for the continuous adc espp::ContinuousAdc adc( {.sample_rate_hz = 20 * 1000, .channels = channels, .convert_mode = ADC_CONV_SINGLE_UNIT_1, // or BOTH_UNIT, ALTER_UNIT, SINGLE_UNIT_1, SINGLE_UNIT_2 .window_size_bytes = 1024, .log_level = espp::Logger::Verbosity::WARN}); adc.start(); auto task_fn = [&adc, &channels](std::mutex &m, std::condition_variable &cv) { for (auto &conf : channels) { auto maybe_mv = adc.get_mv(conf); if (maybe_mv.has_value()) { fmt::print("{}: {} mV\n", conf, maybe_mv.value()); } else { fmt::print("{}: no value!\n", conf); } auto maybe_rate = adc.get_rate(conf); if (maybe_rate.has_value()) { fmt::print("{}: {} Hz\n", conf, maybe_rate.value()); } else { fmt::print("{}: no rate!\n", conf); } } // NOTE: sleeping in this way allows the sleep to exit early when the // task is being stopped / destroyed { std::unique_lock<std::mutex> lk(m); cv.wait_for(lk, 500ms); } // don't want to stop the task return false; }; auto task = espp::Task({.callback = task_fn, .task_config = {.name = "Read ADC"}, .log_level = espp::Logger::Verbosity::INFO}); task.start(); // test stopping and starting the adc std::this_thread::sleep_for(3s); logger.info("Stopping ADC"); adc.stop(); std::this_thread::sleep_for(3s); logger.info("Starting ADC"); adc.start();
Note
The available modes, frequencies, and throughput is dependent on whether you run on ESP32, ESP32s2, or ESP32s3.
Public Functions
-
inline explicit ContinuousAdc(const Config &config)
Initialize and start the continuous adc reader.
- Parameters
config – Config used to initialize the reader.
-
inline ~ContinuousAdc()
Stop, deinit, and destroy the adc reader.
-
inline void start()
Start the continuous adc reader.
-
inline void stop()
Stop the continuous adc reader.
-
inline std::optional<float> get_mv(const AdcConfig &config)
Get the most up to date filtered voltage (in mV) from the provided
channel
.- Parameters
config – The config used to initialize the channel (includes unit and channel)
- Returns
std::optional<float> voltage in mV for the provided channel (if it was configured and the adc is running).
-
inline std::optional<float> get_rate(const AdcConfig &config)
Get the most up to date sampling rate (in Hz) from the provided
channel
.- Parameters
config – The config used to initialize the channel (includes unit and channel)
- Returns
std::optional<float> Rate in Hz for the provided channel (if it was configured and the adc is running).
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
-
struct Config
Configure the sample rate (globally applied to each channel), select the number of channels, and the conversion mode (for S2 S3)
Public Members
-
size_t sample_rate_hz
Samples per second to read from each channel.
-
std::vector<AdcConfig> channels
Channels to read from, with associated attenuations.
-
adc_digi_convert_mode_t convert_mode
Conversion mode (unit 1, unit 2, alternating, or both). May depend on ESP32 chip.
-
size_t task_priority = {5}
Priority to run the adc data reading / filtering task.
-
size_t window_size_bytes = {256}
Amount of bytes to allocate for the DMA buffer when reading results. Larger values lead to more filtering.
-
size_t sample_rate_hz
-
inline explicit ContinuousAdc(const Config &config)