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
}
@Ashish Ranjan, 👍3
1 ответ
Лучший ответ:
Я создал тестовую схему с использованием трансформатора переменного тока для получения синусоидального сигнала частотой 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 вызывает большие задержки между вызовами преобразователя АЦП. «Пробелы» на диаграмме представляют изменения синусоидального сигнала между последовательными вызовами функции чтения АЦП.
- Arduino/ESP8266 нет данных SPI, поступающих от MCP3008
- Где определение system_adc_read() в коде esp8266 Arduino?
- Любой способ использовать DMA для передачи данных на SD - карту в ESP8266
- ADS1115, ACS712 и ESP8266
- 8266 AnalogRead(A0) всегда 1024
- Измерение уровня заряда батареи с уже используемым АЦП
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?