Liebe Community,
ich würde gern einen Rolladen über ein Webinterface steuern, APPfrei sozusagen.
Es soll im WebIF 2 Buttons geben (Up/Down).
Weiterhin gibt es 3 Ausgänge:
1. Relais "Netzteil 12V ein"
2. Relais "Rolladen hoch"
3. Relais "Rolladen runter"
Funktion:
- sobald ein Fahrbefehl ansteht, soll 1. Relais 12 ein kommen u. ca. 0,5 Sek. später entsprechendes Fahrrichtungsrelais
- wenn Fahrbefehl beendet, Richtungsrelais sofort aus, 12V Relais ca. 5 Sek. später aus
- bei Richtungsumkehr (evtl. Feinpositionierung) sollen ca. 0,5 Sek. vergehen, um auf jeden Fall die gleichzeitige Betätigung beider Richtungsrelais zu unterbinden und 1. Relais 12V ein bleibt betätigt (solange nicht mehr als 5 Sek. vergehen), auch wenn hier wieder der Fahrbefehl beendet ist, 5 Sek. später 12V aus (verlängert sich jeweils nach dem letzten Fahrbefehl)
- wenn beide Richtungsbuttons gedrückt werden, bleibt alles aus.
ja, ich bin mir bewusst, ich kann den Rolladen so auch zerstören, natürlich ist hier ein "Sichtfeedback" erforderlich...
Nun zum Detail: Solange ich den Up-Button auf dem Handy im WebIF drücke, soll er fahren, wenn ich los lasse, soll er stoppen...soweit so gut...
Problem:
der Rolladen fährt weiter, wenn:
- man aus Versehen den Home-Button am Handy drückt
- das Handy ausschaltet (gegen den Ausschalter an der Seite kommt)
- plötzlich das WLAN ausfällt oder der Empfang gestört ist)
- der PC plötzlich einen Bluescreen bekommt
- das Netzwerkkabel vom Laptop abzieht
- das WLAN am Laptop durch Knopfdruck ausschaltet
- der Router explodiert
- ein Gauner sich von hinten anschleicht und ALT+F4 drückt... etc. ...
- mir fallen noch weitere 100 Gründe ein, aber diese geschehen eher selten...
Kann man hier eine Funktion einbauen, die überprüft, ob der verbundene Client noch "lebt" ?
Kann man verhindern, dass ein 2. Client parallel im WebIF das Gleiche machen will?
Ich denke in diese Richtungen:
- während der WebIF Button Up/Down gedrückt wird, eine Art WebIF-Ping abfragen, wenn kein Ping zurück kommt, Rolladenstop
- während der WebIF Button Up/Down gedrückt wird, 300ms Fahrbefehl anstehen lassen, aber nach 250ms erneut nachfragen, ob Richtugsbutton noch gedrückt ist, wenn ja wieder 350ms verlängern und wieder nach 250ms gedrückten Button abfragen, Ihr wisst, was ich meine...
ich habe mir schon Gedanken gemacht, komme aber nicht weiter...
- kein 1. Relais "Netzteil 12V ein" eingebunden
- keine Ahnung, wie man hier "Totmannschalter/Heartbeat" - Funktion integrieren kann
- keine Ahnung, wie man die Anzahl der Clienten auf einen beschränkt
der Grundgedanke zu allem ist im Link im Programm enthalten
Danke an Rui Santos
(habe Ihn schon angeschrieben...Antwort:
Unfortunately I don't have any tutorials on that exact subject, but it's definitely possible to implement that exact logic in the arduino code...
Due to time constraints, I also don't do custom projects or consulting at the moment.)
Ich hoffe, Ihr könnt mir helfen?
Vielleicht ist auch der gesamte Lösungsansatz vollkommen falsch für diesen, meinen Zweck?
Vielen Dank im Voraus
hier das bisherige Arduino Programm:
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.co…outputs-momentary-switch/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "***";
const char* password = "***";
const int outputUP = 1;
const int outputDOWN = 2;
// HTML web page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>Balkonrolladen</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial;
text-align: center;
margin: 0% auto;
padding-top: 1%;
padding-bottom: 1%;
background-color: #666666;
}
.button {
width: 85%;
height: 85%;
font-size: 300%;
text-align: center;
line-height: 3;
outline: none;
color: #fff;
background-color: #2f4468;
border: none;
border-radius: 5px;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.button:active {
background-color: #7f2e45;
}
</style>
</head>
<body>
<h1>Balkonrolladen</h1>
<button class="button buttonUP" onmousedown="toggleCheckbox('UPon');" ontouchstart="toggleCheckbox('UPon');" onmouseup="toggleCheckbox('UPoff');" ontouchend="toggleCheckbox('UPoff');">hoch</button>
<br><br>
<button class="button buttonDOWN" onmousedown="toggleCheckbox('DOWNon');" ontouchstart="toggleCheckbox('DOWNon');" onmouseup="toggleCheckbox('DOWNoff');" ontouchend="toggleCheckbox('DOWNoff');">runter</button>
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/" + x, true);
xhr.send();
}
</script>
</body>
</html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("ESP IP Address: http://");
Serial.println(WiFi.localIP());
pinMode(outputUP, OUTPUT);
digitalWrite(outputUP, LOW);
pinMode(outputDOWN, OUTPUT);
digitalWrite(outputDOWN, LOW);
// Send web page to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html);
});
// Receive an HTTP GET request UP HIGH
server.on("/UPon", HTTP_GET, [] (AsyncWebServerRequest * request) {
digitalWrite(outputDOWN, LOW);
digitalWrite(outputUP, HIGH);
request->send(200, "text/plain", "ok");
});
// Receive an HTTP GET request UP LOW
server.on("/UPoff", HTTP_GET, [] (AsyncWebServerRequest * request) {
digitalWrite(outputUP, LOW);
request->send(200, "text/plain", "ok");
});
// Receive an HTTP GET request DOWN HIGH
server.on("/DOWNon", HTTP_GET, [] (AsyncWebServerRequest * request) {
digitalWrite(outputUP, LOW);
digitalWrite(outputDOWN, HIGH);
request->send(200, "text/plain", "ok");
});
// Receive an HTTP GET request DOWN LOW
server.on("/DOWNoff", HTTP_GET, [] (AsyncWebServerRequest * request) {
digitalWrite(outputDOWN, LOW);
request->send(200, "text/plain", "ok");
});
server.onNotFound(notFound);
server.begin();
}
void loop() {
}