ESP8266 code nach re-flash funktioniert nicht mehr richtig

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

Da solltest du mit den Versionen (IDE und ESP-core) nochmals kompilieren und flashen, mit der du die Erstinstallation vorgenommen hast.

@svag1895

gib mal das generierte HTML in einen Validator und überprüfe ob es formale Fehler gibt:

(ab und zu Zeilenschaltungen im HTML würden die Lesbarkeit erhöhen ...)

und nicht nur die Hauptseite sondern alle Endpoints/URI die du mit JavaScript aufrufst.

Außerdem braucht man am ESP8266 keine externe NTP Library. Das kommt schon mit dem Core mit:
NTP for the ESP8266 including day light saving time (DST) without 3rd party library

Es hört sich tatsächlich so an, als ob Ihnen der Speicher ausgeht, was etwas seltsam ist, wenn man bedenkt, dass es vorher ordnungsgemäß funktioniert hat. Dennoch empfehle ich Ihnen, das F()-Makro für alle String-Literale zu verwenden.

html += F("<div class='container'>");

Für alle diese Zeilen, wodurch vermieden wird, dass sie vor Beginn der Skizze in den RAM verschoben werden müssen.

Wenn der Speicher sehr knapp werden kann, sollten Sie erwägen, große Seiten als „Chunked-Content“ zu senden, wodurch der Bedarf an einem großen Puffer verringert wird.

Die andere Sache ist natürlich, dass es einen Fehler im HTML gibt, etwa ein fehlendes schließendes </p> irgendwo oder etwas anderes, das Sie vergessen haben zu schließen.
Der beste Weg, dies zu finden, besteht darin, die Entwicklertools in Ihrem Browser zu verwenden (ich verwende Chrome und dann Einstellungen -> Weitere Tools -> Entwicklertools).


So können Sie sehen, was tatsächlich vom Browser empfangen wurde und ob offensichtlich etwas fehlt. Sollten Teile fehlen, die laut Skizze übertragen werden sollen, liegt die Ursache höchstwahrscheinlich an fehlendem Speicher.

n.b. Ich habe Google Translate verwendet, um diese Antwort zu kompilieren. Es bereitet mir zusätzliche Mühe, dies zu tun.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.