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

RGB 32-band audio-spectrumvisualisator – Arduino LED-matrixproject

Onderdelen en benodigdheden

Arduino Nano R3 1
WS2812B 8x32 RGB LED-matrix 1
Weerstand 4,75k ohm 3
Weerstand 100k ohm 2
Weerstand 10k ohm 1
Doorsteekweerstand 390 ohm 1
Condensator 100 nF 2
Condensator 1000 µF 1
SparkFun Drukknopschakelaar 12mm 1
4x6 cm multi-gaten prototypeprint 1

Benodigde tools en machines

  • Solderbout (standaard)
  • 3,5 mm Jack-splitterkabel

Over dit project

Het project

Dit project is bedoeld voor het maken van een RGB 32-band audio (muziek) frequentiespectrumvisualisator met Arduino Nano en een 8x32 WS2812B RGB LED-matrix.

Het oorspronkelijke project dat dit inspireerde

Een grote dank gaat naar Shajeeb, auteur van het oorspronkelijke project gebaseerd op de MAX72xx LED-matrix. Ik heb alleen het besturingsgedeelte van de LED-matrix aangepast om het aan te passen aan de RGB WS2812B LED-matrix.

Link naar oorspronkelijk project: 32-Band Audio Spectrum Visualizer Analyzer

De WS2812B RGB LED-matrix

Door het gebruik van een RGB LED-matrix gebaseerd op 5050 SMD high-brightness LEDs, is het nodig om een externe voeding te gebruiken, omdat de RGB-matrix meer dan 10mA per LED kan trekken. Daarom kan het met alle LEDs aan op maximale helderheid meer dan 2,5 Ampère trekken.

Om die reden heb ik een diode in serie op de +5V-lijn geplaatst, om de Arduino in stand-alone-modus te kunnen voeden wanneer de USB-kabel niet is aangesloten, en om te voorkomen dat de Arduino de bron van de RGB-matrix wordt, zodat de interne circuits van het bord niet overbelast worden met een stroom die ze niet kunnen leveren.

Naast de invoerdiode, om de ingang van de LED-matrix te beschermen tegen mogelijke spanningspieken, heb ik ook een 390 ohm weerstand in serie geplaatst tussen de Arduino-pin D6 en de Data-ingang, en een 1000 µF 12V condensator om de stabiliteit van de Arduino-voedingsspanning te verbeteren.

Hardware-montage

Zoals zichtbaar in de hoofdafbeelding maakte ik de eerste prototype op een 4x6 cm multi-gaten printplaat met twee RCA-audiobussen (direct op de print gesoldeerd) die ook vervangen kunnen worden door een 3,5 mm female Jack-bus. Het belangrijks om ron te vermijden is om de verbindingen tussen de bron en de audio-ingang van de print met een afgeschermde kabel te maken. Een ander tip is om de verbinding tussen de Arduino en de LED-matrix zo kort mogelijk te houden.

De code

Uiteindelijk is alle software gebaseerd op het geweldige werk van de auteur van de bemonsteringsprocedure via de FFT-bibliotheek en de definitieve realisatie van Shajeeb.

Ik heb twee functies toegevoegd:

De eerste is GetLedFromMatrix(...) om de matrix in rijen en kolommen af te beelden en elk van de 256 LEDs via rij- en kolomcoördinaten te kunnen adresseren.

De tweede is de functie die ik willekeurig SetColumn(...) noem – die de LEDs van elke kolom aanzet op basis van de piekwaarde verkregen door audio-digitalisering (waarden tussen 0 en 7) en op basis van de vooraf ingestelde kleuren in een tweedimensionale array. Je kunt experimenteren met de waarden en dus de kleuren naar believen. Om de code te vereenvoudigen gebruikte ik een subroutine genaamd Wheel() (afkomstig van een demo bij Adafruit's Neopixel-bibliotheek) die, uitgaande van een waarde tussen 0 en 255, een ongesigneerde 32-bit lange waarde retourneert die direct doorgegeven kan worden aan de setPixelColor-functie. Hierop kun je naar believen spelen, rekening houdend met de geheugenbeperkingen van de Arduino, en waar mogelijk het gebruik van 32-bit variabelen om RGB-kleurwaarden op te slaan te vermijden.

Audio-egalizatie

Omdat ik de tests uitvoerde met audio afkomstig van de geluidskaart geïntegreerd in het moederbord van de pc, om de frequentierespons te verbeteren, voegde ik een byte-array van 32 waarden toe die in feite een egalisatiecurve vormen om de bas te dempen en de hoogten te versterken. Als je het niet nodig hebt, zet de EQ_ON-variabele op false of verander dempingsniveau door de 32 waarden van de eq[32]-array te wijzigen. Een waarde van 100 laat de amplitude ongewijzigd, een waarde lager dan 100 dempt en een waarde hoger dan 100 versterkt het frequentieband.

LED-helderheid

De helderheid van de matrix is in de code vooraf ingesteld op 32 (constante BRIGHTNESS). De maximale helderheidswaarde van de WS2812B-matrix (op papier) is 255, maar al bij waarden groter dan 100 verandert het LED-licht van wit naar bleek geel. Het is waarschijnlijk nodig om de matrix via de twee centrale rode en zwarte draden te voeden in plaats van via de rechter connector.

Ik experimenteer er nog mee...

Tot slot, als je een maximale helderheid van 64 gebruikt, is een 1A-voeding waarschijnlijk voldoende, anders is 2A essentieel.

Toekomstige update

Ik werk aan een nieuwe versie die de OpenMusicLabs FHT-bibliotheek gebruikt, die zich vele malen sneller blijkt dan de Arduino FFT.

Blijf op de hoogte. :)

Excuseer mijn slechte Engels, ik gebruikte Google Translate.

Code

Spectrum_Analyzer_WS2812B.ino

/* Copyright (c) 2019 Shajeeb TM
   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:
   ...
   WS2812B Led Matrix versie door Janux
*/
#include <arduinoFFT.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

#define SAMPLES 64
#define xres 32
#define yres 8
#define ledPIN 6
#define NUM_LEDS (xres * yres)
#define BRIGHTNESS 32
#define buttonPin 5

byte yvalue;
byte displaycolumn, displayvalue;
int peaks[xres];
byte state = HIGH;
byte previousState = LOW;
byte displaycolor = 0;

double vReal[SAMPLES];
double vImag[SAMPLES];
byte data_avgs[xres];
arduinoFFT FFT = arduinoFFT();

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 100;

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

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

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, 0, 0},
  {170, 160, 150, 140, 130, 120, 1, 1},
  {170, 160, 150, 140, 130, 120, 1, 1}
};

void setup() {
  pixel.begin();
  pixel.setBrightness(BRIGHTNESS);
  ADCSRA = 0b11100101;
  ADMUX = 0b00000000;
}

void loop() {
  for (int i = 0; i < SAMPLES; i++) {
    while (!(ADCSRA & 0x10));
    ADCSRA = 0b11110101;
    int value = ADC - 512;
    vReal[i] = value / 8;
    vImag[i] = 0;
  }
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);

  int step = (SAMPLES / 2) / xres;
  int c = 0;
  for (int i = 0; i < (SAMPLES / 2); i += step) {
    data_avgs[c] = 0;
    for (int k = 0; k < step; k++) {
      data_avgs[c] = data_avgs[c] + vReal[i + k];
    }
    data_avgs[c] = data_avgs[c] / step;
    c++;
  }

  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] = peaks[i] - 1;
    if (yvalue > peaks[i]) peaks[i] = yvalue;
    yvalue = peaks[i];
    displaycolumn = i;
    displayvalue = yvalue;
    setColumn(displaycolumn, displayvalue);
  }
  pixel.show();
  displaycolorChange();
}

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

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

void displaycolorChange() {
  int reading = digitalRead(buttonPin);
  if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) {
    displaycolor++;
    if (displaycolor > 6) displaycolor = 0;
    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);
}

Aangepaste onderdelen en behuizingen

3D-printbestanden: arduino_rgb_audio_analyzer_lX4Dv4Pta2.zip

Schema's

Schema van de schakeling

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. TV-Uitgangskabel voor Arduino UNO Bouwen met Alleen Twee Weerstanden
  11. Precisie Reactietijd Test met Arduino UNO