Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Visualiseur de spectre audio RGB 32 bandes – Projet matrice LED Arduino

Composants et fournitures

Composant Quantité
Arduino Nano R3 1
Matrice LED RGB WS2812B 8x32 1
Résistance 4,75 kΩ 3
Résistance 100 kΩ 2
Résistance 10 kΩ 1
Résistance traversante 390 Ω 1
Condensateur 100 nF 2
Condensateur 1000 µF 1
Bouton poussoir 12 mm (SparkFun) 1
Plaque de prototype multi-trous 4x6 cm 1

Outils et machines nécessaires

À propos de ce projet

Le projet

Ce projet réalise un visualiseur de spectre de fréquence audio (musique) RGB 32 bandes utilisant un Arduino Nano et une matrice LED RGB 8x32 WS2812B.

Le projet original qui a inspiré celui-ci

Un grand merci à Shajeeb, auteur du projet original basé sur une matrice LED MAX72xx. J'ai seulement modifié la partie pilotage de la matrice pour l'adapter à la matrice RGB WS2812B.

Lien vers le projet original : 32-Band Audio Spectrum Visualizer Analyzer

La matrice LED RGB WS2812B

Avec une matrice LED RGB basée sur des LED SMD 5050 haute luminosité, une alimentation externe est nécessaire car la matrice peut consommer plus de 10 mA par LED. Avec toutes les LED allumées à luminosité max, la consommation peut dépasser 2,5 Ampères.

Pour cette raison, j'ai inséré une diode en série sur le +5V pour pouvoir alimenter l'Arduino en mode autonome (sans câble USB) et éviter que l'Arduino ne devienne la source d'alimentation de la matrice RGB, ce qui surchargerait ses circuits internes.

En plus de la diode d'entrée, pour protéger l'entrée de données de la matrice contre d'éventuels pics de tension, j'ai ajouté une résistance de 390 Ω en série entre la broche D6 de l'Arduino et l'entrée Data, et un condensateur 1000 µF 12V pour stabiliser la tension d'alimentation de l'Arduino.

Assemblage matériel

Comme visible sur la photo principale, j'ai réalisé le premier prototype sur une plaque multi-trous 4x6 cm en utilisant deux prises RCA audio (soudées directement sur la plaque) qui peuvent être remplacées par une prise Jack 3,5 mm femelle. Pour éviter le ronflement, il est important de faire les connexions entre la source et l'entrée audio du circuit avec un câble blindé. Autre conseil : gardez la connexion entre l'Arduino et la matrice LED la plus courte possible.

Le code

Tout le logiciel repose sur l'excellent travail de l'auteur de la procédure d'échantillonnage via la bibliothèque FFT et la réalisation finale de Shajeeb.

J'ai ajouté deux fonctions :

Égalisation audio

Comme j'ai testé avec l'audio de la carte son intégrée à la carte mère du PC, pour améliorer la réponse en fréquence, j'ai ajouté un tableau de 32 octets qui constitue une courbe d'égalisation pour atténuer les basses et renforcer les aigus. Si vous n'en avez pas besoin, mettez simplement EQ_ON à false ou modifiez le niveau d'atténuation en changeant les 32 valeurs du tableau eq[32]. Une valeur de 100 laisse l'amplitude inchangée, une valeur inférieure atténue, une valeur supérieure accentue la bande de fréquence.

Luminosité des LED

La luminosité de la matrice est fixée dans le code à 32 (constante BRIGHTNESS). La valeur max théorique des WS2812B est 255, mais déjà au-delà de 100, la lumière blanche vire au jaune pâle. Il faudrait probablement alimenter la matrice par les deux fils centraux rouge et noir au lieu du connecteur droit.

J'expérimente encore...

Enfin, avec une luminosité max de 64, une alimentation 1A suffit probablement, sinon 2A est indispensable.

Mise à jour future

Je travaille sur une nouvelle version utilisant la bibliothèque OpenMusicLabs FHT qui s'avère plusieurs fois plus rapide que la FFT Arduino.

Restez connectés ! :)

Pardonnez mon anglais approximatif, j'ai utilisé Google Translate.

Code

Spectrum_Analyzer_WS2812B.ino

/* Copyright (c) 2019 Shajeeb TM
 * Permission accordée gratuitement... (licence MIT)
 * Version WS2812B par Janux */
#include <arduinoFFT.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

#define SAMPLES 64          // Doit être puissance de 2
#define xres 32             // Nombre total de colonnes, <= SAMPLES/2
#define yres 8              // Nombre total de lignes
#define ledPIN 6            // Broche contrôle matrice LED
#define NUM_LEDS (xres * yres)
#define BRIGHTNESS 32
#define buttonPin 5         // Broche bouton pour changer mode couleur

byte yvalue, 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);

// Filtre EQ pour atténuer basses et améliorer aigus
// Utile sur carte son PC qui a souvent trop de basses et peu d'aigus
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 };

// Couleurs pour chaque LED, utilisées dans setColumn, 0 = couleur personnalisée
// Calculées par la fonction Wheel ci-dessous
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);
  // Configuration ADC pour échantillonnage rapide
  ADCSRA = 0b11100101; // Mode free-running, prédiviseur 32
  ADMUX = 0b00000000;  // Pin A0, référence externe
}

void loop() {
  // Échantillonnage
  for (int i = 0; i < SAMPLES; i++) {
    while (!(ADCSRA & 0x10)); // Attendre conversion ADC (bit ADIF)
    ADCSRA = 0b11110101;      // Effacer ADIF pour conversion suivante
    int value = ADC - 512;    // Lire ADC et soustraire offset DC
    vReal[i] = value / 8;     // Compresser et copier
    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);

  // Réorganiser résultats FFT pour correspondre aux colonnes (xres)
  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] += vReal[i + k];
    }
    data_avgs[c] /= step;
    c++;
  }

  // Affichage selon valeurs mesurées
  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];
    displaycolumn = i;
    displayvalue = yvalue;
    setColumn(displaycolumn, displayvalue);
  }
  pixel.show();
  displaycolorChange();
}

// Allume les LED de la colonne x selon la valeur y
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: // 0 dans tableau = couleur personnalisée pour pics
          if (colors[displaycolor][i] > 0) {
            pixel.setPixelColor(led, Wheel(colors[displaycolor][i]));
          } else {
            pixel.setPixelColor(led, 255, 255, 255); // Blanc pour pics
          }
          break;
        case 5: // Couleur par colonne
          pixel.setPixelColor(led, Wheel(x * 16));
          break;
        case 6: // Couleur par ligne
          pixel.setPixelColor(led, Wheel(i * 36));
          break;
        default: // Modes 0-3, couleurs du tableau
          pixel.setPixelColor(led, Wheel(colors[displaycolor][i]));
      }
    } else {
      pixel.setPixelColor(led, 0);
    }
  }
}

// Calcule numéro de LED par coordonnées x,y
// Valide pour WS2812B disposition serpentine horizontale
// LED 0 en bas à droite (connecteur entrée à droite)
// x=0-31, y=0-7, retourne 0-255
byte GetLedFromMatrix(byte x, byte y) {
  x = xres - x - 1;
  if (x & 0x01) { // Colonnes impaires : ordre inverse
    return ((x + 1) * yres - y - 1);
  } else { // Colonnes paires : ordre normal
    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;
}

// Utilitaire Adafruit Neopixel : 0-255 -> valeur couleur (transition R-G-B-R)
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);
}

Pièces personnalisées et boîtiers

Visualiseur de spectre audio RGB 32 bandes – Projet matrice LED Arduino Visualiseur de spectre audio RGB 32 bandes – Projet matrice LED Arduino

Fichiers 3D : arduino_rgb_audio_analyzer_lX4Dv4Pta2.zip

Schémas

Visualiseur de spectre audio RGB 32 bandes – Projet matrice LED Arduino

Processus de fabrication

  1. Analyseur de spectre audio Arduino 32 bandes – Affichage linéaire et pseudo-logarithmique
  2. Alerte Soif Plante Intelligente – Capteur DIY pour une Hydratation Optimale
  3. Horloge à Mots Italienne avec Arduino Nano, NeoPixel, LCD et RTC
  4. Compteur kWh Sigfox fiable avec Arduino MKR Fox 1200
  5. Moniteur de température Bluetooth avec Arduino Nano
  6. Serrure à gestes sans contact : Accès sécurisé avec APDS-9960 et Arduino
  7. Kit Compagnon Arduino Nano – Composants et Outils Essentiels pour l'Électronique DIY
  8. Circuit d'entrée analogique isolée pour Arduino : Protection contre les parasites industriels
  9. Test Précis de Temps de Réaction avec Arduino UNO