I need to use system_adc_read_fast (uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div) to get a sampling rate close to 100ksps. And I am able to achieve that using adc_clk_div = 32.

However, when I print out the values stored in adc_addr, I always get 1024. Why is this?

I have a NodeMCU v3. I have connected an electret microphone to it. +ve terminal is connected to 3.3V through 10k; GND is connected to GND. +ve terminal is connected to A0 on NodeMCU.


simulate this circuit – Schematic created using CircuitLab

It works fine when I use system_adc_read() (except the sampling rate is then 10ksps which is not desirable).


// Expose Espressif SDK functionality - wrapped in ifdef so that it still
// compiles on other platforms
#ifdef ESP8266
    extern "C" {
        #include "user_interface.h"


#define num_samples 512
uint16_t adc_addr[num_samples]; // point to the address of ADC continuously fast sampling output
uint16_t adc_num = num_samples; // sampling number of ADC continuously fast sampling, range [1, 65535]
uint8_t adc_clk_div = 32; // ADC working clock = 80M/adc_clk_div, range [8, 32], the recommended value is 8

int i = 0;
unsigned long start = 0;
unsigned long total = 0;
unsigned long tim = 0;

void setup() {
    // put your setup code here, to run once:

void loop() {
    // put your main code here, to run repeatedly:
    #ifdef ESP8266
        // Serial.println(system_get_sdk_version());

        ets_intr_lock( ); //close interrupt

        start = micros();

        // Serial.println(system_adc_read());
        system_adc_read_fast(adc_addr, adc_num, adc_clk_div);

        unsigned int tot = micros() - start;

        ets_intr_unlock(); //open interrupt

        tim += tot;
        total += num_samples * 1000000.0 / tot;

        for (int j=0; j<adc_num;  j++) {

        if (i == 100) {
            // Serial.print("Sampling rate: ");
            // Serial.println(total / 100);
            // Serial.print("It lasted: ");
            // Serial.println(tim / 100);

            i = 0;
            tim = 0;
            total = 0;
  • Please add a schematic of your wiring: the behaviour you are describing doesn't look correct – Roberto Lo Giacco Jan 11 '18 at 1:27
  • the analog pin input range is 0-1.0v - perhaps your circuit results in voltage always > 1? – Jaromanda X Jan 11 '18 at 3:10
  • The ADC works fine when I use system_adc_read(). So, I'm sure the voltage is < 1. – Ashish Ranjan Jan 11 '18 at 3:12

I created a test circuit using an AC transformer to produce a 50 cycles / second sine wave signal and tried a number of variations on the system_adc_read_fast sample program in the Espressif SDK manual "2C-ESP8266_Non_OS_SDK_API_Reference__EN".

The ESP8266 ADC returned realistic values for adc_clk_div = 8 and 16, but, as you found, the values returned were always 1024 when I tried 32.

I found that the ADC unit was capable of performing ADC conversions in about 6-10 microseconds...

In a test program to collect data for a 40 millisecond period (ie two complete sine waves - I used a diode to chop off the negative halves) I called the system_adc_read_fast function 40 times collecting 116 samples in each call (using "number of samples" = 116).

I collected all the readings in a two-dimensional array before printing any values because the Serial.print function causes long delays between calls to the ADC converter. The "gaps" in the chart represent the changes in the sine wave signal between successive calls to the ADC read function. Chart of ESP8266 ADC values over a 40 millisecond period

| improve this answer | |
  • Wow! Thanks dude. This is awesome. I've been able to verify this myself. Don't know why I missed this in the first place!? Again, thank you so much. – Ashish Ranjan May 22 '18 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.