Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

FHT Audio Spectrum Visualizer – Bouw een indrukwekkend LED-audiodisplay

Onderdelen en benodigdheden

OnderdeelAantalOpmerking
Arduino Nano R31
WS2812B 8x32 RGB LED-matrix1256 LED's, serpentine layout
Weerstand 4,75k ohm3
Weerstand 100k ohm2
Weerstand 10k ohm2Voor drukknoppen
Weerstand 390 ohm1Voor datalijn LED-matrix
Diode 1N4007 (of 1N4004)1Bescherming voeding
Condensator 100 nF2Decoupling
Condensator 1000 µF1Voedingstabilisatie
Drukknop 12mm2Kleur & helderheid
Prototype printplaat 4x6 cm1
Stereo RCA-vrouwelijke printconnector1Audio-in

Benodigde tools en machines

  • Solderbout
  • 3,5mm audio jack kabel naar stereo RCA (voor aansturing)

Over dit project

De Arduino FHT-bibliotheek

FHT (Fast Hartley Transform) doet hetzelfde als de bekende FFT (Fast Fourier Transform), maar werkt alleen met reële data. FFT gebruikt complexe getallen. Daardoor is FHT tweemaal zo snel en gebruikt de helft van het geheugen.

De bibliotheek gebruikt één array voor sampling (in plaats van twee bij FFT), vereenvoudigt de wiskunde en vermijdt zware floating-point berekeningen door keertabellen te gebruiken.

Nadeel: FHT retourneert de helft van de array-grootte, wat resolutie aan de randen van het frequentiebereik vermindert. Voor een visuele gadget is dit prima – we willen LEDs op de muziek laten reageren, geen meetinstrument bouwen.

De FHT is zo snel dat een delay(10) in de loop nodig is om flikkeren te voorkomen. Het resultaat is veel vloeiender dan de FFT-versie.

De nieuwe versie

De hardware is identiek aan de vorige versie. Alleen een extra drukknop en 10k-weerstand worden toegevoegd, plus een code-update.

Nieuwe functies:

  • Extra knop voor helderheidsinstelling.
  • Instellingen (kleur & helderheid) worden opgeslagen in EEPROM en hersteld bij herstart.
  • Visuele feedback bij indrukken knoppen en opstarten (uitschakelbaar).

Code

FHT Code Versie (Arduino)

/* Copyright (c) 2020 Janux - MIT License
   Based on original MAX72xx/FFT project by Shajeeb.
   Config section based on work by Ragnar Ranøyen Homb (Norwegian Creations). */
#define LIN_OUT 1
#define FHT_N 128
#include <FHT.h>

#define xres 32
#define yres 8
#define ledPIN 6
#define NUM_LEDS (xres * yres)
#include <Adafruit_NeoPixel.h>

#define colorPIN 5
#define brightnessPIN 10
byte displaycolor = 0;
byte brightness = 1;
#include <EEPROM.h>
#define CONFIG_START 32
#define CONFIG_VERSION "VER01"

typedef struct {
  char version[6];
  byte displaycolor;
  byte brightness;
} configuration_type;
configuration_type CONFIGURATION = { CONFIG_VERSION, displaycolor, brightness };

byte yvalue;
int peaks[xres];
byte state = HIGH, previousState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 100;
byte data_avgs[xres];

Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUM_LEDS, ledPIN, NEO_GRB + NEO_KHZ800);

byte eq[32] = { 60,65,70,75,80,85,90,95,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,115,125,140,160,185,200,200,200 };
bool EQ_ON = true;

byte colors[][8] = {
  {170,160,150,140,130,120,1,1},
  {1,5,10,15,20,25,90,90},
  {90,85,80,75,70,65,1,1},
  {90,90,90,30,30,30,1,1},
  {170,160,150,140,130,120,110,0}
};

byte charBitmap[] = {
  0x1C,0x10,0x10,0x10,0x10,0x1C,0x08,0x18,0x08,0x08,0x08,0x1C,
  0x0C,0x12,0x04,0x08,0x10,0x1E,0x0C,0x12,0x02,0x06,0x12,0x0C,
  0x10,0x10,0x10,0x14,0x1E,0x04,0x1E,0x10,0x1E,0x02,0x12,0x0C,
  0x1E,0x10,0x10,0x1E,0x12,0x1E,0x1E,0x02,0x04,0x08,0x08,0x08,
  0x0C,0x12,0x0C,0x12,0x12,0x0C,0x1C,0x12,0x1C,0x12,0x12,0x1C
};

void setup() {
  pixel.begin();
  ADCSRA = 0b11100101; // free running, prescaler 32
  ADMUX = 0b00000000;  // A0, externe referentie
  if (loadConfig()) {
    displaycolor = CONFIGURATION.displaycolor;
    brightness = CONFIGURATION.brightness;
  }
  pixel.setBrightness(brightness * 24 + 8);
  showSettings(3, true);
}

void loop() {
  while (1) {
    Sampling();
    RearrangeFHT();
    SendToDisplay();
    colorChange();
    brightnessChange();
    delay(10);
  }
}

void Sampling() {
  for (int i = 0; i < FHT_N; i++) {
    while (!(ADCSRA & 0x10));
    ADCSRA = 0b11110101;
    byte m = ADCL;
    byte j = ADCH;
    int value = (j << 8) | m;
    value -= 0x0200;
    value <<= 6;
    fht_input[i] = value / 8;
  }
  fht_window(); fht_reorder(); fht_run(); fht_mag_lin();
}

void RearrangeFHT() {
  int step = (FHT_N / 2) / xres;
  int c = 0;
  for (int i = 0; i < (FHT_N / 2); i += step) {
    data_avgs[c] = 0;
    for (int k = 0; k < step; k++) data_avgs[c] += fht_lin_out[i + k];
    data_avgs[c] /= step;
    c++;
  }
}

void SendToDisplay() {
  for (int i = 0; i < xres; i++) {
    if (EQ_ON) data_avgs[i] = data_avgs[i] * (float)eq[i] / 100;
    data_avgs[i] = constrain(data_avgs[i], 0, 80);
    data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres);
    yvalue = data_avgs[i];
    peaks[i]--;
    if (yvalue > peaks[i]) peaks[i] = yvalue;
    yvalue = peaks[i];
    setColumn(i, yvalue);
  }
  pixel.show();
}

void setColumn(byte x, byte y) {
  for (byte i = 0; i < yres; i++) {
    int led = GetLedFromMatrix(x, i);
    if (peaks[x] > i) {
      switch (displaycolor) {
        case 4:
          if (colors[displaycolor][i] == 0) pixel.setPixelColor(led, 255,255,255);
          else pixel.setPixelColor(led, Wheel(colors[displaycolor][i]));
          break;
        case 5: pixel.setPixelColor(led, Wheel(x * 16)); break;
        case 6: pixel.setPixelColor(led, Wheel(i * y * 3)); break;
        case 7: // Vlaggenmodus
          if (i < yres - 2) {
            if (x & 0x01) pixel.setPixelColor(led, 0,0,255);
            else pixel.setPixelColor(led, 255,0,0);
          } else pixel.setPixelColor(led, 255,255,255);
          break;
        default: pixel.setPixelColor(led, Wheel(colors[displaycolor][i]));
      }
    } else pixel.setPixelColor(led, 0);
  }
}

int GetLedFromMatrix(byte x, byte y) {
  x = xres - x - 1;
  int led;
  if (x & 0x01) led = ((x + 1) * yres - y - 1);
  else led = ((x + 1) * yres - yres + y);
  return constrain(led, 0, NUM_LEDS);
}

void colorChange() {
  int reading = digitalRead(colorPIN);
  if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) {
    displaycolor++; if (displaycolor > 7) displaycolor = 0;
    showSettings(1, true); saveConfig(); lastDebounceTime = millis();
  }
  previousState = reading;
}

void brightnessChange() {
  int reading = digitalRead(brightnessPIN);
  if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) {
    brightness++; if (brightness > 7) brightness = 0;
    pixel.setBrightness(brightness * 24 + 8);
    showSettings(2, true); saveConfig(); lastDebounceTime = millis();
  }
  previousState = reading;
}

unsigned long Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) return pixel.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  if (WheelPos < 170) { WheelPos -= 85; return pixel.Color(0, WheelPos * 3, 255 - WheelPos * 3); }
  WheelPos -= 170; return pixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

int loadConfig() {
  if (EEPROM.read(CONFIG_START+0)==CONFIG_VERSION[0] &&
      EEPROM.read(CONFIG_START+1)==CONFIG_VERSION[1] &&
      EEPROM.read(CONFIG_START+2)==CONFIG_VERSION[2] &&
      EEPROM.read(CONFIG_START+3)==CONFIG_VERSION[3] &&
      EEPROM.read(CONFIG_START+4)==CONFIG_VERSION[4]) {
    for (unsigned int i=0; i=0; x--) {
    for (int y=5; y>=0; y--) {
      if ((charBitmap[val*6 + 5-y] >> x) & 0x01) {
        pixel.setPixelColor(GetLedFromMatrix(4-x+pos, y+1), Wheel((pos>10)*170));
        pixel.show();
      }
    }
  }
}

Schema's

FHT Audio Spectrum Visualizer – Bouw een indrukwekkend LED-audiodisplay FHT Audio Spectrum Visualizer – Bouw een indrukwekkend LED-audiodisplay

Productieproces

  1. 32-band Arduino Audio Spectrum Analyzer – Lineaire & Pseudo-Log Display
  2. Slimme Plantenalarmer – DIY Sensor voor Optimale Hydratatie
  3. Bouw een Italiaanse Woordklok met Arduino Nano, NeoPixel, LCD en RTC
  4. Bouw een Betrouwbare Sigfox kWh Meter met Arduino MKR Fox 1200
  5. Bluetooth Temperatuurmeter met Arduino Nano
  6. Contactloos Gebaarslot: Veilige toegang met APDS-9960 en Arduino
  7. Arduino Nano Companion Kit – Essentiële Componenten & Hulpmiddelen voor DIY Electronica
  8. USB MIDI Adapter Kit voor Arduino Micro / Leonardo – Complete Onderdelenlijst
  9. Geïsoleerde analoge ingangsschakeling voor Arduino bouwen
  10. RGB 32-band audio-spectrumvisualisator – Arduino LED-matrixproject
  11. Precisie Reactietijd Test met Arduino UNO