In dem folgenden Versuch konstruieren wir einen einfachen Musik-Visualisierer, der grundsätzlich lediglich aus drei Komponenten besteht. Die
Aufgabe eines Mikrocontrollers übernimmt Arduino Uno, Musikklänge werden von dem Modul KY-037, auf dem ein Mikrofon angebracht ist, in Empfang genommen und schließlich
werden die Ergebnisse auf einer RGB-Matrix, die aus acht Spalten und acht Reihen besteht, angezeigt. Das von dem Modul KY-037 gesendete analoge Signal wird über den
analogen Eingang von dem Mikrocontroller eingelesen und für die Anzeige auf der Matrix untersucht. Bei der Einstellung der Pegelanzeige kommt es darauf an, den maximalen
Schallpegel an eine aus acht Pixel bestehender Spalte der Matrix anzupassen. Dazu verfügt die Schaltung über ein Potentiometer, mit dem die hierfür notwendige Justierung
vorgenommen werden kann. Zusätzlich kann das auf dem KY-037 Modul eingebaute Trimmer verwendet werden. Des Weiteren verfügt die Schaltung über einen Schalter, mit dem
zwischen zwei Anzeige-Modi umgeschaltet werden kann. In dem ersten Modus, den wir als „Lauf-Anzeige“ bezeichnen, werden die Spalten im Messung-Takt von links nach rechts
verschoben. Die letzte Messung wird dann immer in der ersten linken Spalte visualisiert. In dem Modus werden die Messungen alle 50ms ausgewertet. In dem zweiten Modus
unter den Namen „Voll-Anzeige“ werden zuerst acht Messungen für jede Spalte gesammelt, bevor die Matrix aktualisiert wird. Die Auswertungszeitspanne in diesem Modus
beträgt 20 ms.
Das Auslesen von Werten über den analogen Eingang erfolgt fortlaufend. Innerhalb des vorbestimmten Zeitfenster von 50 ms für den ersten Modus und 20 ms für den zweiten
werden mehrere Messungen durchgeführt. Festgehalten werden jeweils die maximalen und minimalen Werte, die dann bei der Ergebnisbildung voneinander abgezogen werden (Spitze
zu Spitze – Auswertung).
Schallsensor
Der Schallsensor KY-037 (erhältlich im Handel auch unter anderen Bezeichnungen) besteht u.a. aus einem Mikrofon, dem Komparator LM393 und einem
Trimm-Potentiometer. Man kann zwischen zwei Ausgängen wählen. Bei dem ersten Ausgang handelt es sich um einen digitalen Ausgang. Er kann dazu verwendet werden, bei
einer bestimmten Schallschwelle einen Schaltvorgang auszulösen. Der zweite Ausgang, den wir in unserer Schaltung nutzen, ist ein analoger Ausgang. Die Empfindlichkeit
beider Ausgänge kann mit dem Trimmerpoti reguliert werden. Die Spannungsversorgung des Moduls beträgt 3,3V bis 5V. Da unsere Schaltung mit 5V versorgt wird, sind
keine weiteren Anpassungsmaßnahmen notwendig.
Der Arduino Uno, der in der Schaltung als die Rechenzentrale auftritt, muss vier seiner Pins überwachen und auswerten. Der erste Pin (2) ist als Ausgang
definiert und wird dazu benutzt, die Matrix zu steuern. Er wird mithilfe der eingebundenen Bibliothek verwaltet. Der zweite Pin (3) ist als Eingang definiert und
wird dazu verwendet, den aktuellen Zustand des Schalters S1 abzufragen. Mit dem Schalter kann man zwischen zwei Anzeige-Modi umschalten. Der dritte Pin (A0) kommt
zum Einsatz als analoger Eingang und empfängt die Signale von dem Schallsensor. Auch der vierte Pin (A1) fungiert in der Schaltung als analoger Eingang. Er wertet
die Signale von dem Potentiometer P1 aus.
Bei den 64 LEDs der Matrix CJMCU-64 handelt es sich um RGB-LEDs. Abkürzung RGB steht für Rot, Gelb und Blau. Jede RGB-Leuchtdiode besteht intern aus drei
Leuchtionen, die grün, gelb und blau leuchten. Durch Mischung dieser drei Grundfarben können andere Farben generiert werden. Wenn z.B. alle drei interne Leuchtdioden
aufleuchten, entsteht ein weißes Licht. Durch Steuern der Helligkeit der einzelnen Leuchtdioden kann eine breite Palette an Farblicht einer RGB-LED generiert werden.
In dem Beispiel werden nur zwei Farben verwendet. Für unteren Bereich der Anzeige ist die Farbe Blau zuständig. Der obere Bereich leuchtet rot. Im Programm kann
man durch Eingabe des Helligkeitswertes für die einzelnen Leuchtionen jeder RGB-LED auch andere
Farben auswählen.
// **********************************************************************************************
// Pegelanzeige mit RGB-Matrix
// Arduino UNO mit 8x8 RGB-Matrix und Mikrofonmodul KY-037
// Arduino IDE 2.3.2
// **********************************************************************************************
#include<Adafruit_NeoPixel.h> // Matrix Bibliothek
Adafruit_NeoPixel strip(64, 2, NEO_GRB + NEO_KHZ800);
int Zeitfenster; // Pause zwischen Messungen in ms
int Messung; // Analoges Wert von Mikrofon
int Signal; // Aktuelle Messung
int Messung_Zaehler; // 8 Messungen bei Vollausschlag
float Teilwert; // Pegelanpassung mit Poti
int Linie [8][8] = { { 0, 8, 16, 24, 32, 40, 48, 56 }, // Matrix Belegung
{ 1, 9, 17, 25, 33, 41, 49, 57 },
{ 2, 10, 18, 26, 34, 42, 50, 58 },
{ 3, 11, 19, 27, 35, 43, 51, 59 },
{ 4, 12, 20, 28, 36, 44, 52, 60 },
{ 5, 13, 21, 29, 37, 45, 53, 61 },
{ 6, 14, 22, 30, 38, 46, 54, 62 },
{ 7, 15, 23, 31, 39, 47, 55, 63 } };
int RGB [8][8][3]; // Farbenwerte pro Pixel
int Anzeige_Schalter = 3; // Anzeige-Umschaltung
int Messung_IN = A0; // Eingang Mikrofon
int Poti_IN = A1; // Eingang Poti
// **********************************************************************************************
void setup() {
pinMode (Anzeige_Schalter, INPUT_PULLUP); // Anzeige-Umschaltung
strip.begin(); // Matrix Initialisierung
strip.show();
strip.setBrightness(20);
}
// **********************************************************************************************
void Spalte_mit_Farben_belegen (int Spalte) {
float Zwischenwert = 0; // Pegelauschlag abfragen und LEDs
int Multiplikator = 0; // entsprechend färben
for (int i=7; i>-1; i--) {
Multiplikator++;
Zwischenwert = Multiplikator * Teilwert;
if (Signal >= Zwischenwert) {
RGB [Spalte][i][0] = 0;
RGB [Spalte][i][1] = 0;
RGB [Spalte][i][2] = 255;
if (i < 4 ) {
RGB [Spalte][i][0] = 255;
RGB [Spalte][i][2] = 0;
}
strip.setPixelColor(Linie [Spalte][i], RGB [Spalte][i][0],
RGB [Spalte][i][1], RGB [Spalte][i][2]);
}
}
}
// **********************************************************************************************
void loop() {
unsigned long startMillis = millis();
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
while (millis() - startMillis < Zeitfenster) {
Messung = analogRead(Messung_IN); // Messung
if (Messung < 1024) {
if (Messung > signalMax) {
signalMax = Messung;
}
elseif (Messung < signalMin) {
signalMin = Messung; }
}
}
Signal = signalMax - signalMin;
float Poti_Messwert = analogRead (Poti_IN); // Pegelanpassung mit Poti
Teilwert = Poti_Messwert * 30 / 1023;
if (digitalRead(Anzeige_Schalter) == HIGH) { // ---------------- Modus Lauf - Anzeige
Zeitfenster = 50;
// Spalten von rechts nach links
for (int i=7; i>0; i--) { // mit Nachbar-Farben belegen
for (int j=0; j<8; j++) {
for (int k=0; k<3; k++) {
RGB [i][j][k] = RGB [i-1][j][k];
} // Neue Farben LEDs zuordnen
strip.setPixelColor(Linie [i][j], RGB [i][j][0], RGB [i][j][1], RGB [i][j][2]);
}
}
for (int i=0; i<8; i++) { // Erste Spalte links löschen
RGB [0][i][0] = 0; RGB [0][i][1] = 0; RGB [0][i][2] = 0;
strip.setPixelColor(Linie [0][i], RGB [0][i][0], RGB [0][i][1], RGB [0][i][2]);
}
Spalte_mit_Farben_belegen (0); // Erste Spalte links neu belegen
strip.show(); // Ergebnisse zeigen
}
if (digitalRead(Anzeige_Schalter) == LOW) { // ----------------- Modus Voll - Anzeige
Zeitfenster = 20;
Messung_Zaehler++;
if (Messung_Zaehler < 8) { // 8 Spalten = 8 Messungen
Spalte_mit_Farben_belegen (Messung_Zaehler); // Jede Spalte neu belegen
}
if (Messung_Zaehler >= 7) { // Anzeige erst, ween alle 8 Messungen
Messung_Zaehler = -1; // fertig.
strip.show(); // Ergebnisse zeigen
for (int i=0; i<8; i++) { // nach Anzeige alles löschen
for (int j=0; j<8; j++) {
RGB [i][j][0] = 0; RGB [i][j][1] = 0; RGB [i][j][2] = 0;
strip.setPixelColor(Linie [i][j], RGB [i][j][0], RGB [i][j][1], RGB [i][j][2]);
}
}
}
}
}
// **********************************************************************************************