ADC continuous read sample rate is not what is specified

pipe01
Posts: 1
Joined: Thu Jan 05, 2023 7:15 pm

ADC continuous read sample rate is not what is specified

Postby pipe01 » Thu Jan 05, 2023 7:32 pm

Hello, I'm trying to use the ADC in the continuous introduced by IDF 5.0, however the sample rate that I specify in the adc_continuous_config_t does not correlate to what I actually get. Here is the code that I'm running:

Code: Select all

#include <esp_adc/adc_continuous.h>
#include "esp_timer.h"

#include "freertos/FreeRTOS.h"

#include <string.h>
#include <math.h>
#include <atomic>

#define SAMPLE_RATE 40000

adc_continuous_handle_t adcHandle = NULL;

std::atomic_uint32_t sampleCount;

void printSampleRateTask(void *arg)
{
    uint32_t samplesPerSecond = sampleCount.exchange(0, std::memory_order_acq_rel);

    printf("Time: %lld, samples per second: %lu\n", esp_timer_get_time(), samplesPerSecond);
}

extern "C" void app_main()
{
    adc_continuous_handle_cfg_t handle_cfg = {
        .max_store_buf_size = 2000,
        .conv_frame_size = 1000,
    };

    ESP_ERROR_CHECK(adc_continuous_new_handle(&handle_cfg, &adcHandle));

    adc_digi_pattern_config_t channel[1] = {};
    channel[0].atten = ADC_ATTEN_DB_11;
    channel[0].channel = 0;
    channel[0].unit = 0;
    channel[0].bit_width = SOC_ADC_DIGI_MIN_BITWIDTH;

    adc_continuous_config_t cfg = {
        .pattern_num = 1,
        .adc_pattern = channel,
        .sample_freq_hz = SAMPLE_RATE,
        .conv_mode = ADC_CONV_SINGLE_UNIT_1,
        .format = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
    };

    ESP_ERROR_CHECK(adc_continuous_config(adcHandle, &cfg));
    ESP_ERROR_CHECK(adc_continuous_start(adcHandle));

    const esp_timer_create_args_t periodic_timer_args = {
        .callback = &printSampleRateTask,
        .name = "sampleRate",
    };
    esp_timer_handle_t periodic_timer;

    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 1000000));

    esp_err_t ret;
    uint32_t ret_num = 0;
    uint8_t result[1000] = {0};

    while (1)
    {
        ret = adc_continuous_read(adcHandle, result, sizeof(result), &ret_num, 1000);

        if (ret == ESP_OK)
        {
            sampleCount += ret_num / SOC_ADC_DIGI_RESULT_BYTES;
        }
        else
        {
            printf("status: %d\n", ret);
        }
    }
}
This is an excerpt from the serial output:

Code: Select all

Time: 1028996, samples per second: 32500
Time: 2028961, samples per second: 32500
Time: 3028961, samples per second: 33000
Time: 4028961, samples per second: 32500
Time: 5028961, samples per second: 33000
Time: 6028961, samples per second: 32500
Time: 7028961, samples per second: 33000
Time: 8028961, samples per second: 32500
Time: 9028961, samples per second: 32500
Time: 10028961, samples per second: 33000
Time: 11028961, samples per second: 32500
Time: 12028961, samples per second: 33000
Time: 13028961, samples per second: 32500
And this is what IDF says when building:

Code: Select all

CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/wemos_d1_mini32.html
PLATFORM: Espressif 32 (5.3.0+sha.98b1e96) > WEMOS D1 MINI ESP32
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: 
 - framework-espidf @ 3.50000.0 (5.0.0) 
 - tool-cmake @ 3.16.4 
 - tool-esptoolpy @ 1.40400.0 (4.4.0) 
 - tool-mkfatfs @ 2.0.1 
 - tool-mklittlefs @ 1.203.210628 (2.3) 
 - tool-mkspiffs @ 2.230.0 (2.30) 
 - tool-ninja @ 1.7.1 
 - toolchain-esp32ulp @ 1.23500.220830 (2.35.0) 
 - toolchain-xtensa-esp32 @ 11.2.0+2022r1
I've tried changing the sample rate, as well as buffer sizes and the max_store_buf_size and conv_frame_size, but no combination makes the sample rates match. How can I make it more precise?

Thanks.

acflach
Posts: 1
Joined: Tue Jan 31, 2023 5:22 am

Re: ADC continuous read sample rate is not what is specified

Postby acflach » Tue Feb 07, 2023 6:17 am

Hi! In my tests with ESP-IDF continuous read example, a framerate of 22050 Hz yelds erratic values: 17920 or 18048 Hz . . . In my case, it is useless for generate 22.05 kHz WAV files . . .

Is it better using a ADC simple read and a timer?

Any progress in issue or a workaround?

Thanks


Who is online

Users browsing this forum: Bing [Bot], Lvalue, mikecarlos and 128 guests