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 вызывает большие задержки между вызовами преобразователя АЦП. «Пробелы» на диаграмме представляют изменения синусоидального сигнала между последовательными вызовами функции чтения АЦП.
Ого! Спасибо, чувак. Это потрясающе. Я сам смог это проверить. Не знаю, почему я это пропустил!? Еще раз огромное спасибо., @Ashish Ranjan
- 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?
Пожалуйста, добавьте схему вашей проводки: описанное вами поведение выглядит некорректным., @Roberto Lo Giacco
Диапазон входного аналогового сигнала составляет 0-1,0 В. Возможно, ваша схема всегда выдает напряжение > 1?, @Jaromanda X
АЦП работает нормально, когда я использую system_adc_read(). Поэтому я уверен, что напряжение < 1., @Ashish Ranjan
максимальное значение adc_clk_div равно 23, @user97484