Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Komponenten und Zubehör

Arduino Nano 33 BLE × 1
Elektret-Mikrofon-Verstärker MAX9814 (mit AGC) × 1
0,91" OLED I2C Display 128×32 Pixel (SSD1306) × 1
Kondensator 4,7 nF (für RC-Tiefpass, Grenzfrequenz ~17 kHz) × 1
Kondensator 470 µF (Netzteil-Puffer) × 1
Widerstand 2 kΩ (für RC-Tiefpass) × 1

Apps und Online-Dienste

Über dieses Projekt

Einführung

Ein Balkendiagramm auf einem kleinen OLED reagiert in Echtzeit auf Musik und Geräusche. Tiefe Frequenzen links, hohe rechts – logarithmische Skalierung angelehnt an die menschliche Hörwahrnehmung.

Aufbau & Verkabelung

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Störungsbehebung: 50/60 Hz Brummen

Netzfrequenz-Störungen durch benachbarte Geräte. Abhilfe: Faraday-Käfig – Schaltung in Metallgehäuse, Gehäuse an Masse legen.

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Abtastrate & Nyquist

Arduino Nano 33 BLE mit analogRead() schafft ~35.000 Samples/s. Nyquist → max. 17,5 kHz. Sicherheitshalber 8 kHz Obergrenze via Tiefpass.

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED
Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED
Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED
Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Maximale Abtastrate messen

#define ANALOG_PIN A0
#define SAMPLES 1000000.0
int newTime, analogValue;
void setup() {
  Serial.begin(9600);
  Serial.println("Sampling... please wait.");
}
void loop() {
  newTime = micros();
  for (int i = 0; i < (int)SAMPLES; i++) {
    analogValue = analogRead(ANALOG_PIN);
  }
  float elapsedTimePerSampleUs = (micros() - newTime) / SAMPLES;
  Serial.print("Time per sample (us): "); Serial.println(elapsedTimePerSampleUs);
  Serial.print("Max sampling freq (Hz): "); Serial.println(pow(10,6) / elapsedTimePerSampleUs);
}
Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Echtzeit-Abtastung mit Busy-Wait:

for (int i = 0; i < SAMPLES; i++) {
  unsigned long newTime = micros();
  int value = analogRead(ANALOG_PIN);
  vReal[i] = value; vImag[i] = 0;
  while (micros() < (newTime + sampling_period_us)) { yield(); }
}

Benutzeroberfläche (OLED)

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Bildschirm in 11 Frequenzzonen (logarithmisch, Zonen 3–13 von 14), angepasst an menschliches Gehör (20 Hz – 20 kHz, Erwachsene ~15–17 kHz).

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Jeder Balken: gestrichelte Linien = Maximum im Band, gefülltes Rechteck = Mittelwert. Anzeige in dB (heuristische Referenz).

Funktionsweise

  1. Audio-Samples per analogRead + Busy-Wait mit fester Abtastrate (24 kHz) erfassen (1024 Samples, 2er-Potenz für FFT).
  2. FFT (arduinoFFT Bibliothek): DC-Entfernung → Hamming-Fenster → FFT → Betragsspektrum.
  3. Spektrum in 14 logarithmische Bänder aufteilen, 11 davon (Zone 3–13) in dB darstellen.

Zum Mikrofon-Modul MAX9814

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Elektret-Mikrofon: Quasi-permanent geladenes Dielektrikum (elektrostatisches Gegenstück zum Permanentmagneten). Membranbewegung ändert Kapazität → Spannungsschwankung → FET-Verstärker.

MAX9814: Mikrofonverstärker mit automatischer Gain-Control (AGC), geringem Rauschen, Bias 1,25 V, 2 Vpp Ausgang. Drei Gain-Stufen (40/50/60 dB) per Jumper an GAIN-Pin. Attack/Release-Verhältnis anpassbar (Standard 1:4000). Ausgang DC-gekoppelt (1,25 V Bias) – für Line-In Koppelkondensator (≥1 µF, besser 33–100 µF) nötig. Versorgung 2,7–5,5 V.

OLED Display 0,91" 128×32 I2C

Keine Hintergrundbeleuchtung nötig (selbstleuchtend), niedriger Stromverbrauch. 4 Pins: VCC, GND, SDA (A4), SCL (A5). Bibliotheken: Adafruit_SSD1306, Adafruit_GFX.

Arduino Nano 33 BLE Klangspektrum-Visualisierer: Echtzeit-Audio-Display auf OLED

Ausblick

Nächste Version: Optimiertes ADC-Reading & FFT für nRF52840 (Nano 33 BLE Prozessor).

Code

Sound Spectrum Visualizer für Arduino Nano 33 BLE

Benötigte Bibliotheken: arduinoFFT, Adafruit_GFX, Adafruit_SSD1306.

/* Sound Spectrum Visualizer for Arduino Nano 33 BLE
 * @author Enrique Albertos
 * GPL v3
 */
#include "arduinoFFT.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SAMPLES 1024
#define SAMPLING_FREQ 24000
#define AMPLITUDE 100
#define FREQUENCY_BANDS 14
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define BARWIDTH 11
#define BARS 11
#define ANALOG_PIN A0
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
double vImag[SAMPLES], vReal[SAMPLES];
unsigned long sampling_period_us;
arduinoFFT fft = arduinoFFT(vReal, vImag, SAMPLES, SAMPLING_FREQ);
float reference = log10(50.0);
double coutoffFrequencies[FREQUENCY_BANDS];

void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); }
  display.clearDisplay(); display.display();
  display.setRotation(0); display.invertDisplay(false);
  sampling_period_us = (1.0 / SAMPLING_FREQ) * 1e6;
  double basePot = pow(SAMPLING_FREQ / 2.0, 1.0 / FREQUENCY_BANDS);
  coutoffFrequencies[0] = basePot;
  for (int i = 1; i < FREQUENCY_BANDS; i++) coutoffFrequencies[i] = basePot * coutoffFrequencies[i-1];
  // Gestrichelte Trennlinien
  for (int i = 0; i < BARS - 1; i++)
    for (int j = 0; j < SCREEN_HEIGHT; j += 4)
      display.writePixel((i+1)*BARWIDTH + 2, j, SSD1306_WHITE);
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
}

int oldHeight[20], oldMax[20];

void loop() {
  // Sampling
  for (int i = 0; i < SAMPLES; i++) {
    unsigned long newTime = micros();
    int value = analogRead(ANALOG_PIN);
    vReal[i] = value; vImag[i] = 0;
    while (micros() < (newTime + sampling_period_us)) yield();
  }
  // FFT
  fft.DCRemoval();
  fft.Windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  fft.Compute(FFT_FORWARD);
  fft.ComplexToMagnitude();

  double median[20] = {0}, max[20] = {0};
  int index = 0;
  double hzPerSample = (1.0 * SAMPLING_FREQ) / SAMPLES;
  double hz = 0, sum = 0; int count = 0;
  for (int i = 2; i < SAMPLES/2; i++) {
    count++; sum += vReal[i];
    if (vReal[i] > max[index]) max[index] = vReal[i];
    if (hz > coutoffFrequencies[index]) {
      median[index] = sum / count; sum = 0; count = 0; index++; max[index] = 0;
    }
    hz += hzPerSample;
  }
  if (sum > 0) median[index] = sum / count;

  // Anzeige
  int bar = 0;
  for (int i = FREQUENCY_BANDS - 1; i >= 3; i--) {
    int newHeight = 0, newMax = 0;
    if (median[i] > 0 && max[i] > 0) {
      newHeight = 20.0 * (log10(median[i]) - reference);
      newMax = 20.0 * (log10(max[i]) - reference);
    }
    if (newHeight < 0) newHeight = 1;
    if (newMax < 0) newMax = 1;
    if (newHeight >= SCREEN_HEIGHT - 2) newHeight = SCREEN_HEIGHT - 3;
    if (newMax >= SCREEN_HEIGHT - 2) newMax = SCREEN_HEIGHT - 3;

    int barX = bar * BARWIDTH + 5;
    // Alte Balken löschen
    if (oldHeight[i] > newHeight) display.fillRect(barX, newHeight+1, 7, oldHeight[i], SSD1306_BLACK);
    if (oldMax[i] > newHeight)
      for (int j = oldMax[i]; j > newHeight; j -= 2)
        display.drawFastHLine(barX, j, 7, SSD1306_BLACK);
    // Neue Max-Linien
    for (int j = newMax; j > newHeight; j -= 2)
      display.drawFastHLine(barX, j, 7, SSD1306_WHITE);
    // Neuer Median-Balken
    display.fillRect(barX, 1, 7, newHeight, SSD1306_WHITE);
    oldMax[i] = newMax; oldHeight[i] = newHeight;
    bar++;
  }
  display.drawFastHLine(0, SCREEN_HEIGHT-1, SCREEN_WIDTH, SSD1306_WHITE);
  display.display();
}

Schaltpläne

soundspectrumvisualizer_qLzRsVPVlc.fzz (Fritzing) + PNG-Schaltbild

Herstellungsprozess

  1. Klassisches Pong-Spiel auf Arduino UNO mit OLED-Display bauen – Schritt-für-Schritt-Tutorial
  2. K30 CO₂-Sensor: Echtzeit-Luftqualitätsmessung mit Arduino
  3. Kommunikationshilfe für Taubblinde: 1Sheeld + Arduino + Sprachausgabe & Anzeige
  4. Smartes Sparschwein: Münzprüfer mit Arduino Nano steuern
  5. LED per Bluetooth mit Arduino steuern – Einfache DIY-Anleitung
  6. Zwei Schrittmotoren mit Arduino Nano & Joystick steuern – Einfaches Tutorial
  7. Audio-Datenübertragung mit Arduino Nano 33 BLE Sense
  8. Handheld Geigerzähler mit Arduino Nano selbst bauen
  9. Präzise Solareinstrahlungsmessung mit Arduino UNO & Ethernet Shield
  10. Arduino Nano Fress-Roboter: Ultraschall-gesteuerter Mund (Schritt-für-Schritt)