Das RGB LED Matrix Modul SK6812 verfügt über 40 RGB LEDs vom Typ 5050.
Bezug
Das mir vorliegende Modul habe ich über ebay.de für ca. 6€ inkl. Versandkosten* erstanden.
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Technische Daten des SK6812 RGB LED Modul
Das Modul verfügt wie bereits erwähnt über 40 LEDs vom Typ 5050 und hat die Abmaße (L x B x H) von 69 mm in der Länge, 57 mm in der Breite sowie 19 mm in der Höhe. Das Modul wird über den 5V Leitung gespeist und verbraucht dabei ca. 0,46 A.
Das Bild ist etwas dunkel geraten, da meine Kamera mit den hellen RGB LEDs nicht so richtig klarkam.
Das Modul wird einfach auf den Mikrocontroller gesteckt und bedeckt zunächst einmal alle Pins. Es werden jedoch die Pins nach oben durch Buchsenleisten bereitgestellt.
Beispiele
Auf der Wiki-Seite https://wiki.keyestudio.com/KS0416_keyestudio_SK6812_Shield vom Hersteller findet man ein kleines Beispiel, welches auf den Mikrocontroller hochgeladen werden kann und somit alle Funktionen des Shields aufzeigt.
Für das Programmieren des Moduls wird zusätzlich die Adafruit Bibliothek “Adafruit Neo Pixel” benötigt, welche in der Arduino IDE bequem über den Bibliotheksverwalter installiert werden kann. Wie du eine Bibliothek in der Arduino IDE installierst habe ich im gleichnamigen Beitrag Arduino IDE, Einbinden einer Bibliothek ausführlich erläutert.
Die Bibliothek zum Betreiben eines NeoPixels habe ich bereits mehrfach verwendet und unter anderem im Beitrag Arduino Lektion 31: 12bit RGB NeoPixel Ring verwendet.
Beispiel I – LED Lauflicht
Basierend auf dem Beispiel vom Hersteller habe ich ein LED-Lauflicht erzeugt, welches jede LED einmal aufleuchten lässt, zunächst in der Reihe, dann in jeder Spalte.
#include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif //Pin zum steuern des Moduls ist am digitalen Pin D13 angeschlossen #define PIN 13 const int MAX_PIXEL = 40; //das Modul verfügt über insgesamt 40 LEDs vom Typ 5050 Adafruit_NeoPixel strip = Adafruit_NeoPixel(MAX_PIXEL, PIN, NEO_GRB + NEO_KHZ800); //Konstanten für die Farben const uint32_t COLOR_RED = strip.Color(255, 0, 0); //Wenn alle Farben auf 0 sind dann ist die LED aus const uint32_t COLOR_NONE = strip.Color(0, 0, 0); const int PAUSE = 125; void setup() { Serial.begin(9600); //begin der kommunikation mit dem Modul strip.begin(); strip.setBrightness(25); strip.show(); } void loop() { lauflichtPixelFuerPixel(); lauflichtSpaltenweise(); lauflichtReihenweise(); } void lauflichtPixelFuerPixel() { for (int pixel = 0; pixel <= MAX_PIXEL; pixel++) { //setzen der aktuellen Pixelposition mit der Farbe "rot" strip.setPixelColor(pixel, COLOR_RED); strip.show(); //anzeigen der Farbe delay(PAUSE); //eine kleine Pause //setzen der Farbe auf "NONE" strip.setPixelColor(pixel, COLOR_NONE); strip.show(); //anzeigen der Farbe } } void lauflichtSpaltenweise() { int colIndex = 0; for (int spalte = 0; spalte <= 8; spalte++) { int index = colIndex; for (int pixel = 0; pixel < 5; pixel++) { strip.setPixelColor(index, COLOR_RED); index = index + 8; } strip.show(); //anzeigen der Farbe delay(PAUSE); //eine kleine Pause index = colIndex; for (int pixel = 0; pixel < 5; pixel++) { strip.setPixelColor(index, COLOR_NONE); index = index+8; } strip.show(); //anzeigen der Farbe colIndex = colIndex + 1; } } void lauflichtReihenweise() { int rowIndex = 0; for (int reihe = 0; reihe <= 4; reihe++) { int index = rowIndex; for (int pixel = 0; pixel < 8; pixel++) { strip.setPixelColor(index+pixel, COLOR_RED); } strip.show(); //anzeigen der Farbe delay(PAUSE); //eine kleine Pause index = rowIndex; for (int pixel = 0; pixel < 8; pixel++) { strip.setPixelColor(index+pixel, COLOR_NONE); } strip.show(); //anzeigen der Farbe rowIndex = rowIndex + 8; } }
Webseite zum steuern des RGB LED Moduls
Im ersten Beispiel habe ich gezeigt, wie ein einfaches Lauflicht erzeugt werden kann. Im weiteren Verlauf könnte ich nun aufzeigen wie man verschiedene Effekte generiert, jedoch ist es immer fast das gleiche, man benötigt eine Schleife (oder mehr) und steuert dann die Pixel an. Ich möchte als Nächstes jedoch zeigen, wie du dir eine kleine Webseite erstellst und über einen ESP8266 die RGB LED Matrix steuerst.
Für dieses kleine Projekt benötigst du:
- 1x ESP8622 (zbsp. Wemos D1 Mini),
- 2x Breadboardkabel, männlich – männlich, 20cm.
- 1x min. 170 Pin Breradboard
Webseite
Die Webseite enthält ein Eingabefeld für die IP-Adresse des ESP sowie 2 Schaltflächen (zum Zurücksetzen und Absenden). Des Weiteren sind natürlich die einzelnen “Pixel” auf der Seite vorhanden.
Für jeden der 40 Pixel wurde jeweils ein ColorPicker eingerichtet.
Wenn der Benutzer auf einem Pixel klickt, so wird ein Dialog geöffnet und es kann eine Farbe gewählt werden.
Beim Absenden der Seite werden alle Pixel ausgewertet und der HEX Wert der Farbe in ein RGB Wert umgerechnet.
ESP866 – Programm
Der ESP dient dazu, die Daten der Seite zu empfangen und auszuwerten.
Zunächst muss eine Verbindung zum lokalen Wi-Fi Netzwerk hergestellt werden.
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> const char* ssid = ""; //SSID aus dem Router const char* password = ""; //Passwort für den Zugang zum WLAN ESP8266WebServer server(80); //Port auf welchem der Server laufen soll. String pixels[40]; void setup() { delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde. Serial.begin(9600); WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung. while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde. delay(500); } server.on("/sk6812", callHandleSK6812Shield); server.begin(); // Starten des Servers. }
In der loop Funktion wird nur ausgeführt das der Server die anfragen vom Client behandelt.
void loop() { server.handleClient(); }
Die eigentliche Arbeit erledigt die Funktion “callHandleSK6812Shield”.
Hier wird zunächst über die Parameter der Adresse iteriert und die Daten in einem Array abgelegt.
Als Parameter können die einzelnen Pixelfarben oder auch einfach der Befehl “reset” empfangen werden. Wenn also ein Parameter “reset” empfangen wird, dann wird eine interne Variable auf true gesetzt und die Schleife abgebrochen, ansonsten wird das Array mit den Farben befüllt. Am Ende der Funktion wird nun geprüft, ob ein “reset” durchgeführt werden soll oder aber die Pixelfarben gesendet werden sollen. Im Fall eines “reset” wird nur der Befehl “reset” über die serielle Schnittstelle gesendet.
void callHandleSK6812Shield() { boolean doReset = false; for (int i = 0; i < server.args(); i++) { String parameterName = server.argName(i); String parameterValue = server.arg(i); //Wenn der Parametername gleich "text" ist dann... if (parameterName == "reset") { doReset = true; break; } if (parameterName != "test") { pixels[i - 1] = parameterValue; } } sendResult(); if (doReset) { Serial.println("reset"); } else { sendSerialCommands(); } }
Sollten jedoch die Pixelfarben gesendet werden, so wird das Array mit dem Pixel durchlaufen und über die serielle Schnittstelle gesendet. Es werden jedoch nur die farbigen Pixel gesendet!
void sendSerialCommands() { for (int i = 0; i < 40; i++) { if (pixels[i] != "000000000") { String line = ""; if (i < 10) { line += "0"; } line += String(i); line += "-"; line += pixels[i]; Serial.println(line); } } }
Arduino – Programm
Der Arduino UNO (in meinem Fall ein Arduino UNO von der gleichen Firma Keyestudio) empfängt die Daten per serieller Schnittstelle vom ESP und wertet diese wiederum aus.
Ich habe zusätzlich die Bibliothek “SoftwareSerial” verwendet, um auch debug Ausgaben auf der eigentlichen seriellen Schnittstelle durchführen zu können.
#include <SoftwareSerial.h> SoftwareSerial serial(2, 3); // RX | TX
Für das ansteuern der Pixel verwende ich wie auch im ersten Beispiel die Bibliothek von Adafruit.
#include <Adafruit_NeoPixel.h> //Pin zum steuern des Moduls ist am digitalen Pin D13 angeschlossen #define PIN 13 const int MAX_PIXEL = 40; //das Modul verfügt über insgesamt 40 LEDs vom Typ 5050 Adafruit_NeoPixel strip = Adafruit_NeoPixel(MAX_PIXEL, PIN, NEO_GRB + NEO_KHZ800);
Zusätzlich benötigen wir als Global Konstante den Wert für die Farbe Schwarz.
//Wenn alle Farben auf 0 sind dann ist die LED aus const uint32_t COLOR_NONE = strip.Color(0, 0, 0);
In der Funktion “setup” werden die beiden seriellen Schnittstellen mit der Geschwindigkeit von 9600baud eingerichtet / gestartet sowie die Kommunikation mit dem RGB LED Shield gestartet.
Damit ich später ein Video erzeugen kann dimme ich die LEDs mit der Funktion “setBrightness” auf den Wert 15.
void setup() { Serial.begin(9600); serial.begin(9600); //begin der kommunikation mit dem Modul strip.begin(); strip.setBrightness(15); strip.show(); }
Die Funktion “loop” dient nun dazu die vom ESP gesendeten Daten zu empfangen und zu verarbeiten.
Zunächst wird geprüft ob Daten empfangen werden können, wenn ja dann werden die im gesamten geladen und in der Variable “dataLine” gespeichert.
void loop() { if (serial.available() > 0) { dataLine = serial.readString(); dataLine.trim();
Wenn die Anzahl der Zeichen in der Datenzeile größer als 0 ist, dann werden alle nicht sichtbaren Steuerzeichen (\r & \n) aus den empfangenen Daten entfernt.
if (dataLine.length() > 0 ) { dataLine.replace("\r",""); dataLine.replace("\n","");
Als Nächstes wird nun geprüft, ob der Befehl “reset” empfangen wurde. Wenn dieses so ist, dann werden alle Pixel auf die Farbe Schwarz gesetzt und die Funktion loop verlassen.
if(dataLine == "reset"){ resetPixel(); return; }
void resetPixel(){ for(int i=0;i<40;i++){ strip.setPixelColor(i, COLOR_NONE); } strip.show(); }
Wenn nicht der Befehl “reset” empfangen wurde, dann werden die Zeilen geparst.
Eine korrekte Datenzeile enthält einen zweistelligen Index, gefolgt von einem Bindestrich und den RGB Farbwert.
00-255000128
int from = 0; int to = 12; for (int i = 0; i < dataLine.length() / 12; i++) { String line = dataLine.substring(from, (to+(i*12))); from = from + 12; int pixelIndex = line.substring(0, 2).toInt(); String rgbValue = line.substring(3); int red = rgbValue.substring(0, 3).toInt(); int green = rgbValue.substring(3, 6).toInt(); int blue = rgbValue.substring(6,10).toInt(); pixel(pixelIndex, red, green, blue); }
void pixel(int pixel, int red, int green, int blue) { strip.setPixelColor(pixel, strip.Color(red, green, blue)); strip.show(); }