Page im Browser per Taster anzeigen

Hallo zusammen,
ich habe bei meinem WomoMonitor 2.0 noch folgende herausforderung:
Ich habe ein TFT das mit 5 Tastern gesteuert wird. Das funktioniert auch einwandfrei. Zusätzlich gibt es ein WebInterface. Wenn ich im Browser eine Seite wechsle, wird die auch automatisch auf dem Screen gewechselt. Umgekehrt sollte das aber auch gemacht werden. Also wenn ich am Monitor mit einer Taste einen Screen weitergehe, sollte das im Browser nachgeladen werden.
warum poste ich das hier? Der andere Thread hat 500 Posts, da wird jemand, der da nicht mitgelesen hat, keine Lust haben alles durchzulesen. Hier mal der komplette Sketch, und der Server.

//#######################################################################
//# Wohnmobil-Monitor 2.0 by Roland Kälin
//#
//# Dieses System ist ausgelegt für eine Auflösung von 480x320
//# Benutzt wird ein 3.5" Touch-Display mit einem ILI9486 Treiber
//# Bekannte Bugs:
//#
//#
//# Fehlende Funktionen
//# 1. GPS tracking auf SD-Karte
//# 2. Setting Screen
//# 3. Screen Ausschalten (wird bei diesem evtl nicht gehen)
//#######################################################################

#include <WebServer.h>
#include <WiFi.h>
#include <ArduinoOTA.h>
#include <LittleFS.h>
#include <TinyGPSPlus.h>  //Bibliothek für GPA Modul einbinden
#include <TFT_eSPI.h> //Bibliothek für Bildschirm einbinden
#include <Adafruit_MPU6050.h>  //Bibliothek für Gyroskop einbinden
#include <Preferences.h> //Bibliothek für EEProm einbinden
#include <Wire.h>  //Bibliothek für Wire einbinden
#include "icons.h" //Rimor Logo einbinden
#include <DHT22.h> //Bibliothek für Temperatursensor einbinden
#include <SPI.h> //ibliothek für SPI einbinden
#include "gaugesprites.h"
#include "level.h"
#include "gps.h"

/* Nur für mich zur Gedankenstütze
  boolean        1 Byte (!)          true | false

  byte           1                   0 ... 255
  uint8_t        1                   0 ... 255

  char           1                   -128 ... 127
  int8_t         1                   -128 ... 127

  int            2                   -32768 ... 32767
  int16_t        2                   -32768 ... 32767

  unsigned int   2                   0 ... 65535
  uint16_T       2                   0 ... 65535

  long           4                   -2,147 Mrd. ... 2,147 Mrd.
  int32_t        4                   -2,147 Mrd. ... 2,147 Mrd.

  unsigned long  4                   0 ... 4'294'967'295
  uint32_t       4                   0 ... 4'294'967'295

  float          4                   -3.4028235E+38 ... 3.4028235E+38
  double         4                   -3.4028235E+38 ... 3.4028235E+38

  String         1 pro char +1 ges.  Kette von chars
*/


//Schriften definieren
#include "Ubuntu24.h"
#include "Ubuntu72.h"

//Programmversion
String Version = "2.0.20240914.1728";
//Pins definieren
constexpr uint8_t tasterPin{ 34 };
constexpr uint8_t dhtPin{ 23 };

//Baudrate für GPS
constexpr uint32_t GPSBaud{ 9600 };

//Buttons
constexpr uint16_t BUTTONW {150}; //Buttonbreite
constexpr uint16_t BUTTONH {30}; //Buttonhöhe
constexpr uint16_t BUTTONX {165}; //Pos erster Button
constexpr uint16_t BUTTONY {40}; //Pos erster Button
constexpr uint16_t BUTTONS {40}; //Abstand zwischen Buttons
constexpr uint16_t BUTTONR {8}; //Radius

//GPS definieren
TinyGPSPlus gps;

//Heimkoordinaten
constexpr double HOME_LAT = 47.3004913, HOME_LON = 9.1635170;
int16_t muM = 0, muM_alt = -1, fSpeed = 0, fSpeed_alt = -1, sat = 0, sat_alt = -1;
float longi, lati, longi_alt_lati_alt;
uint32_t distHome = 0, disthome_alt = -1, gpsDelay;
String heading = "", heading_alt = " ", courseHome = "", courseHome_alt = " ";


//Temperatursensor definieren
DHT22 dht22(dhtPin);
int8_t hum_alt, temp_alt;
int8_t temperature{ 0 }, humidity{ 0 };

//Display definieren
TFT_eSPI tft = TFT_eSPI();  // Invoke custom library
TFT_eSprite img = TFT_eSprite(&tft);  // Sprite class
TFT_eSprite backgroundS = TFT_eSprite(&tft);

//Farben
#define RGB565(r, g, b)    ((((r)& 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))
constexpr uint16_t farben[] { TFT_RED, TFT_BLUE, TFT_GREEN, TFT_DARKGREEN, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW, TFT_LIGHTGREY, TFT_WHITE }; // textFarbe gibt dann direkt die Farbe, da muss ich adnn aber wissen welche nummer welche Fa

uint16_t colorRed, colorGreen, colorBlue, colorRed_alt, colorGreen_alt, colorBlue_alt;
uint16_t hintergrundFarbe = RGB565(0, 0, 0), textFarbe = RGB565(0, 255, 0);
byte yFarbe = 1;
String hintergrundFarbeW, tempColor;

//Displayausrichtung
constexpr byte rotar{ 1 };  //Display Rotation

//Gyroskop definieren
Adafruit_MPU6050 mpu;

//Screens definieren
enum pageId {
  MENU,
  TEMP,
  LEVEL,
  GPSm,
  FARBEN,
  INFO,
  NEUSTART,
  SYSTEM,
  SPLASH,
};
int8_t currentPage = SPLASH, oldPage = -1, aktPage = -1;
constexpr int8_t MAX_SCREENS{8};
String systemMessageW = "";
String systemMessageS = "";
uint8_t buttonActive = 1;
enum menuId {
  HOMEM,
  WETTERM,
  NIVELM,
  GPSMM,
  COLORM,
  INFOM,
  NEUSTARTM,
  SYSTEMM,
  OKM
};
constexpr uint8_t MAX_MENU{7};
int8_t buttonPosY = WETTERM, oldbuttonPosY = -1;
String oldText = "WETTER";
//Einstellungen zum Nivelieren
constexpr float KORREX = {0.15};
float x = 0, y = 0, x_alt = KORREX + 0.1, y_alt = KORREX + 0.1, x_corr, y_corr;

constexpr byte multix = 70, multiy = 35;  //multiplikator für Anzeige
unsigned long startnivel;          //Verzögerungsfunktion beim nivelieren, damit es nicht so flackert
constexpr long NIVEL = {200};

//Buttons auswerten
const bool pressed = true;
const bool notPressed = !pressed;
constexpr uint32_t debounceTime{ 50 };
bool lastButtonState = notPressed;
unsigned long debounceStart;

//Namen zuweisen
enum buttonId {
  LEER,
  DOWN,
  RIGHT,
  UP,
  LEFT,
  OK_PRESSED
};
byte button = LEER;
int buttonPressed = LEER, buttonValue = 0;

//Systemreset
//void (*resetFunc)(void) = 0;  //declare reset function at address 0

//Speicher definieren
Preferences speicher;

//Netzwerk
String ssids;
String passwords;
WebServer server(80);

//##############################################
//#Setup
//##############################################
void setup(void) {
  Serial.begin(115200);
  delay(500);
  Serial.println(F("Setup"));
  setupFS();
  Serial.println(F("Filesystem enthält:"));
  listDir(LittleFS, "/", 3); // Lists the files in filesystem

  //Bildschirm starten
  tft.init();
  tft.setRotation(rotar);  //0-Vertikal 1-Horizontal 2-Vertikal umgekehrt 3-Horizontal umgekehrt
  Serial.println(F("Bildschirm gestartet"));
  systemMessageS += "  - Bildschirm gestartet\n";
  systemMessageW += "Bildschirm gestartet<BR>";
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BC_DATUM, 240, 27, Ubuntu24, "Setup", TFT_WHITE, TFT_BLACK);
  tft.setSwapBytes(true);
  drawBmp("/Startbild.bmp", 0, 40);
  img.createSprite(22, 22);
  backgroundS.createSprite(200, 200);
  backgroundS.setSwapBytes(true);

  //Serial2 für GPS beginnen
  //RX --> 28
  //TX --> 29
  Serial2.begin(GPSBaud);
  Serial.println(F("Serial für GPS gestartet"));
  systemMessageS += "  -  GPS gestartet\n";
  systemMessageW += "GPS gestartet<BR>";
  readGPS();
  delay(1000);
  readGPS();
  if (sat == 0)
  {
    systemMessageS += "  - Keine Sateliten oder\n";
    systemMessageS += "     GPS nicht verbunden\n";
    systemMessageW += "Keine Sateliten oder GPS nicht verbunden<BR>";
  }

  //Speicher starten und Daten laden
  speicher.begin("credentials", false);
  readMemory();
  if (ssids == "" || passwords == "") {
    Serial.println(F("Keine Daten gefunden"));
  }
  else
  {
    Serial.println(F("Daten geladen"));
    Serial.print(F("ssid: ")); Serial.println(ssids);
    Serial.print(F("passwort: ")); Serial.println(passwords);
    Serial.print(F("Farbe: ")); Serial.println(textFarbe);
    systemMessageS += "  - Daten aus Speicher eingelesen\n";
    systemMessageW += "Daten aus Speicher eingelesen<BR>";

  }


  // Gyroskop starten
  if (!mpu.begin()) {
    Serial.println(F("Gyroskop nicht gefunden"));
    systemMessageS += "  - Gyroskop nicht gefunden\n";
    systemMessageW += "Gyroskop nicht gefunden<BR>";

    {}
  }
  else
  {
    Serial.println(F("Gyroskop gestartet"));
    systemMessageS += "  - Gyroskop gestartet\n";
    systemMessageW += "Gyroskop gestartet<BR>";

  }
  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
  mpu.setGyroRange(MPU6050_RANGE_1000_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  readMPU();
  x_corr = x * -1;
  y_corr = y * -1;
  Serial.print(F("X: ")); Serial.println(x);
  Serial.print(F("Y: ")); Serial.println(y);
  Serial.print(F("X_corr: ")); Serial.println(x_corr);
  Serial.print(F("Y_corr: ")); Serial.println(y_corr);

  x = x + x_corr;
  y = y + y_corr;

  Serial.print(F("X: ")); Serial.println(x);
  Serial.print(F("Y: ")); Serial.println(y);


  //Wire starten
  Wire.begin();
  Wire.setClock(400000L);
  Serial.println(F("Wire gestartet"));

  //Seite setzen die nach dem Setup angezeigt wird
  currentPage = MENU;
  Serial.println(F("Startseite gesetzt"));

  //Temperatursensor starten
  Serial.println(F("Umgebungsfühler gestartet"));
  systemMessageS += "  - Umgebungsfühler gestartet\n";
  systemMessageW += "Umgebungsfühler gestartet<BR>";
  dht22.getTemperature();
  dht22.getHumidity();



  //delay(2000);
  tft.fillScreen(TFT_WHITE);
  tft.loadFont("Clip72", LittleFS);
  tft.setTextDatum(CC_DATUM);
  tft.setTextColor(TFT_BLACK, TFT_WHITE);
  tft.drawString("A", 240, 160);
  showmsgXY(BC_DATUM, 240, 27, Ubuntu24, "Setup abgeschlossen", TFT_BLACK, TFT_WHITE);
  Serial.println(F("Setup abgeschlossen"));
  systemMessageS += "  - Setup abgeschlossen\n";
  systemMessageW += "Setup abgeschlossen<BR>";
  delay (1500);
  drawSplashScreen();
  Connect();
  ArduinoOTA.onStart([]() {
    //save();                       //Einkommentieren wenn Werte vor dem Update gesichert werden sollen
  });
  ArduinoOTA.begin();
  server.on("/", handleMenupage);              // send root page
  server.on("/0.htm", handleMenupage);               // the page can use the same handle
  server.on("/wetterPage.htm", handleWetterpage);              // another page, another handle
  server.on("/wasserPage.htm", handleWasserpage);
  server.on("/readLevel", handleLevel);
  server.on("/readWasserwaage", handleWasserwaage);// another page, another handle
  server.on("/levelPage.htm", handleLevelpage);
  server.on("/farbenPage.htm", handleFarbenpage);// another page, another handle
  server.on("/settingsPage.htm", handleSettingspage);              // another page, another handle
  server.on("/neustartPage.htm", handleNeustartpage);
  server.on("/systemPage.htm", handleSystempage);
  server.on("/gpsPage.htm", handleGPSpage);
  server.on("/readGPS", handleGPS);
  server.on("/neustartPage1.htm", handleNeustart);// another page, another handle
  server.on("/infoPage.htm", handleInfopage);              // another page, another handle
  server.on("/f.css", handleCss);                // a stylesheet
  server.on("/favicon.ico", handle204);          // not available, send 204
  server.onNotFound(handleNotFound);             // show a typical HTTP Error 404 page
  server.begin();
  Serial.println("HTTP Server gestartet\n\n");
}
//##############################################
//#Loop
//##############################################
void loop(void) {
  ArduinoOTA.handle();
  server.handleClient();

  checkButtons();
  switch (currentPage) {
    case SPLASH:
      if (currentPage != oldPage) {
        oldPage = currentPage;
        server.send(200, "text/html", "\"/\""); //Send web page
        drawSplashScreen();
      }
      break;

    case MENU: //Menu page
      if (currentPage != oldPage) {
        oldPage = currentPage;
        drawMenuScreen();
      }
      if (buttonPosY != oldbuttonPosY)
      {
        updateMenuM();
        oldbuttonPosY = buttonPosY;
      }

      if (button == OK_PRESSED)
      {
        currentPage = buttonPosY;
        buttonPosY = 1;
      }
      break;

    case TEMP:  //Temperature page
      if (currentPage != oldPage) {
        oldPage = currentPage;
        //  handleWetterpage();
        String message = "192.168.1.110/wetterPage.htm/";
        server.send(200, "text/html", message); //Send web page
        drawTempScreen(temperature, humidity);
      }
      getDHTData(temperature, humidity);
      updateTempScreen(temperature, humidity);

      break;

    case LEVEL:  //Nivelieren
      if (currentPage != oldPage) {
        Serial.println(F("Nivel"));
        oldPage = currentPage;
        // server.send(200, "text/html", "levelPage.htm"); //Send web page
        handleLevelpage();
        drawLevelScreen();
      }
      getLevel();
      break;

    case GPSm:  //Nivelieren
      if (currentPage != oldPage) {
        oldPage = currentPage;
        server.send(200, "text/html", "/gpsPage.htm"); //Send web page
        drawGPSScreen();
      }
      readGPS();
      updateGPSScreen();

      break;

    case FARBEN:  //textFarbearbe setzen
      if (currentPage != oldPage) {
        oldPage = currentPage;
        server.send(200, "text/html", "/colorPage.htm"); //Send web page
        drawColorScreen();
      }
      getFarben();
      break;

    case INFO:
      if (currentPage != oldPage) {
        oldPage = currentPage;
        server.send(200, "text/html", "infoPage.htm"); //Send web page
        drawInfoScreen();
      }


      break;

    case NEUSTART:  //System zurücksetzen
      if (currentPage != oldPage) {
        oldPage = currentPage;
        Serial.print(F("currentPage: "));
        Serial.println(currentPage);
        server.send(200, "text/html", "neustartPage.htm"); //Send web page
        drawResetScreen();

      }
      if (button == OK_PRESSED) {
        ESP.restart();
      }

      break;


    case SYSTEM:  //System zurücksetzen
      if (currentPage != oldPage) {
        oldPage = currentPage;
        server.send(200, "text/html", "systemPage.htm"); //Send web page
        drawSystemScreen();

      }

      break;
  }
}
/************************************************************************************
    Screens anzeigen
************************************************************************************/
void drawSplashScreen() {
  tft.fillScreen(hintergrundFarbe);
  tft.setRotation(rotar);
  tft.drawBitmap(tft.width() / 2 - 160, tft.height() / 2 - 65, rimor, 250, 65, textFarbe, hintergrundFarbe);
  tft.drawBitmap(tft.width() / 2, tft.height() / 2, sailer, 120, 60, textFarbe, hintergrundFarbe);
}

void drawMenuScreen() {
  buttonPosY = 1;
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);  //(100, 155, 203)
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Hauptmenu", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2), Ubuntu24, "Wetter", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS, Ubuntu24, "Level", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS * 2, Ubuntu24, "GPS", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS * 3, Ubuntu24, "Farben", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS * 4, Ubuntu24, "Info", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS * 5, Ubuntu24, "Neustart", textFarbe, hintergrundFarbe);
  showmsgXY(CC_DATUM, BUTTONX + BUTTONW / 2, (BUTTONY + BUTTONH / 2) + BUTTONS * 6, Ubuntu24, "System", textFarbe, hintergrundFarbe);
  updateMenuM();
}

void drawTempScreen(int8_t temp, int8_t hum) {
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);  //(100, 155, 203)
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Umgebungsdaten", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(TC_DATUM, 120, 44, Ubuntu24, "Temperatur", textFarbe, hintergrundFarbe);
  tft.drawFastVLine(240, 34, 286, textFarbe);
  showmsgXY(TC_DATUM, 360, 44, Ubuntu24, "Feuchtigkeit", textFarbe, hintergrundFarbe);
  showmsgXY(BR_DATUM, 120, 200, Ubuntu72, temp, 0, textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 130, 200, Ubuntu72, "°C", textFarbe, hintergrundFarbe);
  showmsgXY(BR_DATUM, 380, 200, Ubuntu72, hum, 0, textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 390, 200, Ubuntu72, "%", textFarbe, hintergrundFarbe);

}

void drawLevelScreen() {
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);
  backgroundS.pushImage(0, 0, 200, 200, gauge);
  img.pushImage(0, 0, 22, 22, libelle);
  img.pushToSprite(&backgroundS, x * multix + 89, y * multiy + 89, TFT_WHITE);  //Weiss wird transparent
  backgroundS.pushSprite(110, 85); // Plot sprite
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Nivelierung", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(ML_DATUM, 320, 185, Ubuntu24, "Vorne", textFarbe, hintergrundFarbe);
  showmsgXY(MR_DATUM, 100, 185, Ubuntu24, "Hinten", textFarbe, hintergrundFarbe);
  showmsgXY(BC_DATUM, 210, 75, Ubuntu24, "Links", textFarbe, hintergrundFarbe);
  showmsgXY(TC_DATUM, 210, 295, Ubuntu24, "Rechts", textFarbe, hintergrundFarbe);
}

void drawGPSScreen() {
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "GPS", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(BC_DATUM, 120, 70, Ubuntu24, "Richtung", textFarbe, hintergrundFarbe);
  showmsgXY(BC_DATUM, 360, 70, Ubuntu24, "Geschwindigkeit", textFarbe, hintergrundFarbe);
  showmsgXY(BC_DATUM, 120, 180, Ubuntu24, "Höhe über Meer", textFarbe, hintergrundFarbe);
  showmsgXY(BC_DATUM, 360, 180, Ubuntu24, "Anzahl Sateliten", textFarbe, hintergrundFarbe);
}


void drawColorScreen() {
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Farben Auswahl", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  // colorNumber = speicher.getInt("farbe");
  yFarbe = 4;
  for (int i = 20; i < 255; i++)
  {
    tft.fillRect(i + 20, 50, 1, 40, RGB565(i, 0, 0));
  }
  for (int i = 20; i < 255; i++)
  {
    tft.fillRect(i + 20, 110, 1, 40, RGB565(0, i, 0));
  }
  for (int i = 20; i < 255; i++)
  {
    tft.fillRect(i + 20, 170, 1, 40, RGB565(0, 0, i));
  }
  showmsgXY(BL_DATUM, 20, 300, Ubuntu24, "OK zum übernehmen", textFarbe, hintergrundFarbe);
}

void drawInfoScreen() {
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Informationen über das System", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(BL_DATUM, 25, 80, Ubuntu24, "Dieses System wurde in mühevoller", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 105, Ubuntu24, "Kleinstarbeit und mit viel Zeit", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 130, Ubuntu24, "von Roland zusammengeklöppelt", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 155, Ubuntu24, "Bei Fragen gerne melden.", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 205, Ubuntu24, "Tel: +41 79 xxx xx xx", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 230, Ubuntu24, "email: rxxxxxxxxxxxx@gmail.com", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 280, Ubuntu24, "Programmversion: ", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 250, 280, Ubuntu24, Version, textFarbe, hintergrundFarbe);
}

/*##################################################################
  ## Screen für: Neustart
  ##################################################################*/
void drawResetScreen() {
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Neustart", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(BL_DATUM, 25, 70, Ubuntu24, "Bei einem Neustart des Systems", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 95, Ubuntu24, "werden alle Parameter neu geladen.", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 120, Ubuntu24, "Das Fahrzeug muss dabei ganz", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 145, Ubuntu24, "gerade stehen, da der Niveausensor", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 170, Ubuntu24, "dabei neu kalibriert wird.", textFarbe, hintergrundFarbe);
  showmsgXY(BL_DATUM, 25, 220, Ubuntu24, "Ok zum neu starten", textFarbe, hintergrundFarbe);
}

/*##################################################################
  ## Screen für: Systemnachrichten
  ##################################################################*/

void drawSystemScreen() {
  tft.setRotation(rotar);
  tft.fillScreen(hintergrundFarbe);
  showmsgXY(BL_DATUM, 20, 30, Ubuntu24, "Systemnachrichten", textFarbe, hintergrundFarbe);
  tft.drawFastHLine(0, 34, 480, textFarbe);
  showmsgXY(BL_DATUM, 0, 80, Ubuntu24, systemMessageS, textFarbe, hintergrundFarbe);

}



/************************************************************************************
    Zusätzliche Funktionen
*************************************************************************************/
//##############################################
//#Temperatursensor auswerten
//##############################################
void getDHTData(int8_t &temp, int8_t &hum) {
  temp = dht22.getTemperature();
  hum = dht22.getHumidity();

}

//Temperaturscreen updaten
void updateTempScreen(int8_t temp, int8_t hum) {
  if ((temp) != (temp_alt)) {
    showmsgXY(BR_DATUM, 120, 200, Ubuntu72, temp, 0, textFarbe, hintergrundFarbe);
    temp_alt = temp;
  }
  if ((hum) != (hum_alt)) {
    showmsgXY(BR_DATUM, 380, 200, Ubuntu72, hum, 0, textFarbe, hintergrundFarbe);
    showmsgXY(BL_DATUM, 130, 200, Ubuntu72, "°C", textFarbe, hintergrundFarbe);
    hum_alt = hum;
  }
}

//#######################################################
//Nivelierung
//#######################################################
void getLevel() {
  readMPU();
  if (millis() - startnivel > NIVEL) {
    // Serial.print(F("X: ")); Serial.println(x);
    // Serial.print(F("Y: ")); Serial.println(y);
    if (nivelKorrex(x, y, x_alt, y_alt)) {
      //Serial.print(F("X-checked: ")); Serial.println(x);
      //Serial.print(F("Y-checked: ")); Serial.println(y);
      backgroundS.pushImage(0, 0, 200, 200, gauge);
      img.pushImage(0, 0, 22, 22, libelle);
      img.pushToSprite(&backgroundS, x * multix + 89, y * multiy + 89, TFT_WHITE);  //Weiss wird transparent
      backgroundS.pushSprite(110, 85); // Plot sprite
      x_alt = x;
      y_alt = y;
      startnivel = millis();
    }
  }
}

//##############################################
//#Gyroskop abfragen
//##############################################
void readMPU() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  y = (a.acceleration.x + y_corr);
  x = a.acceleration.y + x_corr;
}

//##############################################
//#GPS abfragen
//##############################################
void readGPS() {
  notsosmartDelay(100);
  sat = gps.satellites.value();
  muM = gps.altitude.meters();
  heading = gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "* ";
  fSpeed = gps.speed.kmph();
  longi = gps.location.lng();
  lati = gps.location.lat();
  distHome = (unsigned long)TinyGPSPlus::distanceBetween(
               gps.location.lat(),
               gps.location.lng(),
               HOME_LAT,
               HOME_LON) / 1000;
  double courseToHome =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      HOME_LAT,
      HOME_LON);
  courseHome = TinyGPSPlus::cardinal(courseToHome);

}

void updateGPSScreen() {
  //Funktion prüfen
  if (millis() - gpsDelay > 1000) {
    gpsDelay = millis();
    if (heading != heading_alt) {
      showmsgXY(BC_DATUM, 120, 150, Ubuntu72, heading, textFarbe, hintergrundFarbe);
      heading_alt = heading;
    }
    if (fSpeed != fSpeed_alt) {
      showmsgXY(BC_DATUM, 360, 150, Ubuntu72, fSpeed, 0, textFarbe, hintergrundFarbe);
      fSpeed_alt = fSpeed;
    }
    if (muM != muM_alt) {
      showmsgXY(BC_DATUM, 120, 260, Ubuntu72, muM, 0, textFarbe, hintergrundFarbe);
      muM_alt = muM;
    }
    if (sat != sat_alt) {
      showmsgXY(BC_DATUM, 360, 260, Ubuntu72, sat, 0, textFarbe, hintergrundFarbe);
      sat_alt = sat;
    }
  }
}
static void notsosmartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (Serial2.available()) {
      gps.encode(Serial2.read());
    }
  } while (millis() - start < ms);
}

//############################################
//Buttons auswerten
//############################################


void checkButtons()
{
  buttonValue = analogRead(tasterPin);
  button = LEER;
  if (buttonValue < 2501) {
    if (lastButtonState == notPressed)  // vorher nicht gedrückt
    {
      lastButtonState = pressed;
      debounceStart = millis();  // Merken, wann ausgelöst wurde
      buttonValue = analogRead(tasterPin);
      buttonPressed = buttonValue;
      Serial.print(F("Tasterwert: ")); Serial.println(buttonValue);
    }
  } else  // Taste nicht (mehr) gedrückt
  {
    if (lastButtonState == pressed)  // wenn Taste als gedrückt gilt
    {
      if (millis() - debounceStart > debounceTime)  // Zeit abgelaufen?
      {
        switch (buttonPressed) {
          case 0 ... 19:
            if (currentPage == MENU)
            {
              button = UP;  //Taste auf UP setzen
              buttonPosY--;
              if (buttonPosY < 1)buttonPosY = MAX_MENU;
            }
            break;

          case 20 ... 300:
            button = RIGHT;  //Taste auf RIGHT setzen
            currentPage++;
            if (currentPage > MAX_SCREENS)currentPage = 0;
            break;

          case 301 ... 700:
            button = LEFT;  //Taste auf LEFT setzen
            currentPage--;
            if (currentPage < 0)currentPage = MAX_SCREENS;
            break;

          case 701 ... 1800:
            if (currentPage == MENU)
            {
              button = DOWN;  //Taste auf DOWN setzen
              buttonPosY++;
              if (buttonPosY > MAX_MENU)buttonPosY = 1;
            }
            break;

          case 1801 ... 2500:
            button = OK_PRESSED; //Taste auf OK_PRESSED setzen

            break;

          default:
            button = LEER;
            break;
        }
      }
      lastButtonState = notPressed;
      //Serial.println(F("Taster losgelassen"));
    }
  }
}




//############################################
//Farben auswählen
//############################################
void getFarben()
{

  readMemory();
  showmsgXY(BC_DATUM, 390, 80, Ubuntu24, "Vorschau", textFarbe, hintergrundFarbe);
  tft.fillRect(340, 100, 100, 100, textFarbe);

  tft.drawRect(18 + colorRed, 50, 3, 40, RGB565(colorRed - 1, 0, 0));
  tft.drawRect(20 + colorRed, 50, 3, 40, RGB565(colorRed + 1, 0, 0));
  tft.drawLine(0, 49, 280, 49, hintergrundFarbe);
  tft.drawLine(0, 90, 280, 90, hintergrundFarbe);
  tft.drawRect(19 + colorRed, 49, 3, 42, TFT_WHITE);
  tft.drawRect(18 + colorGreen, 110, 3, 40, RGB565(0, colorGreen - 1, 0));
  tft.drawRect(20 + colorGreen, 110, 3, 40, RGB565(0, colorGreen + 1, 0));
  tft.drawLine(0, 109, 280, 109, hintergrundFarbe);
  tft.drawLine(0, 150, 280, 150, hintergrundFarbe);
  tft.drawRect(19 + colorGreen, 109, 3, 42, TFT_WHITE);
  tft.drawRect(18 + colorBlue, 170, 3, 40, RGB565(0, 0, colorBlue - 1));
  tft.drawRect(20 + colorBlue, 170, 3, 40, RGB565(0, 0, colorBlue + 1));
  tft.drawLine(0, 169, 280, 169, hintergrundFarbe);
  tft.drawLine(0, 210, 280, 210, hintergrundFarbe);
  tft.drawRect(19 + colorBlue, 169, 3, 42, TFT_WHITE);
  if (yFarbe == 1)
  {
    tft.drawRect(15, 105, 300, 50, hintergrundFarbe);
    tft.drawRect(15, 45, 300, 50, textFarbe);
  }
  if (yFarbe == 2)
  { tft.drawRect(15, 45, 300, 50, hintergrundFarbe);
    tft.drawRect(15, 165, 300, 50, hintergrundFarbe);
    tft.drawRect(15, 105, 300, 50, textFarbe);
  }
  if (yFarbe == 3)
  {
    tft.drawRect(15, 271, 200, 34, hintergrundFarbe);
    tft.drawRect(15, 105, 300, 50, hintergrundFarbe);
    tft.drawRect(15, 165, 300, 50, textFarbe);
  }
  if (yFarbe == 4)
  {
    tft.drawRect(15, 165, 300, 50, hintergrundFarbe);
    tft.drawRect(15, 271, 200, 34, textFarbe);
  }

  textFarbe = RGB565(colorRed, colorGreen, colorBlue);
  writeMemory();
}

//############################################
//Nachricht an Position schreiben
//############################################
void showmsgXY(uint8_t ausrichtung, int16_t x, int16_t y, const uint8_t *f, String msgS, uint16_t vFarbe, uint16_t hFarbe) {
  tft.setTextWrap(true, true);
  tft.loadFont(f);
  tft.setTextDatum(ausrichtung);
  tft.setTextColor(vFarbe, hFarbe, true);
  tft.setTextColor(vFarbe, hFarbe, true);
  if (currentPage == GPSm)
  {
    tft.setTextPadding(tft.textWidth("WWW"));
  }
  else
  {
    tft.setTextPadding(tft.textWidth("W"));
  }
  tft.drawString(msgS, x, y);
  tft.setTextDatum(TL_DATUM);  // Reset datum to normal
  tft.unloadFont();
}

//############################################
//Wert an Position schreiben
//############################################
void showmsgXY(uint8_t ausrichtung, int16_t x, int16_t y, const uint8_t *f, float msgF, uint8_t nachKomma, uint16_t vFarbe, uint16_t hFarbe) {

  char s[6];
  uint8_t len;
  int lang = msgF;
  sprintf(s, "%d", lang);
  len = strlen(s);
  tft.setTextWrap(true, true);
  tft.loadFont(f);
  tft.setTextDatum(ausrichtung);
  tft.setTextColor(vFarbe, hFarbe, true);
  switch (len)
  {
    case 1:
      tft.setTextPadding(tft.textWidth("WW"));
      break;
    case 2:
      tft.setTextPadding(tft.textWidth("WWW"));
      break;
    case 3:
      tft.setTextPadding(tft.textWidth("WWWW"));
      break;
    case 4:
      tft.setTextPadding(tft.textWidth("WWWWW"));
      break;
    default:
      tft.setTextPadding(tft.textWidth("W"));
      break;
  }
  tft.drawFloat(msgF, nachKomma, x, y);
  tft.setTextDatum(TL_DATUM);  // Reset datum to normal
  tft.unloadFont();
}

// -------------------------------------------------------------------------
// List files in ESP8266 or ESP32 filesystem
// -------------------------------------------------------------------------
void listDir(fs::FS & fs, const char * dirname, uint8_t levels) {
  Serial.printf("Listing directory: %s\r\n", dirname);

  File root = fs.open(dirname);
  if (!root) {
    Serial.println("- failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println(" - not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if (levels) {
        listDir(fs, file.path(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("\tSIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}


bool nivelKorrex(float xn, float yn, float xa, float ya)
{
  if (xn - xa > KORREX or xn - xa < (KORREX * -1) or yn - ya > KORREX or yn - ya < (KORREX * -1))
  {
    Serial.print(F("X_diff: ")); Serial.println(xn - xa);
    Serial.print(F("Y_diff: ")); Serial.println(yn - ya);
    return 1;
  }
  else
  {
    return 0;
  }
}


//Handles für Webinterface
void handleLevel()
{

  getLevel();
  String message;
  // String message = woKeilen;
  Serial.println(message);
  message += F("</BR></BR>"
               "<svg height=\"220\" width=\"220\"> "
               "<circle cx=\"110\" cy=\"110\" r=\"100\" stroke=\"black\" "
               "stroke-width=\"2\" fill=\"#00FF00\" /> "

               "<circle cx=\"110\" cy=\"110\" r=\"20\" stroke=\"black\" "
               "stroke-width=\"2\" fill=\"darkgreen\" /> "


               "<circle cx=");
  message +=  x * multix + 110;
  message += F(" cy=");
  message +=  y * multiy + 110;
  message += F(" r=\"7\" stroke=\"red\" "
               "stroke-width=\"2\" fill=\"red\" /> "
               " </svg> "
              );


  message += F("</span>");


  server.send(200, "text/html", message); //Send web page
}

void handleWasserwaage()
{
  String message = F("<link rel=\"stylesheet\" type=\"text/css\" href=<\"f.css?rnd=132\">");
  server.send(200, "text/css", message);
}

void handleGPS()
{
  readGPS();
  String message = F("Längengrad: ");
  message += String(longi, 7);
  message += F("<br> Breitengrad: ");
  message += String(lati, 7);
  message += F("<br>Höhe über Meer: ");
  message += muM;
  message += F("<br>Blick-/Fahrtrichtung: ");
  message += heading;
  message += F("<br>Geschwindigkeit: ");
  if (fSpeed < 2) fSpeed = 0;
  message += fSpeed;
  message += F(" km/h<br>"
               "Luftlinie bis nach Hause: ");
  if (distHome < 20) message += "Du bist daheim";
  else
  {
    message += String(distHome);
    message += " km";
  }
  message += F("<br>Das Zuhause liegt in folgender Richtung: ");
  message += courseHome;
  message += F("</BR></BR>");
  message += F("</span>");

  server.send(200, "text/html", message); //Send web page
}

void readMemory()
{
  //Farben für Hauptfarbe aus EEProm laden
  ssids = speicher.getString("ssid");
  passwords = speicher.getString("password");
  textFarbe = speicher.getInt("farbe");
  colorRed = speicher.getInt("farbeRot");
  colorGreen = speicher.getInt("farbeGruen");
  colorBlue = speicher.getInt("farbeBlau");
  hintergrundFarbeW = speicher.getString("hFarbeWeb");
  /* Serial.println(F("Daten geladen"));
    Serial.print(F("ssid: ")); Serial.println(ssids);
    Serial.print(F("passwort: ")); Serial.println(passwords);
    Serial.print(F("Farbe: ")); Serial.println(textFarbe);
    Serial.print(F("Farbe Rot: ")); Serial.println(colorRed);
    Serial.print(F("Farbe Grün: ")); Serial.println(colorGreen);
    Serial.print(F("Farbe blau: ")); Serial.println(colorBlue);
    Serial.print(F("Hintergrund: ")); Serial.println(hintergrundFarbeW);*/
}

void writeMemory()
{
  speicher.begin("credentials", false);
  speicher.putString("ssid", ssids);
  speicher.putString("password", passwords);
  speicher.putInt("farbe", textFarbe);
  speicher.putInt("farbeRot", colorRed);
  speicher.putInt("farbeGruen", colorGreen);
  speicher.putInt("farbeBlau", colorBlue);
  speicher.putString("hFarbeWeb", hintergrundFarbeW);
}

void colorConverter(String hexString)
{
  //String hexString = hex;
  Serial.print(F("HEX: ")); Serial.println(hexString);
  long number = (int) strtol( &hexString[0], NULL, 16);
  colorRed = number >> 16;
  colorGreen = number >> 8 & 0xFF;
  colorBlue = number & 0xFF;
  textFarbe = RGB565(colorRed, colorGreen, colorBlue);
  Serial.print("red is ");
  Serial.println(colorRed);
  Serial.print("green is ");
  Serial.println(colorGreen);
  Serial.print("blue is ");
  Serial.println(colorBlue);
}

void updateMenuM()
{
  for (uint8_t i = 0; i < MAX_MENU;)
  {
    Serial.print(F("I: ")); Serial.println(i);
    tft.drawRoundRect(BUTTONX, BUTTONY + (BUTTONS * (i)), BUTTONW, BUTTONH, BUTTONR, hintergrundFarbe);
    i++;
  }
  Serial.print(F("buttonpos: ")); Serial.println(buttonPosY);
  tft.drawRoundRect(BUTTONX, BUTTONY + (BUTTONS * (buttonPosY - 1)), BUTTONW, BUTTONH, BUTTONR, textFarbe);
}

//Vers. 20240914.1728
/********************************************************************
   Webserver

   ******************************************************************/

// the html output
// Advice: check your generated HTML output if it is valid HTML: https://validator.w3.org
// *** HOME ***  0.htm
String level = "Level";
String getm = "GET";
void handleMenupage() {
  if (oldPage != SPLASH) {
    currentPage = SPLASH;
    oldPage = currentPage;
    drawSplashScreen();

  }
  String message;
  readMemory();
  message =  F("<!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<title>" "Womo-Monitor" );
  message += F("</title>\n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>Womo-Monitor" );

  message += F("</h1>\n"
               "<nav><p>"
               "<a href=\"wasserPage.htm\"><button class='button'>Wasser</button></a>"
               "<a href=\"levelPage.htm\"><button class='button'>Level</button></a><br>"
               "<button class='button'>Batterie</button></a>"
               "<a href=\"wetterPage.htm\"><button class='button'>Wetter</button></a><br>"
               "<button class='button'>Solar</button></a>"
               "<button class='button'>Strom</button></a><br>"
               "<a href=\"settingsPage.htm\"><button class='button'>Einstellungen</button></a>"
               "<a href=\"infoPage.htm\"><button class='button'>Infos</button></a><br>"
               "<a href=\"gpsPage.htm\"><button class='button'>GPS</button></a>"
               "</nav>\n"
               "</header>\n"
               "<main>\n");
  /*
    // print whatever you need on the web page:
    message += F("<article>\n"
                 "<h2>Values</h2>\n"
                 "<p>The integer variable  is currently: ");
    message += anInteger;
    message += F("</p>\n");
    message += F("<p>The float variable is currently: ");
    message += aFloat;
    message += F("</p>\n");
    message += F("</article>\n");

    message += F("<article>\n"
                 "<h2>Another Topic</h2>\n"
                 "<p>The String object doesn't update currently: ");
    message += aString;
    message += F("</p>\n");
    message += F("</article>\n");
  */
  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}

// *** Wetter ***
void handleWetterpage() {
  if (oldPage != TEMP) {
    currentPage = TEMP;
    oldPage = currentPage;
    drawTempScreen(temperature, humidity);

  }
  String message;

  message =  F("<!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<meta http-equiv=\"refresh\" content=\"120\">"
               "<title>" "Wetter" );
  message += F("</title>\n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>" "Womo-Monitor" );
  message += F("</h1>\n"
               "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>\n"
               "</header>\n"
               "<main>\n");

  message += F("<article>\n"
               "<h2>Wetterdaten</h2>\n"
               "<p>Temperatur: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
  message += temperature;
  message += F(" °C<br>");
  message += F( "<p>Feuchtigkeit: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
  message += humidity;
  message += F(" %<br>");
  /*  message += F("Luftdruck: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
    message += pres / 100 + sealevelKorr;
    message += F(" hpa<br>"
                 "Tendenz:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
    message += wetterTendenz;
    message += F("<br><br>");
    message += baroMessage;*/
  message += F("</p>");

  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("</p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}


// *** Wasser ***
void handleWasserpage() {

  String message;

  message =  F("<!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<meta http-equiv=\"refresh\" content=\"1\">"
               "<title>" "Wasser"
               "</title>\n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>" "Womo-Monitor" );
  message += F("</h1>\n"
               "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>\n"
               "</header>\n"
               "<main>\n");

  // print whatever you need on the web page:
  message += F("<article>\n"
               "<h2>Frischwasser</h2>\n"
               "<p>Tankinhalt: ");
  // message += Wasserstand;
  message += (" %<br>");
  message += F("</article>\n");

  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}


// *** Nivelierung ***
void handleLevelpage() {
  if (oldPage != LEVEL) {
    currentPage = LEVEL;
    oldPage = currentPage;
    drawLevelScreen();

  }
  String message;
  message = levelPage; //Read HTML contents
  message += F( "</article></p>"
                "</main>");
  message += F(            "<footer>"
                           "<p>Programmversion: ");
  message += Version;
  message += F("</p>\n"
               "</footer\n>"
               "</body>"
               "</html>");
  server.send(200, "text/html", message); //Send web page
}
// *** GPS ***
void handleGPSpage() {
  if (oldPage != GPSm) {
    currentPage = GPSm;
    oldPage = currentPage;
    drawGPSScreen();

  }
  String message;
  message = gpsPage; //Read HTML contents
  message += F( "</article></p>"
                "</main>");
  message += F(            "<footer>"
                           "<p>Programmversion: ");
  message += Version;
  message += F("</p>\n"
               "</footer\n>"
               "</body>"
               "</html>");
  server.send(200, "text/html", message); //Send web page

}
// *** Farben ***
void handleFarbenpage() {
  if (oldPage != FARBEN) {
    currentPage = FARBEN;
    oldPage = currentPage;
    drawColorScreen();

  }
  String message;
  readMemory();
  String tempcolor = hintergrundFarbeW;
  Serial.print("Read color : "); Serial.println(hintergrundFarbeW);
  message = F("<!DOCTYPE html>\n"
              "<html lang='en'>\n"
              "<head>\n"
              "<title>" "Farben"
              "</title>\n"
              "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
              "<meta name=\"viewport\" content=\"width=device-width\">\n"
              "<link rel='stylesheet' type='text/css' href='f.css'>\n"
              "</head>\n"
              "<body>"
              "<header><h1>Womo-Monitor</h1>"
              "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>"
              "</header>"
              "<main>\n"
              "<article>\n"
              "<form action=\"/farbenPage.htm\">\n"
              "<label for = \"favcolor\">Farbe wählen: </label> "
              "<input type = \"color\" id = \"favcolor\" name = \"favcolor\" value = #'");
  Serial.print("Laufende Farbe: "); Serial.println(hintergrundFarbeW);
  message += hintergrundFarbeW;
  message += F("'>"
               " <br> "
               "<button type = \"submit\" value = \"favcolor\" class = \"button\" >SET</button> ");
  String uebergabe = "";

  for (uint8_t i = 0; i < server.args(); i++)
  {
    uebergabe += server.arg(i);
  }
  hintergrundFarbeW = uebergabe;

  if (hintergrundFarbeW == "")
  {
    hintergrundFarbeW = tempcolor;
  }
  // Serial.print("Uebergabe: "); Serial.println(uebergabe);
  Serial.print("Hintergrund: "); Serial.println(hintergrundFarbeW);
  // Serial.println(message);
  hintergrundFarbeW.remove(0, 1);
  colorConverter(hintergrundFarbeW);
  drawColorScreen();
  Serial.println(hintergrundFarbeW);
  writeMemory();
  readMemory();
  Serial.print("Hintergrund: "); Serial.println(hintergrundFarbeW);

  message += F(" </form> "
               "</article>"
               "</body>"
               "</html>");
  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");
  server.send(200, "text/html", message); //Send web page

}

// *** Settings ***
void handleSettingspage() {
  String message;

  message =  F(" <!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<title>" "Einstellungen" );
  message += F(" </title> \n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>Einstellungen" );

  message += F("</h1>\n"
               "<nav><p>"
               "<a href=\"/\"><button class='button'>Home</button></a><br>"
               "<a href=\"neustartPage.htm?fname=Nein&subject=\"><button class='button'>Neustart</button></a>"
               "<a href=\"hoehePage.htm\"><button class='button'>Höhe</button></a><br>"
               "<a href=\"farbenPage.htm\"><button class='button'>Farben</button></a>"
               "<a href=\"systemPage.htm\"><button class='button'>Systemnachrichten</button></a><br>"
               "<a href=\"wifiPage.htm\"><button class='button'>WiFi</button></a>"
               "<a href=\"passwortPage.htm\"><button class='button'>Passwort</button></a><br>"
               "</nav>\n"
               "</header>\n"
               "<main>\n");

  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}

//Systemnachrichten
void handleSystempage() {
  if (oldPage != SYSTEM) {
    currentPage = SYSTEM;
    oldPage = currentPage;
    drawSystemScreen();

  }
  String message;

  message =  F(" <!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<title>" "Systemnachrichten" );
  message += F(" </title> \n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>Systemnachrichten" );

  message += F("</h1>\n"
               "<nav><p>"
               "<a href=\"/\"><button class='button'>Home</button></a><br>"

               "</nav>\n"
               "</header>\n"
               "<main>\n");
  message += systemMessageW;
  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}
// *** Neustart ***
void handleNeustartpage() {
  if (oldPage != NEUSTART) {
    currentPage = NEUSTART;
    oldPage = currentPage;
    drawResetScreen();

  }
  String message;

  message = F("<!DOCTYPE html>\n"
              "<html lang='en'>\n"
              "<head>\n"
              "<title>" "Neustart"
              "</title>\n"
              "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
              "<meta name=\"viewport\" content=\"width=device-width\">\n"
              "<link rel='stylesheet' type='text/css' href='f.css'>\n"
              "</head>\n"
              "<body>"
              "<header><h1>Womo-Monitor</h1>"
              "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>"
              "</header>"
              "<main>\n"
              "<article>\n"
              "Ja eingeben für Neustart<br>"
              "<form action=\"/neustartPage.htm\">\n");
  message += F("<label for='fname'</label><br>"
               "<input type='text' id='fname' name='fname' value=\"Nein\"><br>"
               " <br> "
               "<button name = \"subject\" type = \"submit\" class = \"button\" >Senden</button> ");
  String uebergabe = "";

  for (uint8_t i = 0; i < server.args(); i++)
  {
    uebergabe += server.arg(i);
  }
  Serial.println(uebergabe);
  if (uebergabe == "Ja")
  {
    delay(2000);
    ESP.restart();
    server.send(200, "text/html", "<META http-equiv=\"refresh\" content=\"1;URL=/\">");
  }
  message += F(" </form> "
               "</article>"
               "</body>");
  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");
  server.send(200, "text/html", message); //Send web page
  readMemory();
}
//Neustart
void handleNeustart() {
  String message;

  message = F("<!DOCTYPE html>\n"
              "<html lang='en'>\n"
              "<head>\n"
              "<title>" "Neustart"
              "</title>\n"
              "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
              "<meta name=\"viewport\" content=\"width=device-width\">\n"
              "<link rel='stylesheet' type='text/css' href='f.css'>\n"
              "</head>\n"
              "<body>"
              "<header><h1>Neustart</h1>"
              "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>"
              "</header>"
              "<main>\n"
              "</body>");
  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("<p>\n"
               "</footer>\n");


  server.send(200, "text/html", message); //Send web page
  ESP.restart();
}


// *** Info ***
void handleInfopage() {
  if (oldPage != INFO) {
    currentPage = INFO;
    oldPage = currentPage;
    drawInfoScreen();
  }
  String message;

  message =  F("<!DOCTYPE html>\n"
               "<html lang='en'>\n"   // english or any other language code you using for your page content
               "<head>\n"
               "<title>" "Infos" );
  message += F("</title>\n"
               "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
               "<meta name=\"viewport\" content=\"width=device-width\">\n"
               "<link rel='stylesheet' type='text/css' href='f.css'>\n"
               "</head>\n");
  message += F("<body>\n");
  message += F("<header>\n<h1>Womo-Monitor" );
  message += F("</h1>\n"
               "<nav><p><a href=\"/\"><button class='button'>Home</button></a></nav>\n"
               "</header>\n"
               "<main>\n");

  message += F("<article>\n"
               "<h2>Informationen über das System</h2>\n"
               "<p>Dieses System wurde in mühevoller<br>"
               "Kleinstarbeit und mit viel Zeit<br>"
               "von mir zusammengeklöppelt.<br><br>"
               "Bei Fragen oder Problemen gerne melden<br><br>"
               "Tel: +41 79 ... .. ..<br>"
               "email: r..........@gmail.com");

  // end of content
  message += F("</main>\n");
  // a footer line
  message += F("<footer>\n"
               "<p>Programmversion: ");
  message += Version;
  message += F("</p>\n"
               "</footer>\n");

  server.send(200, "text/html", message);
}

// Output a "404 not found" page. It includes the parameters which comes handy for test purposes.
void handleNotFound() {
  Serial.println(F("D124 handleNotFound()"));
  String message;
  message += F("404 - File Not Found\n"
               "URI: ");
  message += server.uri();
  Serial.println(server.uri());
  message += F("\nMethod: ");
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += F("\nArguments: ");
  message += server.args();
  message += F("\n");
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

// Output a "204 no content" page. Used for the favicon.ico request (as we don't have any favicon currently)
void handle204() {
  server.send(204);                // this page doesn't send back content
}


void handleCss() {
  // output of stylesheet
  // this is a straight forward example how to generat a static page from program memory
  String message;
  readMemory();
  message = F("*{font-family:sans-serif}\n"
              "body{margin:10px}\n"
              "h1, h2{color:white;background:#C0C0C0");
  message += F(";text-align:left}\n"
               "h1{margin:1px;padding:5px;font-size:1.4em}\n"
               "h2{margin:1px;padding:5px;font-size:1.2em}\n"
               "main{text-align:left}\n"
               "nav{background-color:#");
  message += hintergrundFarbeW;
  message += F(";margin:1px;padding:5px;font-size:0.8em;align:center;}\n"
               "article{margin:1px;padding:0.1em;border-style:solid;border-width:thin;border-color:#");
  message += hintergrundFarbeW;
  message += F(";text-align:left;background-color:#");
  message += hintergrundFarbeW;
  message += F("}\n"
               "footer p{font-size:0.7em;color:dimgray;background:silver;text-align:left;margin-bottom:5px}\n"
               //Button
               ".button {"
               "display: inline-block;"
               "padding: 5px 5px;"
               "font-size: 15px;"
               "cursor: pointer;"
               "margin: 4px 4px;"
               "text-align: center;"
               "text-decoration: none;"
               "outline: none;"
               "color: #fff;"
               "width: 150px;"
               "background-color:#008800;border: none;"
               "border-radius: 5px;"
               "box-shadow: 5px 5px #909090;"
               "}");

  server.send(200, "text/css", message);
}

mein verdacht wäre ja, dass der Server nachfragt, ob da eine neue Seite gesendet wurde, aber wie kann ich das machen?
hat jemand eine idee?
Hardware ist ein 3.5" parallel TFT ohne Touchfunktion,
ein DHT22
ein GPS
ein 5 Tasten Modul sowas
und ein MPU6050 Gyroskop
sowie ein ESP32

Der Server fragt nicht!
Dann wäre er ja ein Client und kein Server.

Vielleicht suchst du ja Websockets, oder so...

Oder Du fragst aus dem Browser per Fetch-API zyklisch den Status des Servers ab. Wie das geht siehst Du bei Fips.

Gruß Tommy

Fips scheint bei ESP die Standardantwort :rofl: Hätte er mal einen logischen seitenaufbau wäre das DIE top referenz. Ich schau da mal durch

Er hat einen logischen Seitenaufbau, denn alles sind Erweiterungen zum Webserver. Um in die Logik einzusteigen, gibt es die Einführung von @agmue.
Wichtig ist es auch die Kommentare am Anfang zu lesen. Sie beschreiben, wie die einzelnen Teile in den Webserver einzufügen sind.

Gruß Tommy

Daten nachladen beschreibe ich im Beispiel 70:
https://werner.rothschopf.net/microcontroller/202310_esp_webserver_maxi_en.htm#70

Das ist aber eher, auf der Seite gibts wo Werte - und diese werden aktualisiert.

Wenn du einen ganzen Seitenwechsel willst, müsstest du eigentlich den Inhalt der ganzen Seite tauschen. Dazu müssten du den reinen html body als resource zur Verfügung stellen und mittels Fetch API austauschen.

Ja.

Dort siehst Du auch, daß man die HTML-Datei besser im Dateisystem speichert und nicht im Programm. Es muß auch nicht bei jeder Änderung die ganze Seite übertragen werden, sondern es genügt etwas JSON, was gut zu JavaScript paßt. Darin findest Du setInterval(renew, 1000), damit sich die HTML-Seite frische Infos holt.

Die Erklärung ESP32 WebSocket Server: Control Outputs (Arduino IDE) finde ich ganz gut, allerdings wird dort die Bibliothek ESPAsyncWebServer verwendet, was m. E. nicht notwendig ist.

Jetzt noch WebSocket mit Fips zusammengebracht, darauf könntest Du aufbauen :wink:

ESP_WebSocket_server2client.zip (16,5 KB)

Eventuell sind die Tabs nicht mehr aktuell, aber so zusammen tun sie es. Mußt Du erst drauf achten, wenn Du sie in Dein Projekt einbaust.

image

Das sollte doch Deinem Wunsch entsprechen, oder?

das schaue ich mir gerne an, sobald ich das neue Display zum leuchten gebracht habe :see_no_evil:

Wo ist das Problem? :wink:

habs dir im anderen thread beschrieben

Dan schreib mall was für Typ ist das.

steht alles hier :wink:

Das ist der Nachteil, wenn man seine Beiträge auf mehrere Threads verteilt.

Gruß Tommy

ist ja ein anderes Problem. Das hier behandelt das Problem, dass man per Tastenddruck den Browser updaten kann. Im anderen Thread behandeln wir Probleme mit dem Monitor an und für sich

Also das habe ich mal runtergeladen. Das läuft auch soweit,, löst aber mein Problem nicht. Einzelne werte anzeigen habe ich ja auch schon mit der Wasserwaage, GPS etc.
ich bräuchte eben das umgekehrte. Wenn ich am Arduino einen Taster drücke, dass dann der Browser aktualisiert.
Ich hatte heute noch eine wilde idee:
Eine If abfrage, ob sich was geändert hat im ESP bezüglich andere page, und dann das ganze an einen redirect funktion in der html übergeben (natürlich dort auch mit abfrage ob, und was geändert hat.)

Gut, dann kann ich darauf aufbauen :slightly_smiling_face:

Dann verstehe ich Dein Problem nicht oder Du irrst, kannst Du Dir aussuchen :blush:

GPIO 35: zu messende Spannung
GPIO 33: Taster gegen GND
Display (ST7735) an mehreren GPIOs

Die Spannung und der Zustand der LED wird auf dem Display und im Browser (/index.html) angezeigt. Die LED kann mittels Taster und Klicken im Browser umgeschaltet werden.

ESP_WebSocket_server2client.zip (27,6 KB)

image

image

Das Programm tut, was es soll, ist aber wenig vorbildlich.

Löst das Dein Problem?

ohne den sketch getestet zu haben glaube ich nicht dass das mein Problem löst.
beim drücken des Tasters sollte nicht etwas auf der Seite geändert werden. Wenn ich den Taster drücke sollte index.html verlassen werden und z.b. info.html aufgerufen werden.

  1. Eine Variante wäre mittels Javascript/FechtAPI den ganzen HTML Body auszutauschen.
  2. Oder ein Javascript periodisch abfragen zu lassen was den die aktuelle Display Seite ist und entsprechend eine andere Seite anzufordern.

1 erscheint mir besser.

ja im prinzip so ähnlich wie ich in post #16 geschrieben habe. Da müsste ich aber wahrscheinlich eher in einem html Forum nachfragen wie ich das am besten mache