Странная проблема с библиотекой FHT для проекта светодиода, реагирующего на звук
Я игрался с библиотекой FHT и столкнулся с интересной проблемой с fht_mag_octave()
, нарушающей вывод моих действий АЦП. Работает на MEGA ADK.
Идея состоит в том, что я использую FHT для считывания входного сигнала микрофона в A0, но также время от времени проверяю потенциометр A2, чтобы отрегулировать громкость/яркость всей полосы FastLED.
Вот код, о котором идет речь... он прост. Просто стандартный цикл FHT, а затем каждые 100 циклов он проверяет A2 на предмет настройки яркости.
#include <FastLED.h>
#define LED_PIN 6
#define BRIGHTNESS 200
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 16
CRGB* const leds(NUM_LEDS);
#define LOG_OUT 1 // использовать функцию вывода журнала
#define OCTAVE 1 // // Группируем блоки в октавы (используем функцию вывода журнала LOG_OUT 1)
#define OCT_NORM 0 // Не нормализовать интенсивность октавы по количеству ячеек
#define FHT_N 128 // установить fht на 128 точек
#include <FHT.h> //
void setup() {
Serial.begin(9600);
delay(1000);
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
FastLED.setBrightness (BRIGHTNESS);
// TIMSK0 = 0; // отключаем timer0 для снижения джиттера (закомментировал это, потому что думаю, что это мешает FastLED)
ADCSRA = 0xe5; // установить АЦП в режим свободного хода (0b11100101), prescalar=32 для более высокой тактовой частоты АЦП
ADMUX = 0x40 | (0 & 0x07); // используем adc0 (0b1000000)
DIDR0 = 0x01; // отключаем цифровой вход для adc0
}
int counter = 0;
void loop() {
while (1) { // уменьшает дрожание
cli(); // прерывание UDRE замедляет работу на arduino1.0
for (int i = 0 ; i < FHT_N ; i++) { // сохранить 128 образцов
while (!(ADCSRA & 0x10)); // ждем готовности АЦП в двоичном коде 0010000 (следите за тем, чтобы флаг прерывания АЦП был установлен в 1)
ADCSRA = 0xf5; // перезапустить АЦП (в двоичном формате 11110101...http://www.robotplatform.com/knowledge/ADC/adc_tutorial_2.html)
byte m = ADCL; // извлечь данные АЦП
byte j = ADCH;
int k = (j << 8) | m; // преобразуем в int
k -= 0x0200; // преобразуется в знаковое целое число
k <<= 6; // преобразуется в 16-битное знаковое целое число
fht_input[i] = k; // помещаем реальные данные в ячейки
}
fht_window(); // окно данных для лучшей частотной характеристики
fht_reorder(); // переупорядочиваем данные перед выполнением fht
fht_run(); // обрабатываем данные в fht
fht_mag_octave();
// fht_mag_log();
// каждый 100-й цикл регулируйте громкость в соответствии со значением на A2 (Pot)
if (counter > 10) {
ADMUX = 0x40 | (2 & 0x07); // настраиваем admux на просмотр Analogpin A2
while (!(ADCSRA & 0x10)); // ждем готовности АЦП
ADCSRA = 0xf5; // перезапускаем АЦП
byte m = ADCL; // извлечь данные АЦП
byte j = ADCH;
int brightness = (j << 8) | m; // преобразуем в int
// яркость = map(яркость, 0, 1023, 0, 255);
Serial.print("b: ");
Serial.println(brightness);
FastLED.setBrightness (brightness);
ADMUX = 0x40 | (0 & 0x07); // устанавливаем admux обратно на аналоговый вывод A0 (для чтения микрофонного входа
counter = 0;
}
counter++;
sei();
}
}
Вот вывод, как показано (по сути, это вывод бессмысленных, не целых
значений):
b: ⸮
b: ⸮
b:
b:
b: ⸮
b: ⸮
b:
b: ⸮
b: ⸮
b:
b: ⸮
b: ⸮
b: ⸮
b:
b: ⸮
b: ⸮
b:
b: ⸮
b: ⸮
b:
Если я закомментирую строку fht_mag_octave
и раскомментирую fht_mag_log()
, то вот вывод (который выглядит правильно, когда я поворачиваю штифт потенциометра):
b: 0
b: 0
b: 0
b: 0
b: 0
b: 9
b: 35
b: 38
b: 48
b: 85
b: 143
b: 171
b: 188
b: 204
b: 224
b: 245
b: 280
b: 332
Проблема в том, что значение A2 "яркость" не читается правильно, если я использую fht_mag_octave()
. Если я закомментирую только строку fht_mag_octave()
, то все работает отлично. Я также могу использовать fht_mag_log
вместо этого, и это будет работать отлично.
Это заставляет меня думать, что fht_mag_octave()
делает что-то, что мешает работе регистров АЦП.
Есть идеи?
@buzzandy, 👍0
Обсуждение0
- Почему мой код не воспроизводит звук для Arduino ?
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
Пробовали ли вы проводить последовательные измерения каждые 100 минут, чтобы посмотреть, изменится ли результат?, @Tony Stewart Sunnyskyguy EE75
Привет! Да. Код показывает цикл (я настроил его с каждых 100 циклов на каждый цикл... без изменений в поведении). Значения меняются, когда я поворачиваю Pot (когда я закомментирую строку fht_mag_octave(), но в противном случае я получаю бессмыслицу. Это говорит мне, что вывод Pot настроен правильно, и что основные вызовы АЦП работают. ЕДИНСТВЕННАЯ переменная — fht_mag_octave(), @buzzandy
Я имел в виду повторение только А2 подряд, @Tony Stewart Sunnyskyguy EE75
@TonyStewart, Вы гений! Это сработало. Я просто добавил дубликат чтения A2 сразу после этого, и результаты второго чтения были точны! Как вы думаете, в чем причина? И почему простое добавление задержки перед первым вызовом не решило бы это?, @buzzandy
Понятия не имею, в чем причина, я рад, что моя интуиция оказалась верной. Только OEM знает наверняка., @Tony Stewart Sunnyskyguy EE75