Ich habe mit einer 8x8 Matrix mit ws2812b gespielt.
Es wird eine Server erstellt auf dem man 8 Tasten hat zum anzeigen von Animationen (Smiley/Rainbow) oder Steuerung von Hue/Brightness/LED-Off. Unten ist zusätzlich noch ein 8x8 Pattern für custom Muster.
Nun hat ein Freund Probleme mit seinem Board, um zu helfen habe ich kurz mein ESP mit seinem code geflasht, um zu schauen, ob die Probleme bei mir auch auftreten. Anschließend habe ich meinen alten Code für die LED-Animationen wieder auf mein Board geflasht und es stellte sich heraus, dass der Webserver nicht mehr richtig angezeigt wird. Es werden manchmal 3 manchmal 4 Tasten angezeigt, der Rest fehlt. Ich habe die Reihenfolge und die Anordnung der Tasten geändert, Problem besteht weiter.
Nun habe ich einen weiteren ESP8266 geflasht, dieser hat gleiche Probleme. Es stellte sich erstmal heraus, dass die FastLED.h erneuert wurde und Probleme beim Flashen verursachte, daher habe ich diese downgegraded. Es kamen ebenfalls neue Versionen von dem ESP8266 Manager Board, ich habe mehrere Versionen durchprobiert, Problem besteht weiterhin. Hat jemand einen Tipp, wie ich das Problem beheben kann?
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <FastLED.h>
#include <ArduinoOTA.h>
//// WiFi settings
// Station-Modus:
const char* ssid = "XXX";
const char* password = "XXX";
// AP-Modus Einstellungen:
const char* ap_ssid = "ESP_AP";
const char* ap_password = "12345";
#define LED_PIN 5 // 5 = D1 Pin für Datenleitung
#define NUM_LEDS 64 // Anzahl der LEDs (8x8)
#define DEFAULT_BRIGHTNESS 3 // Standardhelligkeit
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
// Define name of the board
#define ESPHostname "ESP_im_Netz"
ESP8266WebServer server(80); // Webserver auf Port 80
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200); // GMT+1 Zeitzone
CRGB leds[NUM_LEDS];
uint8_t currentAnimation = 1; // 0 = Aus, 1 = Smiley, 2 = Rainbow-Glitter, 3 = Benutzerdefiniertes Muster
unsigned long lastHueChange = 0;
int hueChangeDelay = 10;
uint8_t hue = 1;
int brightness = DEFAULT_BRIGHTNESS; // Variable Helligkeit
// **Hier wird customPattern global deklariert**
uint8_t customPattern[8][8]; // Array für benutzerdefiniertes Muster
// Smiley-Muster für 8x8 Matrix (1 = leuchtende LED, 0 = aus)
byte smiley[8] = {
B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100
};
byte arrowRight[8] = {
0b00001000,
0b00000100,
0b00000010,
0b11111111,
0b11111111,
0b00000010,
0b00000100,
0b00001000
};
// Umwandlung (x, y) Koordinate in LED-Index für die Matrix
int xyToIndex(int x, int y) {
return (y * 8) + x;
}
// Funktion zum Zeichnen des Smileys
void drawSmiley() {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
if (bitRead(smiley[y], 7 - x) == 1) {
leds[xyToIndex(x, y)] = CHSV(hue, 255, 255);
} else {
leds[xyToIndex(x, y)] = CRGB::Black;
}
}
}
}
// void drawArrowRight(){
// for (int y = 0; y < 8; y++) {
// for (int x = 0; x < 8; x++) {
// if (bitRead(arrowRight[y],7-x) == 1) {
// leds[xyToIndex(x,y)] = CHSV(hue, 255,255);
// } else {
// leds[xyToIndex(x, y)] = CRGB::Black;
// }
// }
// }
//}
// Funktion zum Zeichnen benutzerdefinierter Muster
void drawCustomPattern(uint8_t pattern[8][8]) {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
if (pattern[y][x] == 1) {
leds[xyToIndex(x, y)] = CHSV(hue, 255, 255); // Benutzerdefinierte Farbe (HSV)
} else {
leds[xyToIndex(x, y)] = CRGB::Black;
}
}
}
FastLED.show();
}
// Clear benutzerdefinierter Muster
void clearCustomPattern() {
// Setze das customPattern Array auf 0 (alle LEDs aus)
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
customPattern[y][x] = 0;
}
}
drawCustomPattern(customPattern); // Zeichne das leere Muster
server.send(200, "text/plain", "Custom Pattern Cleared");
}
// Rainbow-Glitter Animation
void rainbowWithGlitter() {
fill_rainbow(leds, NUM_LEDS, hue, 7);
if (random8() < 80) {
leds[random16(NUM_LEDS)] += CRGB::White;
}
hue++;
}
// Helligkeit erhöhen
void increaseBrightness() {
brightness = min(brightness + 3, 70); // Maximalwert 255
FastLED.setBrightness(brightness);
FastLED.show();
}
// Helligkeit verringern
void decreaseBrightness() {
brightness = max(brightness - 3, 0); // Minimalwert 0
FastLED.setBrightness(brightness);
FastLED.show();
}
// Restart-Funktion (mit Reload der Webseite)
void restartHomePage() {
server.send(200, "text/html", "<html><body><script>setTimeout(function(){ location.reload(); }, 500);</script></body></html>");
}
// HTTP-Handler für benutzerdefinierte Muster
void handleCustomPattern() {
String patternString = server.arg("pattern");
// Konvertiere den String in ein 8x8-Muster
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
customPattern[y][x] = patternString.charAt((y * 8) + x) == '1' ? 1 : 0;
}
}
// Setze Animation auf benutzerdefiniertes Muster
currentAnimation = 3;
drawCustomPattern(customPattern);
server.send(200, "text/plain", "Custom Pattern Set");
}
// HTTP-Handler für den Hue-Slider
void handleSetHue() {
if (server.hasArg("hue")) {
hue = server.arg("hue").toInt(); // Aktualisiere den Hue-Wert
FastLED.show(); // Aktualisiere LEDs mit neuer Farbe
server.send(200, "text/plain", "Hue updated");
} else {
server.send(400, "text/plain", "No Hue value received");
}
}
// Funktion, die die aktuelle Zeit zurückgibt
void handleGetTime() {
String time = timeClient.getFormattedTime(); // Zeit im Format "HH:MM:SS"
server.send(200, "text/plain", time);
}
// Handler to get the current brightness value
void handleGetBrightness() {
String brightnessString = String(brightness); // Assuming 'brightness' is the global variable for LED brightness
server.send(200, "text/plain", brightnessString);
}
// Hue um 5 erhöhen
void handleHueUp() {
hue = (hue + 10) % 256; // Farbhue um 5 erhöhen (bei 256 zurücksetzen)
FastLED.show();
server.send(200, "text/plain", "Hue increased by 5");
}
// Hue um 5 verringern
void handleHueDown() {
hue = (hue - 10 + 256) % 256; // Farbhue um 5 verringern (bei unter 0 auf 255 setzen)
FastLED.show();
server.send(200, "text/plain", "Hue decreased by 5");
}
// Funktion zur Verbindung mit WLAN oder Wechsel zum AP-Modus
void connectToWiFi() {
WiFi.begin(ssid, password);
int attempt = 0;
while (WiFi.status() != WL_CONNECTED && attempt < 20) { // 20 Versuche
delay(500);
Serial.print(".");
attempt++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected");
Serial.print("Station IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nUnable to connect to WiFi. Starting AP mode...");
startAPMode(); // AP-Modus aktivieren
}
}
// Funktion zum Aktivieren des AP-Modus
void startAPMode() {
WiFi.softAP(ap_ssid, ap_password);
Serial.println("AP Mode started");
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
}
// //// Andere Möglichkeite, wenn kein Wifi.station, dann Wifi.AP
// void connectToWiFi() {
// WiFi.begin(ssid, password);
// int attempt = 0; // Zähler für Verbindungsversuche
// // Versuche bis zu 20 Mal eine Verbindung herzustellen
// while (WiFi.status() != WL_CONNECTED && attempt < 20) {
// delay(500);
// Serial.print(".");
// attempt++;
// }
// // Wenn nach 20 Versuchen keine Verbindung hergestellt wurde, AP-Modus aktivieren
// if (WiFi.status() != WL_CONNECTED) {
// Serial.println("\nWiFi-Verbindung fehlgeschlagen. Starte AP-Modus...");
// // Access Point Modus aktivieren
// WiFi.mode(WIFI_AP);
// WiFi.softAP(ap_ssid, ap_password);
// Serial.println("AP-Modus aktiviert.");
// Serial.print("Verbinde dich mit dem Netzwerk: ");
// Serial.println(ap_ssid);
// Serial.print("IP-Adresse des Access Points: ");
// Serial.println(WiFi.softAPIP());
// } else {
// Serial.println("\nWiFi connected");
// Serial.print("Station IP address: ");
// Serial.println(WiFi.localIP());
// }
// }
////// Setup-Funktion ////// Setup-Funktion ////// Setup-Funktion ////// Setup-Funktion ////// Setup-Funktion ////
void setup() {
Serial.begin(115200);
delay(50);
// Wifi Anschluss. Wenn kein Internet, dann lokaler Access Point.
connectToWiFi(); // Versuch, sich mit WiFi zu verbinden
// Setup FastLED
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(brightness);
// NTP Zeit starten
timeClient.begin();
// OTA Setup
ArduinoOTA.setHostname(ESPHostname);
ArduinoOTA.begin();
// Webserver initialisieren
server.on("/", handleRoot);
server.on("/smiley", handleSmiley);
server.on("/rainbow", handleRainbowGlitter);
server.on("/off", handleOff);
server.on("/brightness_up", handleBrightnessUp);
server.on("/brightness_down", handleBrightnessDown);
server.on("/restart", restartHomePage);
server.on("/setPattern", handleCustomPattern); // Neuer Endpunkt für benutzerdefinierte Muster
server.on("/clearPattern", clearCustomPattern); // Neuer Endpunkt zum Leeren des Musters
server.on("/getTime", handleGetTime); // Endpunkt für Echtzeit-Zeitabfrage
server.on("/getBrightness", handleGetBrightness); // Add this handler
server.on("/hue_up", handleHueUp); // Hue um 5 erhöhen
server.on("/hue_down", handleHueDown); // Hue um 5 verringern
server.begin();
Serial.println("HTTP server started");
}
// Root-Seite der Webseite
void handleRoot() {
String html = "<html><head><meta charset='utf-8'><title> 192.168.1.102 </title>"; // Tab Name
html += "<style>";
html += "body { font-family: Arial; display: flex; justify-content: center; align-items: center; height: 50vh; margin: 0; }";
html += "h1 { font-size: 2em; text-align: center; }";
// Style für die Buttons
html += "button { font-size: 1em; padding: 10px; margin: 10px; width: 150px; }";
// Container für das zentrale Layout
html += ".container { text-align: center; }";
// Flexbox für die Anordnung der Buttons nebeneinander
html += ".button-row { display: flex; justify-content: center; margin: 10px 0; }";
html += ".button-row button { flex: 1; max-width: 200px; }"; // Buttons sollen max 200px breit sein
html += "</style>";
html += "<script>function sendRequest(url) { var xhttp = new XMLHttpRequest(); xhttp.open('GET', url, true); xhttp.send(); }</script>";
html += "</head><body>";
html += "<div class='container'>";
html += "<h1>ESP8266 LED Control</h1>";
// Smiley und Rainbow nebeneinander
html += "<div class='button-row'>";
html += "<button onclick=\"sendRequest('/smiley')\">Smiley</button>";
html += "<button onclick=\"sendRequest('/rainbow')\">Rainbow Glitter</button>";
html += "</div>";
// Brightness +3 und Brightness -3 nebeneinander
html += "<h5>Adjust Brightness</h5>";
html += "<div class='button-row'>";
html += "<button onclick=\"sendRequest('/brightness_down')\">Brightness -3</button>";
html += "<button onclick=\"sendRequest('/brightness_up')\">Brightness +3</button>";
html += "</div>";
// HUE +10 or -10 Änderung
html += "<h5>Adjust Hue</h5>";
html += "<div class='button-row'>";
html += "<button onclick=\"sendRequest('/hue_down')\">Hue -10 </button>";
html += "<button onclick=\"sendRequest('/hue_up')\">Hue +10 </button>";
html += "</div>";
// OFF-Taste zentriert
html += "<div class='button-row'>";
html += "<button onclick=\"sendRequest('/off')\">Off</button>";
html += "</div>";
// Anzeige Zeit und Helligkeit
html += "<p style='font-size: 2em;'>Current brightness: " + String(brightness) + "</p>";
html += "<p style='font-size: 2em;'>Current time: " + timeClient.getFormattedTime() + "</p>";
// Echtzeit Helligkeitsanzeige hinzufügen
// Add JavaScript to handle brightness updates
// html += "<p style='font-size: 1em;'> Current brightness: <span id='brightnessDisplay'></span></p>";
html += "<script>";
html += "function sendRequest(url) { var xhttp = new XMLHttpRequest(); xhttp.open('GET', url, true); xhttp.send(); }";
html += "function updateBrightness() {";
html += " var xhttp = new XMLHttpRequest();";
html += " xhttp.onreadystatechange = function() {";
html += " if (this.readyState == 4 && this.status == 200) {";
html += " document.getElementById('brightness').innerHTML = this.responseText;";
html += " }";
html += " };";
html += " xhttp.open('GET', '/getBrightness', true);";
html += " xhttp.send();";
html += "}";
html += "setInterval(updateBrightness, 1000);";
html += "</script>";
// Echtzeit Zeit-Anzeige hinzufügen
html += "<p style='font-size: 1em;'> Current time: <span id='timeDisplay'></span></p>";
html += "<script>";
html += "function updateTime() {";
html += " var xhttp = new XMLHttpRequest();";
html += " xhttp.onreadystatechange = function() {";
html += " if (this.readyState == 4 && this.status == 200) {";
html += " document.getElementById('timeDisplay').innerHTML = this.responseText;";
html += " }";
html += " };";
html += " xhttp.open('GET', '/getTime', true);";
html += " xhttp.send();";
html += "}";
html += "setInterval(updateTime, 1000);"; // Aktualisiere jede Sekunde
html += "</script>";
// LED Grid Pattern
html += "<h2>Custom LED Pattern</h2>";
html += "<table id='ledGrid' border='1' style='margin: auto;'>"; //auto
for (int y = 0; y < 8; y++) {
html += "<tr>";
for (int x = 0; x < 8; x++) {
html += "<td style='width:20px;height:20px;background-color:black' onclick='toggleLED(this, " + String(x) + ", " + String(y) + ")'></td>";
}
html += "</tr>";
}
html += "</table>";
// Tasten Pattern Send/Clear
html += "<div class='button-row'>";
html += "<br><button onclick=\"sendRequest('/clearPattern')\">Clear Pattern</button>";
html += "<br><button onclick='sendPattern()'>Send Pattern</button>";
html += "</div>";
// JavaScript für Pattern senden
html += "<script>";
html += "var ledPattern = Array(8).fill().map(() => Array(8).fill(0));";
html += "function toggleLED(cell, x, y) {";
html += " ledPattern[y][x] = 1 - ledPattern[y][x];";
html += " cell.style.backgroundColor = ledPattern[y][x] ? 'green' : 'black';";
html += "}";
html += "function sendPattern() {";
html += " let patternString = '';";
html += " for (let y = 0; y < 8; y++) {";
html += " for (let x = 0; x < 8; x++) {";
html += " patternString += ledPattern[y][x];";
html += " }";
html += " }";
html += " let xhttp = new XMLHttpRequest();";
html += " xhttp.open('GET', '/setPattern?pattern=' + patternString, true);";
html += " xhttp.send();";
html += "}";
html += "</script>";
html += "</body></html>";
server.send(200, "text/html", html);
}
// Smiley anzeigen
void handleSmiley() {
currentAnimation = 1;
server.send(200, "text/plain", "Smiley Animation");
}
// Rainbow-Glitter Animation aktivieren
void handleRainbowGlitter() {
currentAnimation = 2;
server.send(200, "text/plain", "Rainbow Glitter Animation");
}
// LEDs ausschalten
void handleOff() {
currentAnimation = 0;
FastLED.clear();
FastLED.show();
server.send(200, "text/plain", "LEDs are Off");
}
// Helligkeit erhöhen
void handleBrightnessUp() {
increaseBrightness();
server.send(200, "text/plain", "Brightness increased");
}
// Helligkeit verringern
void handleBrightnessDown() {
decreaseBrightness();
server.send(200, "text/plain", "Brightness decreased");
}
// Hauptprogramm-Schleife
void loop() {
server.handleClient();
ArduinoOTA.handle();
timeClient.update(); // Aktualisiere NTP Zeit
// Keine automatische Farbänderung, weil der Hue-Wert jetzt über den Slider gesteuert wird
// if (millis() - lastHueChange > hueChangeDelay) {
// hue++; // Farbton langsam ändern
// lastHueChange = millis(); // Zeit für nächste Änderung merken
// }
switch (currentAnimation) {
case 1:
drawSmiley(); // Zeigt Smiley an
break;
case 2:
rainbowWithGlitter(); // Zeigt Rainbow-Glitter-Animation an
break;
case 3:
drawCustomPattern(customPattern); // Zeige benutzerdefiniertes Muster
break;
case 0:
FastLED.clear();
break;
}
FastLED.show(); // Aktualisiert die LED-Anzeige in Echtzeit
delay(100);
}
Ich verwende die Node MCU Variante des ESP8266

