I couldn’t find any usable info about the sampling speed of Espressif’s ESP32 onboard ADC.
The benchmark was performed on the following Hardware:
Platform: Espressif 32 -> NodeMCU-32S
System: ESP32 240MHz 320KB RAM (4MB Flash)
The firmware for the benchmark was build using PlatformIO with the Arduino framework. To get a fast access to the hardware, the Espressif IoT Development Framework was used for all ADC specific function calls.
#include <chrono> #include <Arduino.h> #include <driver/adc.h> void setup() { Serial.begin(115200); adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); } void loop() { const uint16_t samples = 10000; auto t1 = std::chrono::system_clock::now(); for (uint32_t i=0; i<samples; i++) { adc1_get_raw(ADC1_CHANNEL_4); // GPIO32 } auto t2 = std::chrono::system_clock::now(); std::chrono::duration<double> diff = t2 - t1; auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count(); Serial.printf("Samples: %u\n", samples); Serial.printf("Duration: %llums\n", ms); Serial.printf("KSPS: %0.4f", static_cast<double>(samples) / ms); }
The results are showing that the ADC is capable of doing 27.2 ksps (27173 samples per second). This does not change when reducing the resolution to 10 or even 9 bits.
Resolution (bit) | Speed (ksps) |
ADC_WIDTH_BIT_9 | 27.1739 |
ADC_WIDTH_BIT_10 | 27.1739 |
ADC_WIDTH_BIT_11 | 27.1739 |
ADC_WIDTH_BIT_12 | 27.1739 |
For me this results were unexpected, since a lower resolution should decrease the sample time.
Update
In the Espressif datasheet (topic 4.1.2), the ADC characteristics shows the following maximum sampling rates.
Description | Sampling rate (max) |
RTC controller | 200 ksps |
DIG controller | 2 Msps |
First question: what is a DIG controller and why has the RTC/DIG controller impact on the sampling speed? Assuming the numbers in the datasheet are valid, the measured speed differ massively from this rates. The implementation of adc1_get_raw is quite complex and does a lot of hardware initialization/locking around adc_convert().
int adc1_get_raw(adc1_channel_t channel) { uint16_t adc_value; RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); adc1_adc_mode_acquire(); adc_power_on(); portENTER_CRITICAL(&rtc_spinlock); //disable other peripherals adc1_hall_enable(false); adc1_fsm_disable(); //currently the LNA is not open, close it by default //set controller adc_set_controller( ADC_UNIT_1, ADC_CTRL_RTC ); //start conversion adc_value = adc_convert( ADC_UNIT_1, channel ); portEXIT_CRITICAL(&rtc_spinlock); adc1_lock_release(); return adc_value; }
So, the hardware might be capable to provide the claimed speeds but definitely not when using Espressif’s IDF as described in their documentation.