ESP8266: system_adc_read_fast() всегда возвращает 1024

Мне нужно использовать system_adc_read_fast (uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div), чтобы получить частоту дискретизации, близкую к 100 ksps. Я могу добиться этого, используя adc_clk_div = 32.

Однако, когда я распечатываю значения, хранящиеся в adc_addr, я всегда получаю 1024. Почему это так?

У меня NodeMCU v3. Я подключил к нему электретный микрофон. Клемма +ve подключена к 3,3 В через 10 кОм; GND подключена к GND. Клемма +ve подключена к A0 на NodeMCU.

схема

Все работает нормально, когда я использую system_adc_read() (за исключением того, что тогда частота дискретизации составляет 10 ksps, что нежелательно).

Набросок:

// Раскрыть функционал Espressif SDK — обернутый в ifdef, чтобы он по-прежнему
// компилируется на других платформах
#ifdef ESP8266
    extern "C" {
        #include "user_interface.h"
    }
#endif

ADC_MODE(ADC_TOUT);

#define num_samples 512
uint16_t adc_addr[num_samples]; // указать на адрес АЦП непрерывной быстрой выборки выходного сигнала
uint16_t adc_num = num_samples; // номер выборки АЦП непрерывной быстрой выборки, диапазон [1, 65535]
uint8_t adc_clk_div = 32; // Рабочая частота АЦП = 80M/adc_clk_div, диапазон [8, 32], рекомендуемое значение 8

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

void setup() {
    // поместите сюда ваш код настройки для однократного запуска:
    Serial.begin(115200);
}

void loop() {
    // поместите сюда свой основной код для многократного выполнения:
    #ifdef ESP8266
        // Серийный.println(system_get_sdk_version());

        wifi_set_opmode(NULL_MODE);
        system_soft_wdt_stop();
        ets_intr_lock( ); //закрыть прерывание
        noInterrupts();

        start = micros();

        // Последовательный.println(system_adc_read());
        system_adc_read_fast(adc_addr, adc_num, adc_clk_div);

        unsigned int tot = micros() - start;

        interrupts();
        ets_intr_unlock(); //открыть прерывание
        system_soft_wdt_restart();

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

        for (int j=0; j<adc_num;  j++) {
            Serial.println(adc_addr[j]);
        }

        if (i == 100) {
            // Serial.print("Частота дискретизации: ");
            // Serial.println(всего / 100);
            // Serial.print("Это длилось: ");
            // Serial.println(tim / 100);

            i = 0;
            tim = 0;
            total = 0;
        }
    #endif
}

, 👍3


1 ответ


Лучший ответ:

3

Я создал тестовую схему с использованием трансформатора переменного тока для получения синусоидального сигнала частотой 50 циклов в секунду и попробовал несколько вариаций программы-примера system_adc_read_fast из руководства по SDK Espressif "2C-ESP8266_Non_OS_SDK_API_Reference__EN".

АЦП ESP8266 вернул реалистичные значения для adc_clk_div = 8 и 16, но, как вы обнаружили, возвращаемые значения всегда были 1024, когда я пробовал 32.

Я обнаружил, что блок АЦП способен выполнять АЦП-преобразования примерно за 6–10 микросекунд...

В тестовой программе для сбора данных за период 40 миллисекунд (т. е. две полные синусоиды — я использовал диод, чтобы отсекать отрицательные половины) я вызывал функцию system_adc_read_fast 40 раз, собирая 116 выборок за каждый вызов (используя «количество выборок» = 116).

Я собрал все показания в двумерный массив, прежде чем печатать какие-либо значения, потому что функция Serial.print вызывает большие задержки между вызовами преобразователя АЦП. «Пробелы» на диаграмме представляют изменения синусоидального сигнала между последовательными вызовами функции чтения АЦП. Диаграмма значений АЦП ESP8266 за период 40 миллисекунд

,