/* * Skrift – ESP MOSFET-Trigger („Stromzufuhr aktivieren") * =========================================================================== * Kleiner WLAN-Empfänger für einen N-Kanal-MOSFET (Low-Side-Schalter). * AutoRecover ruft bei jedem Plotter-Recover-Fenster den Endpunkt /trigger auf; * der ESP schaltet dann den MOSFET (GPIO) und aktiviert damit die Stromzufuhr. * * Läuft auf ESP8266 (NodeMCU/Wemos D1 mini) UND ESP32 – die passenden Bibliotheken * werden über die Board-Auswahl in der Arduino IDE automatisch gewählt. * * Endpunkte (HTTP GET, Port 80): * / Statusseite (Text) – Pin-Zustand, Uptime, IP * /trigger MOSFET aktivieren (Puls von PULSE_MS ms; 0 = dauerhaft an) * /on MOSFET dauerhaft AN * /off MOSFET AUS * Optionaler Schutz: ist AUTH_TOKEN gesetzt, muss jeder Aufruf ?key= * mitschicken (muss zu esp_key in der AutoRecover-config.json passen). * * Verdrahtung (Low-Side, N-Kanal-Logic-Level-MOSFET, z. B. IRLZ44N / AO3400-Modul): * ESP GPIO (MOSFET_PIN) ─► Gate (ggf. 100–220 Ω in Reihe) * Gate ─► 100 kΩ ─► GND (Pulldown, damit der MOSFET beim Booten sicher AUS ist) * Last(+) an Versorgung+, Last(−) ─► Drain ; Source ─► GND (gemeinsame Masse!) * GND von ESP und Last-Versorgung verbinden. * ACTIVE_HIGH=true: GPIO HIGH = MOSFET leitet = „Strom an". */ #if defined(ESP32) #include #include WebServer server(80); #else #include #include ESP8266WebServer server(80); #endif // ── Konfiguration ────────────────────────────────────────────────────────── const char* WIFI_SSID = "DEIN_WLAN"; const char* WIFI_PASS = "DEIN_WLAN_PASSWORT"; // GPIO, an dem das MOSFET-Gate hängt. ESP8266: 5 = D1 (Wemos/NodeMCU). ESP32: z. B. 23. const int MOSFET_PIN = 5; const bool ACTIVE_HIGH = true; // true: HIGH = MOSFET an ("Strom an") const unsigned long PULSE_MS = 3000; // /trigger: Dauer der Aktivierung (0 = latch, bleibt an) // Optionaler Schutz. Leer = kein Schutz. Muss zu esp_key in der config.json passen. const char* AUTH_TOKEN = ""; // Optionale feste IP (empfohlen, damit AutoRecover eine stabile Adresse hat). // Auf true setzen und Werte anpassen; sonst DHCP. const bool USE_STATIC_IP = false; IPAddress IP_ADDR (192, 168, 2, 50); IPAddress IP_GATE (192, 168, 2, 1); IPAddress IP_MASK (255, 255, 255, 0); IPAddress IP_DNS (192, 168, 2, 1); // ── Zustand ──────────────────────────────────────────────────────────────── bool mosfetAn = false; bool pulsAktiv = false; unsigned long pulsBis = 0; void mosfetSchreiben(bool an) { mosfetAn = an; digitalWrite(MOSFET_PIN, (an == ACTIVE_HIGH) ? HIGH : LOW); } bool autorisiert() { if (strlen(AUTH_TOKEN) == 0) return true; return server.hasArg("key") && server.arg("key") == AUTH_TOKEN; } void sendeStatus(const char* hinweis) { String s = String(hinweis) + "\n"; s += "mosfet="; s += (mosfetAn ? "an" : "aus"); s += "\n"; s += "puls="; s += (pulsAktiv ? "aktiv" : "-"); s += "\n"; s += "ip="; s += WiFi.localIP().toString(); s += "\n"; s += "uptime_s="; s += String(millis() / 1000); s += "\n"; server.send(200, "text/plain; charset=utf-8", s); } void handleRoot() { sendeStatus("Skrift ESP MOSFET-Trigger"); } void handleTrigger() { if (!autorisiert()) { server.send(403, "text/plain", "verboten\n"); return; } mosfetSchreiben(true); if (PULSE_MS > 0) { // getimter Puls pulsAktiv = true; pulsBis = millis() + PULSE_MS; sendeStatus("OK trigger (puls)"); } else { // dauerhaft an (latch) pulsAktiv = false; sendeStatus("OK trigger (latch)"); } } void handleOn() { if (!autorisiert()) { server.send(403, "text/plain", "verboten\n"); return; } pulsAktiv = false; mosfetSchreiben(true); sendeStatus("OK on"); } void handleOff() { if (!autorisiert()) { server.send(403, "text/plain", "verboten\n"); return; } pulsAktiv = false; mosfetSchreiben(false); sendeStatus("OK off"); } void setup() { Serial.begin(115200); pinMode(MOSFET_PIN, OUTPUT); mosfetSchreiben(false); // sicher AUS beim Start if (USE_STATIC_IP) WiFi.config(IP_ADDR, IP_GATE, IP_MASK, IP_DNS); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); Serial.print("Verbinde WLAN"); while (WiFi.status() != WL_CONNECTED) { delay(400); Serial.print("."); } Serial.println(); Serial.print("Verbunden. IP: "); Serial.println(WiFi.localIP()); server.on("/", handleRoot); server.on("/trigger", handleTrigger); server.on("/on", handleOn); server.on("/off", handleOff); server.onNotFound([]() { server.send(404, "text/plain", "nicht gefunden\n"); }); server.begin(); Serial.println("HTTP-Server auf Port 80 gestartet."); } void loop() { server.handleClient(); // WLAN bei Bedarf neu verbinden (Plotter läuft lange). static unsigned long letzteWlanPruefung = 0; if (millis() - letzteWlanPruefung > 10000) { letzteWlanPruefung = millis(); if (WiFi.status() != WL_CONNECTED) WiFi.begin(WIFI_SSID, WIFI_PASS); } // Getimten Puls beenden. if (pulsAktiv && (long)(millis() - pulsBis) >= 0) { pulsAktiv = false; mosfetSchreiben(false); } }