Странная проблема с библиотекой 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() делает что-то, что мешает работе регистров АЦП.

Есть идеи?

, 👍0

Обсуждение

Пробовали ли вы проводить последовательные измерения каждые 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