Files
skrift-auto-recover/esp/skrift_mosfet.ino
s4luorth 16d603b19f AutoRecover: bei Recover-Fenster ESP-MOSFET triggern („Stromzufuhr aktivieren")
Erkennt AutoRecover das Plotter-Recover-Fenster, ruft es jetzt zuerst
einen ESP auf (HTTP /trigger) und klickt danach „Recover". Der ESP
schaltet einen MOSFET und aktiviert damit die Stromzufuhr. Konfiguration
über config.json (esp_url/esp_path/esp_key/esp_timeout) bzw. Env-Vars;
ohne esp_url unverändertes Verhalten.

Neu: esp/skrift_mosfet.ino (ESP8266/ESP32-Firmware, WLAN + HTTP-Server,
Endpunkte /trigger /on /off, getimter Puls oder Latch) + esp/README.md
(Verdrahtung/Flashen) + config.example.json.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-21 20:20:36 +02:00

137 lines
5.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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=<token>
* 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 <WiFi.h>
#include <WebServer.h>
WebServer server(80);
#else
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
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);
}
}