Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить

Анализатор спектра на китайском lgt8f328p

Ср июн 16, 2021 22:25:11

Привет кошакам и кошечкам. Тут AlexGiver сподвиг меня на эту тему. Решил свою версию реализовать в очередную поделку на кухню.
Публикую скетч и демонстрацию. На вопросы, кому будет интересно, отвечу.
Спойлер
Код:
//WAVGAT UNO R3 with LGT8F328P (32 mHz)

#define FHT_N 256
#define OCTAVE 1
# define OCT_NORM 1
#include <FHT.h>
#include <FastLED.h>

#define ANALOG_IN1    A0
#define ANALOG_IN2    A1

#define DIN_PIN1      8
#define DIN_PIN2      9

#define LOW_PASS 60

#define COLUMNS 8
#define LEVELS 8
#define DEPTH 8
#define MAGIC_NUMBER 140

#define NUM_LEDS COLUMNS*LEVELS
#define BRIGHTNESS 25

CRGB leds_l[NUM_LEDS];
CRGB leds_r[NUM_LEDS];

bool channel = true;
int integrator_mass [DEPTH][COLUMNS];
int v_array[COLUMNS];
double equaliser[]  = {0.95, 0.9, 1, 1.05, 1.1, 1.2, 1.3, 1.6};

void setup()
{
  pinMode(ANALOG_IN1, INPUT);
  pinMode(ANALOG_IN2, INPUT);
  analogReference(INTERNAL1V024);
  analogReadResolution(12);
  FastLED.addLeds<WS2812B, DIN_PIN1, GRB>(leds_l, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<WS2812B, DIN_PIN2, GRB>(leds_r, NUM_LEDS).setCorrection(TypicalLEDStrip);
}

void loop()
{
  runFHT();
  runPrepareArray();
  runIntegrator();
  runDisplay();
  channel = !channel;
}
void runDisplay()
{
  if (channel == true) {
    for (byte l = 0; l < LEVELS; ++l ) {
      for (byte c = 0; c < COLUMNS; ++c) {
        if ((l < v_array[c])) {
          if (l < 4) leds_l[l * LEVELS + c].setRGB( 0, 255, 0);
          else if (l > 3 && l < 6) leds_l[l * LEVELS + c] = CRGB::Yellow;
          else if (l > 5 ) leds_l[l * LEVELS + c] = CRGB::Red;
        }
        else
          leds_l[l * LEVELS + c].setRGB( 0, 0, 0);
      }
    }
  } else {
    for (byte c = 0; c < COLUMNS; ++c) {
      for (byte l = 0; l < LEVELS; ++l ) {
        if ((l < v_array[c])) {
          if (l < 4) leds_r[c * LEVELS + l].setRGB( 0, 255, 0);
          else if (l > 3 && l < 6) leds_r[c * LEVELS + l] = CRGB::Yellow;
          else if (l > 5 ) leds_r[c * LEVELS + l] = CRGB::Red;
        }
        else
          leds_r[c * LEVELS + l].setRGB( 0, 0, 0);
      }
    }
  }
  FastLED.show(BRIGHTNESS);
}

void runPrepareArray() {
  for (byte c = 0; c < COLUMNS; ++c) v_array[c] = fht_oct_out[c] * equaliser[c];
}

void runIntegrator(){
  double tempData = 0;
  for (byte d = DEPTH - 1; d > 0; --d) {
    for (byte c = 0; c < COLUMNS; ++c) {
      integrator_mass[d][c] = integrator_mass[d-1][c];
    }
  }
  for (byte c = 0; c < COLUMNS; ++c) {
    integrator_mass[0][c] = (double) v_array[c];
    tempData = 0;
    for (byte d = 0; d < DEPTH; ++d) {
        tempData = tempData + integrator_mass[d][c];
    }
    v_array[c] = map(tempData / DEPTH, LOW_PASS,MAGIC_NUMBER,0,LEVELS); 
  } 
}

void runFHT()
{
  for (int i = 0 ; i < FHT_N ; i++) {
    if (channel == true) {
      fht_input[i] = (analogRead(ANALOG_IN1) - 2048);
    }
    else {
      fht_input[i] = (analogRead(ANALOG_IN2) - 2048);
    }
  }
  fht_window();
  fht_reorder();
  fht_run();
  fht_mag_octave();
}

Демонстрация - https://cloud.mail.ru/public/xnsT/aZkpcVg86
Обязательно смещение на входах Uref/2 и НЧ фильтр со срезом выше 18-20 кГц
В проекте используются матрицы 8*8 из адресных светодиодов
Ответить