Webserver nach hinzufügen von Motor WatchDog Fehler

Hallo in die Runde, ich habe ein Webserver für ESP32 Wroom 32 und das funktioniert alles auch ohne Probleme.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <time.h>

// Netzwerkdaten
const char* ssid = "*****";
const char* password = "****";

// WebServer
AsyncWebServer server(80);

// Zeitkonfiguration
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const char* timezone = "CET-1CEST-2,M3.5.0/2,M10.5.0/3"; // Auto DST für Deutschland

// HTML Template
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
  <title>ESP32 WLAN Status</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    body { 
      font-family: Arial; 
      text-align: center; 
      margin: 50px auto;
      background-color: #f0f0f0;
      position: relative;
    }
    .status-box {
      background-color: %COLOR%;
      padding: 20px;
      border-radius: 10px;
      margin: 20px;
      display: inline-block;
    }
    #zeit {
      position: absolute;
      top: 10px;
      right: 10px;
      background: white;
      padding: 8px 15px;
      border-radius: 5px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    }
  </style>
</head>
<body>
  <div id="zeit">Lade Uhrzeit...</div>
  <h1>ESP32 WLAN Status</h1>
  <div class="status-box">
    <h3>Verbindungsstatus:</h3>
    <p style="font-size:24px">%STATUS%</p>
    <p>IP-Adresse: %IP%</p>
  </div>
  <br>
  <button onclick="location.reload()">Aktualisieren</button>

  <script>
  function updateZeit() {
    fetch('/zeit')
      .then(response => response.json())
      .then(data => {
        document.getElementById('zeit').innerHTML = data.zeit;
      })
      .catch(error => console.error('Fehler:', error));
    setTimeout(updateZeit, 1000);
  }
  updateZeit();
  </script>
</body>
</html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  delay(1000);

  // WLAN-Verbindung
  WiFi.begin(ssid, password);
  Serial.println("\nVerbinde mit WLAN...");

  int versuche = 0;
  while (WiFi.status() != WL_CONNECTED && versuche < 20) {
    delay(500);
    Serial.print(".");
    versuche++;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nVerbunden!");
    Serial.print("IP: ");
    Serial.println(WiFi.localIP());

    // NTP-Zeitsynchronisation
    configTzTime(timezone, ntpServer1, ntpServer2);
    Serial.println("Synchronisiere Uhrzeit...");
    
    int retry = 0;
    while (time(nullptr) < 1000000000 && retry < 10) {
      Serial.print(".");
      delay(500);
      retry++;
    }
    Serial.println("\nZeit synchronisiert!");

    // mDNS
    MDNS.begin("esp32");

    // WebServer-Routen
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      String html = index_html;
      html.replace("%COLOR%", WiFi.status() == WL_CONNECTED ? "#90EE90" : "#FFB6C1");
      html.replace("%STATUS%", WiFi.status() == WL_CONNECTED ? "VERBUNDEN" : "GETRENNT");
      html.replace("%IP%", WiFi.localIP().toString());
      request->send(200, "text/html", html);
    });

    server.on("/zeit", HTTP_GET, [](AsyncWebServerRequest *request){
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        request->send(500, "text/plain", "Zeitabfrage fehlgeschlagen");
        return;
      }
      
      char zeitStr[64];
      strftime(zeitStr, sizeof(zeitStr), "%d.%m.%Y %H:%M:%S", &timeinfo);
      String json = "{\"zeit\":\"" + String(zeitStr) + "\"}";
      request->send(200, "application/json", json);
    });

    server.onNotFound([](AsyncWebServerRequest *request){
      request->send(404, "text/plain", "Seite nicht gefunden");
    });

    server.begin();
    Serial.println("WebServer gestartet!");

  } else {
    Serial.println("\nVerbindung fehlgeschlagen!");
    while(1) delay(1000);
  }
}

void loop() {
  // Hier können weitere Aufgaben hinzugefügt werden
  delay(1000);
}

Wenn ich jetzt die H-Brücke BTS7960 + Motor integrieren will bekomme ich den WatchDog Fehler.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <time.h>
#include "config.h"

// Motorvariablen
bool motorActive = false;
String currentDirection = "stop";
int currentSpeed = 100;
unsigned long motorStartTime = 0;

// WebServer und Zeit
AsyncWebServer server(80);
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const char* timezone = "CET-1CEST-2,M3.5.0/2,M10.5.0/3";

void setupMotor() {
  pinMode(R_EN, OUTPUT);
  pinMode(L_EN, OUTPUT);
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  
  digitalWrite(R_EN, HIGH);
  digitalWrite(L_EN, HIGH);
  digitalWrite(RPWM, LOW);
  digitalWrite(LPWM, LOW);
}

void controlMotor(String state, String direction, int speed) {
  if(state == "start") {
    int pwm = map(speed, 0, 100, 0, 255);
    if(direction == "links") {
      analogWrite(LPWM, pwm);
      analogWrite(RPWM, 0);
    } else if(direction == "rechts") {
      analogWrite(RPWM, pwm);
      analogWrite(LPWM, 0);
    }
    motorActive = true;
    currentDirection = direction;
    currentSpeed = speed;
    motorStartTime = millis();
  } else {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
    motorActive = false;
    motorStartTime = 0;
  }
}

String formatRuntime(unsigned long ms) {
  unsigned long seconds = ms / 1000;
  unsigned long minutes = seconds / 60;
  unsigned long hours = minutes / 60;
  seconds %= 60;
  minutes %= 60;
  
  char buf[20];
  snprintf(buf, sizeof(buf), "%02lu:%02lu:%02lu", hours, minutes, seconds);
  return String(buf);
}

void setup() {
  Serial.begin(115200);
  setupMotor();
  delay(1000);

  WiFi.begin(ssid, password);
  Serial.println("\nVerbindungsaufbau mit WLAN...");

  int versuche = 0;
  while(WiFi.status() != WL_CONNECTED && versuche < 20) {
    delay(500);
    Serial.print(".");
    versuche++;
  }

  if(WiFi.status() == WL_CONNECTED) {
    Serial.println("\nErfolgreich verbunden!");
    Serial.print("IP-Adresse: ");
    Serial.println(WiFi.localIP());

    configTzTime(timezone, ntpServer1, ntpServer2);
    Serial.println("Zeitsynchronisation gestartet...");

    if(!MDNS.begin("esp32")) {
      Serial.println("mDNS Fehler!");
    } else {
      Serial.println("mDNS gestartet: http://esp32.local");
    }

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      String html = FPSTR(index_html);
      html.replace("%COLOR%", "#90EE90");
      html.replace("%STATUS%", "VERBUNDEN");
      html.replace("%IP%", WiFi.localIP().toString());
      html.replace("%MOTOR_STATUS%", 
        String(motorActive ? "AKTIV" : "INAKTIV") + 
        " (" + currentDirection + ", " + 
        String(currentSpeed) + "%)");
      request->send(200, "text/html", html);
    });

    server.on("/zeit", HTTP_GET, [](AsyncWebServerRequest *request){
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        request->send(500, "text/plain", "Zeitfehler");
        return;
      }
      char zeitStr[64];
      strftime(zeitStr, sizeof(zeitStr), "%d.%m.%Y %H:%M:%S", &timeinfo);
      request->send(200, "application/json", "{\"zeit\":\"" + String(zeitStr) + "\"}");
    });

    server.on("/motor", HTTP_GET, [](AsyncWebServerRequest *request){
      String state = request->arg("state");
      String direction = request->arg("direction");
      int speed = request->arg("speed").toInt();
      
      speed = constrain(speed, 0, 100);
      
      if(state == "start" && (direction == "links" || direction == "rechts")) {
        controlMotor(state, direction, speed);
        request->send(200, "text/plain", "OK");
      } 
      else if(state == "stop") {
        controlMotor(state, direction, 0);
        request->send(200, "text/plain", "OK");
      }
      else {
        request->send(400, "text/plain", "Ungültige Parameter");
      }
    });

    server.on("/motorStatus", HTTP_GET, [](AsyncWebServerRequest *request){
      String json = String("{\"state\":\"") + (motorActive ? "AKTIV" : "INAKTIV") + "\",";
      json += "\"direction\":\"" + currentDirection + "\",";
      json += "\"speed\":" + String(currentSpeed) + "}";
      request->send(200, "application/json", json);
    });

    server.on("/runtime", HTTP_GET, [](AsyncWebServerRequest *request){
      unsigned long runtime = millis() - motorStartTime;
      unsigned long seconds = runtime / 1000;
      unsigned long minutes = seconds / 60;
      unsigned long hours = minutes / 60;
      seconds %= 60;
      minutes %= 60;
      
      String json = String("{\"h\":") + hours + ",\"m\":" + minutes + ",\"s\":" + seconds + "}";
      request->send(200, "application/json", json);
    });

    server.onNotFound([](AsyncWebServerRequest *request){
      request->send(404, "text/plain", "404: Not Found");
    });

    server.begin();
    Serial.println("HTTP Server gestartet!");

  } else {
    Serial.println("\nVerbindung fehlgeschlagen!");
    while(1) delay(1000);
  }
}

void loop() {
  // Eventuelle Hintergrundaufgaben hier einfügen
  delay(1000);
}

config.h

#ifndef CONFIG_H
#define CONFIG_H

// Netzwerkdaten
const char* ssid = "*****";
const char* password = "****";

// H-Brücke Pins
#define RPWM 3
#define R_EN 4
#define R_IS 5
#define LPWM 6
#define L_EN 7
#define L_IS 8

// HTML Template
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
  <title>ESP32 Motorsteuerung</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    /* CSS-Stile hier einfügen (wie im vorherigen Code) */
  </style>
</head>
<body>
  <div id="zeit">Lade Uhrzeit...</div>
  <h1>ESP32 Motorsteuerung</h1>
  
  <div class="status-box">
    <h3>Systemstatus:</h3>
    <p>Verbindung: %STATUS%</p>
    <p>IP: %IP%</p>
    <p>Motorstatus: <span id="motorStatus">%MOTOR_STATUS%</span></p>
    <p>Laufzeit: <span id="runtime">00:00:00</span></p>
  </div>

  <div class="motor-control">
    <!-- HTML-UI-Elemente hier einfügen (wie im vorherigen Code) -->
  </div>

  <script>
    // JavaScript-Code hier einfügen (wie im vorherigen Code)
  </script>
</body>
</html>
)rawliteral";

#endif

Fehler

rst:0x8 (TG1WDT_SYS_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8

Was kann ich machen damit ich den Fehler nicht mehr bekomme, hat zufällig jemand eine Idee?

Das liegt an deiner Pinbelegung für den Motortreiber.
Da sind Pins bei, die du nicht benutzen darfst.
Sieh mal hier nach.

Prima, wenn es jetzt funktioniert.
Es wäre schön, wenn du deine Änderungen hier in einem neuen Post nochmal hinterlegst.

Ist zwar nicht fertig, aber der Motor kann gesteuert werden.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <time.h>
#include "config.h"

// Motorvariablen
bool motorActive = false;
String currentDirection = "stop";
int currentSpeed = 100;
unsigned long motorStartTime = 0;

// WebServer und Zeit
AsyncWebServer server(80);
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const char* timezone = "CET-1CEST-2,M3.5.0/2,M10.5.0/3";

void setupMotor() {
  pinMode(R_EN, OUTPUT);
  pinMode(L_EN, OUTPUT);
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  
  digitalWrite(R_EN, HIGH);
  digitalWrite(L_EN, HIGH);
  digitalWrite(RPWM, LOW);
  digitalWrite(LPWM, LOW);
}

void controlMotor(String state, String direction, int speed) {
  if(state == "start" && speed > 0) {  // Nur aktiv bei Speed > 0
    int pwm = map(speed, 0, 100, 0, 255);
    if(direction == "links") {
      analogWrite(LPWM, pwm);
      analogWrite(RPWM, 0);
    } else if(direction == "rechts") {
      analogWrite(RPWM, pwm);
      analogWrite(LPWM, 0);
    }
    motorActive = true;
    currentDirection = direction;
    currentSpeed = speed;
    if(motorStartTime == 0) {  // Startzeit nur setzen, wenn nicht bereits läuft
      motorStartTime = millis();
    }
  } else {  // Stoppen bei state=stop ODER speed=0
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
    motorActive = false;
    currentSpeed = 0;
    motorStartTime = 0;  // Startzeit zurücksetzen
  }
}

String formatRuntime(unsigned long ms) {
  unsigned long seconds = ms / 1000;
  unsigned long minutes = seconds / 60;
  unsigned long hours = minutes / 60;
  seconds %= 60;
  minutes %= 60;
  
  char buf[20];
  snprintf(buf, sizeof(buf), "%02lu:%02lu:%02lu", hours, minutes, seconds);
  return String(buf);
}

void setup() {
  Serial.begin(115200);
  setupMotor();
  delay(1000);

  WiFi.begin(ssid, password);
  Serial.println("\nVerbindungsaufbau mit WLAN...");

  int versuche = 0;
  while(WiFi.status() != WL_CONNECTED && versuche < 20) {
    delay(500);
    Serial.print(".");
    versuche++;
  }

  if(WiFi.status() == WL_CONNECTED) {
    Serial.println("\nErfolgreich verbunden!");
    Serial.print("IP-Adresse: ");
    Serial.println(WiFi.localIP());

    configTzTime(timezone, ntpServer1, ntpServer2);
    Serial.println("Zeitsynchronisation gestartet...");

    if(!MDNS.begin("esp32")) {
      Serial.println("mDNS Fehler!");
    } else {
      Serial.println("mDNS gestartet: http://esp32.local");
    }

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      String html = FPSTR(index_html);
      html.replace("%COLOR%", "#90EE90");
      html.replace("%STATUS%", "VERBUNDEN");
      html.replace("%IP%", WiFi.localIP().toString());
      html.replace("%MOTOR_STATUS%", 
        String(motorActive ? "AKTIV" : "INAKTIV") + 
        " (" + currentDirection + ", " + 
        String(currentSpeed) + "%)");
      request->send(200, "text/html", html);
    });

    server.on("/zeit", HTTP_GET, [](AsyncWebServerRequest *request){
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        request->send(500, "text/plain", "Zeitfehler");
        return;
      }
      char zeitStr[64];
      strftime(zeitStr, sizeof(zeitStr), "%d.%m.%Y %H:%M:%S", &timeinfo);
      request->send(200, "application/json", "{\"zeit\":\"" + String(zeitStr) + "\"}");
    });

    server.on("/motor", HTTP_GET, [](AsyncWebServerRequest *request){
      String state = request->arg("state");
      String direction = request->arg("direction");
      int speed = request->arg("speed").toInt();
      
      speed = constrain(speed, 0, 100);
      
      if(state == "start" && (direction == "links" || direction == "rechts")) {
        controlMotor(state, direction, speed);
        request->send(200, "text/plain", "OK");
      } 
      else if(state == "stop") {
        controlMotor(state, direction, 0);
        request->send(200, "text/plain", "OK");
      }
      else {
        request->send(400, "text/plain", "Ungültige Parameter");
      }
    });

    server.on("/motorStatus", HTTP_GET, [](AsyncWebServerRequest *request){
      String json = String("{\"state\":\"") + (motorActive ? "AKTIV" : "INAKTIV") + "\",";
      json += "\"direction\":\"" + currentDirection + "\",";
      json += "\"speed\":" + String(currentSpeed) + "}";
      request->send(200, "application/json", json);
    });

    server.on("/runtime", HTTP_GET, [](AsyncWebServerRequest *request){
  if(motorActive) {
    unsigned long runtime = millis() - motorStartTime;
    unsigned long seconds = runtime / 1000;
    unsigned long minutes = seconds / 60;
    unsigned long hours = minutes / 60;
    seconds %= 60;
    minutes %= 60;
    
    String json = String("{\"h\":") + hours + ",\"m\":" + minutes + ",\"s\":" + seconds + "}";
    request->send(200, "application/json", json);
  } else {
    request->send(200, "application/json", "{\"h\":0,\"m\":0,\"s\":0}");
  }
});

    server.onNotFound([](AsyncWebServerRequest *request){
      request->send(404, "text/plain", "404: Not Found");
    });

    server.begin();
    Serial.println("HTTP Server gestartet!");

  } else {
    Serial.println("\nVerbindung fehlgeschlagen!");
    while(1) delay(1000);
  }
}

void loop() {
  // Eventuelle Hintergrundaufgaben hier einfügen
  delay(1000);
}

config.h

#ifndef CONFIG_H
#define CONFIG_H

// Netzwerkdaten
const char* ssid = "******";
const char* password = "*******";

// H-Brücke Pins
#define RPWM 13
#define R_EN 14
#define R_IS 15
#define LPWM 16
#define L_EN 17
#define L_IS 18

// HTML Template
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
  <title>ESP32 Motorsteuerung</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta charset="UTF-8">
  <style>
    body { 
      font-family: Arial, sans-serif; 
      text-align: center; 
      margin: 0;
      padding: 0;
      background-color: #f0f0f0;
    }
    .header {
      background-color: #4CAF50;
      color: white;
      padding: 20px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    }
    .tab {
      overflow: hidden;
      background-color: #333;
      display: flex;
      justify-content: center;
    }
    .tab button {
      background-color: inherit;
      color: white;
      border: none;
      outline: none;
      cursor: pointer;
      padding: 14px 20px;
      font-size: 16px;
      flex: 1;
      max-width: 200px;
      transition: background-color 0.3s;
    }
    .tab button:hover {
      background-color: #555;
    }
    .tab button.active {
      background-color: #4CAF50;
    }
    .tabcontent {
      display: none;
      padding: 20px;
      animation: fadeEffect 0.5s;
    }
    @keyframes fadeEffect {
      from { opacity: 0; }
      to { opacity: 1; }
    }
    .status-box, .control-box {
      background: white;
      padding: 20px;
      border-radius: 10px;
      margin: 20px auto;
      width: 90%;
      max-width: 500px;
      box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
    input[type="range"] {
      width: 80%;
      margin: 15px 0;
      height: 8px;
      background: #ddd;
      border-radius: 4px;
      -webkit-appearance: none;
    }
    input[type="range"]::-webkit-slider-thumb {
      -webkit-appearance: none;
      width: 20px;
      height: 20px;
      background: #4CAF50;
      border-radius: 50%;
      cursor: pointer;
    }
    button.control-btn {
      margin: 15px;
      padding: 12px 25px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 25px;
      cursor: pointer;
      font-size: 16px;
      transition: all 0.3s ease;
    }
    button.control-btn:hover {
      background-color: #45a049;
      transform: scale(1.05);
    }
    label {
      font-size: 1.1em;
      margin: 10px 0;
      display: inline-block;
    }
    #speedValue {
      font-weight: bold;
      color: #4CAF50;
      font-size: 1.1em;
    }
    .runtime {
      font-size: 1.2em;
      margin: 15px 0;
      color: #333;
    }
  </style>
</head>
<body>
  <div class="header">
    <h1>ESP32 Motorsteuerung</h1>
    <div id="zeit">Lade Uhrzeit...</div>
  </div>

  <div class="tab">
    <button class="tablinks" onclick="openTab(event, 'Status')">Status</button>
    <button class="tablinks" onclick="openTab(event, 'Steuerung')">Manuelle Steuerung</button>
  </div>

  <div id="Status" class="tabcontent">
    <div class="status-box">
      <h3>Systemstatus</h3>
      <p>Verbindung: %STATUS%</p>
      <p>IP: %IP%</p>
      <p>Motorstatus: <span id="motorStatus">%MOTOR_STATUS%</span></p>
      <p class="runtime">Laufzeit: <span id="runtimeStatus">00:00:00</span></p>
    </div>
  </div>

  <div id="Steuerung" class="tabcontent">
    <div class="control-box">
      <div style="margin: 20px 0;">
        <label>Richtung: </label>
        <select id="direction">
          <option value="links">Links</option>
          <option value="rechts">Rechts</option>
        </select>
      </div>

      <div style="margin: 25px 0;">
        <label>Geschwindigkeit: <span id="speedValue">100</span>%</label><br>
        <input type="range" id="speedSlider" min="0" max="100" value="100">
      </div>

      <div>
        <button class="control-btn" onclick="motorStart()">Start</button>
        <button class="control-btn" onclick="motorStop()">Stop</button>
      </div>

      <div class="runtime">
        Laufzeit: <span id="runtimeControl">00:00:00</span>
      </div>
    </div>
  </div>

  <script>
  // Tab-Funktionalität
  function openTab(evt, tabName) {
    const tabcontent = document.getElementsByClassName("tabcontent");
    for (let i = 0; i < tabcontent.length; i++) {
      tabcontent[i].style.display = "none";
    }
    const tablinks = document.getElementsByClassName("tablinks");
    for (let i = 0; i < tablinks.length; i++) {
      tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(tabName).style.display = "block";
    evt.currentTarget.className += " active";
  }
  document.getElementById("Status").style.display = "block";
  document.getElementsByClassName("tablinks")[0].className += " active";

  // Zeitaktualisierung
  function updateZeit() {
    fetch('/zeit')
      .then(response => response.json())
      .then(data => {
        document.getElementById('zeit').innerHTML = data.zeit;
      })
      .catch(error => console.error('Fehler:', error));
    setTimeout(updateZeit, 1000);
  }
  updateZeit();

  // Motorsteuerung
  const speedSlider = document.getElementById('speedSlider');
  const speedValue = document.getElementById('speedValue');
  const directionSelect = document.getElementById('direction');
  
  function motorStart() {
  const speed = speedSlider.value;
  const direction = directionSelect.value;
  fetch(`/motor?state=start&direction=${direction}&speed=${speed}`)
    .then(response => {
      if(response.ok) {
        updateMotorStatus();
        speedSlider.value = speed;
      }
    });
}

  function updateMotorStatus() {
    fetch('/motorStatus')
      .then(response => response.json())
      .then(data => {
        document.getElementById('motorStatus').textContent = 
          `${data.state} (${data.direction}, ${data.speed}%)`;
      });
  }

function updateRuntime() {
  fetch('/motorStatus')
    .then(response => response.json())
    .then(data => {
      if(data.state === "INAKTIV") {
        // Wenn inaktiv, Laufzeit auf 00:00:00 setzen
        document.getElementById('runtimeStatus').textContent = "00:00:00";
        document.getElementById('runtimeControl').textContent = "00:00:00";
      } else {
        // Wenn aktiv, Laufzeit vom Server abfragen
        fetch('/runtime')
          .then(response => response.json())
          .then(data => {
            const runtimeStr = 
              `${data.h.toString().padStart(2,'0')}:` +
              `${data.m.toString().padStart(2,'0')}:` +
              `${data.s.toString().padStart(2,'0')}`;
            document.getElementById('runtimeStatus').textContent = runtimeStr;
            document.getElementById('runtimeControl').textContent = runtimeStr;
          });
      }
    });
}

  function motorStop() {
    fetch('/motor?state=stop')
      .then(response => {
        if(response.ok) updateMotorStatus();
      });
  }

  speedSlider.oninput = function() {
    speedValue.textContent = this.value;
    if(this.value == 0) {
      motorStop();
    } else if(document.getElementById('motorStatus').textContent.includes('AKTIV')) {
      motorStart();
    }
  }

  setInterval(() => {
    updateMotorStatus();
    updateRuntime();
  }, 1000);
  </script>
</body>
</html>
)rawliteral";

#endif

Prima und vielen Dank fürs teilen.