Statuswebseite trotz if Abfrage mit delay?

Hallo zusammen,

ich mache gerade meine ersten Gehversuche mit einem ESP8266.
Natürlich bin ich noch sehr unbeholfen, lese viel und versuche andere Codes zu verstehen.

Aktuell arbeite ich mit Sonoff S20 Steckdosen, welche einen ESP8266 verbaut haben.

Die Steckdose ist soweit umprogrammiert und soll später maleingesteckt werden und dann mittels Ping das Vorhandensein einer IP abfragen. Ist der Ping erfolgreich, so soll die Steckdose angeschaltet werden.
Ist sie nicht erreichbar, bleibt das Relais aus.
Das funktioniert soweit auch schon mit folgendem Code:

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>

const char* ssid = "...";  //Name des bestehenden Wlan Netzwerks
const char* password = "...";  //Passwort des bestehenden Wlan Netzwerks

const IPAddress ThermostatMaster(192, 168, 10, 10); //IP-Adresse des Thermostat Masters 

int Relais=12; // Das Wort „Relais“ steht jetzt für Pin „12“ GPIO12. Daran sind das Relais und die blaue LED parallel angeschlossen.
int PowerLED=13; // Das Wort „PowerLED“ steht jetzt für Pin „13“ GPIO13. Daran ist die grüne LED angeschlossen.


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

  // Start der WLan Verbindung

  Serial.println();
  Serial.println("Connecting to WiFi");
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");

  pinMode(Relais, OUTPUT); // Pin 12 (Pin „Relais“) ist ein Ausgang.  
  pinMode(PowerLED, OUTPUT); // Pin 13 (Pin „PowerLED“) ist ein Ausgang.
  }

  Serial.println();
  Serial.print("WiFi connected with ip ");  
  Serial.println(WiFi.localIP());

  Serial.print("Pinging ip ");
  Serial.println(ThermostatMaster);
}

void loop() { 
    //Ist-Dann Schleife
  if(Ping.ping(ThermostatMaster)) 
  {
    digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
    digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
    delay(10000);
  } 
  
  else 
  {
    digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
    digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
    delay(10000);
  }
  }

Aktuell steht das delay testweise noch auf 10 Sekunden.
Später mal, wenn der Test erfolgreich ist, wird der auf 5 Minuten hochgesetzt, damit ich bei 3 Steckdosen nicht mein Netz nur durch Pings verseuche.

Das würde ja so wie oben alles schon funktionieren.

Genial wäre jetzt, wenn ich, da die Steckdose ja schon im Wlan ist, die IP eingeben könnte und die Steckdose öffnet dann eine ganz einfache Webseite auf der steht "Die Steckdose ist angeschaltet" oder "Die Steckdose ist ausgeschaltet"

Das jetzt vereinfacht beschrieben.
Mein bisheriges Problem ist der delay und die Abfrage meiner Meinung nach.
Durch das delay bremse ich doch den 8266 ein und er ist nicht empfänglich für Webseitenzugriffe oder sehe ich das falsch?

Versucht habe ich mich da mit folgendem Code den ich so abgewandelt habe.

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
#include <ESP8266WebServer.h>

ESP8266WebServer Webserver(80);

const char* ssid = "...";  //Name des bestehenden Wlan Netzwerks
const char* password = "...";  //Passwort des bestehenden Wlan Netzwerks

const IPAddress ThermostatMaster(192, 168, 10, 10); //IP-Adresse des Thermostat Masters

int Relais=12; // Das Wort „Relais“ steht jetzt für Pin „12“ GPIO12. Daran sind das Relais und die blaue LED parallel angeschlossen.
int PowerLED=13; // Das Wort „PowerLED“ steht jetzt für Pin „13“ GPIO13. Daran ist die grüne LED angeschlossen.


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

  // Start der WLan Verbindung

  Serial.println();
  Serial.println("Connecting to WiFi");
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");

  pinMode(Relais, OUTPUT); // Pin 12 (Pin „Relais“) ist ein Ausgang.  
  pinMode(PowerLED, OUTPUT); // Pin 13 (Pin „PowerLED“) ist ein Ausgang.
  }

  Serial.println();
  Serial.print("WiFi connected with ip ");  
  Serial.println(WiFi.localIP());

  Serial.print("Pinging ip ");
  Serial.println(ThermostatMaster);

  Webserver.begin();  //Starten des Webservers
}


void loop() { 

    Webserver.handleClient();
    
    //Ist-Dann Schleife
  if(Ping.ping(ThermostatMaster)) 
  {
    digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
    digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.

    Webserver.on("/", handleRoot_an);

 
    delay(10000);
  } 
  
  else 
  {
    digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
    digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.

    Webserver.on("/", handleRoot_aus);

    delay(10000);
  }
  }


void handleRoot_an() 
{
  Webserver.send(200, "text/html", "<html> <h2>Thermostat Status</h2><h3><b>an</b></h3> </html>");  //hier HTML Code einfügen
}

void handleRoot_aus() 
{
  Webserver.send(200, "text/html", "<html> <h2>Thermostat Status</h2><h3><b>aus</b></h3> </html>");  //hier HTML Code einfügen
}

Meine Frage an Euch ist jetzt ob das überhaupt geht wie ich mir das vorstelle und wenn es gehen kann, würde ich mich über Hilfe freuen.

FNBalu:
Meine Frage an Euch ist jetzt ob das überhaupt geht wie ich mir das vorstelle und wenn es gehen kann, würde ich mich über Hilfe freuen.

Mit dem Sketch nicht!!

Webserver.on("/", handleRoot_an);

Darf nicht im loop stehen.
Schau dir die mitgelieferten Beispiele an.

delay(10000);

Hat in enem Webserver nichts zu suchen.

Gruß Fips

FNBalu:
............
Durch das delay bremse ich doch den 8266 ein und er ist nicht empfänglich für Webseitenzugriffe oder sehe ich das falsch?

Einbremsen ist nicht ganz richtig, der macht nichts mehr außer die Zeit zählen und Strom verbrauchen. Wenn dann die Endversion auf 5 Minuten steht passiert in den 5 Minuten gar nichts.

"Blink without delay" oder der "Nachtwächter" must du googeln.

Nabend. Danke für Eure Antworten.

Zu Webserver.on, laut Beispielscrpten war das auch immer unten, oder halt hinter den Schleifen.
Ich sah allerdings keine Möglichkeit wie ich sonst auf 2 verschiedene Infos komme.

Und das es sich mit dem delay beißt, dachte ich mir leider auch schon.

Ich werde mir blink without delay mal ansehen. Danke für den Hinweis

FNBalu:
Zu Webserver.on, laut Beispielscrpten war das auch immer unten, oder halt hinter den Schleifen.
Ich sah allerdings keine Möglichkeit wie ich sonst auf 2 verschiedene Infos komme.

Welche Beispiele ??

Hier bestimmt nicht!!

Gruß Fips

Das habe ich auch nicht gesagt, das es davon kommt.
Ich klickte mich so durchs Netz und fand folgenden Code.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

MDNSResponder mdns;

void setup() {
  WiFi.softAP("esp8266_ap", "michaelsarduino");
  Serial.begin(115200);
  if (mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("MDNS responder started");
  }
  server.on("/", handleRoot);
  
  server.on("/inline", [](){
    server.send(200, "text/plain", "Funktioniert");
  });
  
  server.begin();
}

void loop() {
  server.handleClient();
  mdns.update();
}

void handleRoot() {
   server.send(200, "text/html", "<html> <h2>ESP NETWORK</h2> schamlose Eigenwerbung: <b>michaelsarduino.blogspot.de/</b> </html>");
}

Quelle: michaelsarduino: ESP 8266 als Access Point

Ganz einfach. Wie gesagt ich bin neu dabei und versuche erstmal zu cheken was überhaupt geht.
Das ich so etwas nie frei Schnauze am Anfang kann sollte eigentlich klar sein.

Nachher in meiner Pause (Nachtschicht) werde ich mal versuchen den Code mit meinem Ping zusammenzuführen.

Nachtschicht ist doof!
Ich kenn das zum Glück nur von Montag bis Freitag.
Schau dir vorrangig die mitgelieferten Beispiele an.

Gruß Fips

Also...

Ich habe versucht meinen Code mit dem Nachtwächter zu vereinen.

Das sieht aus wie folgt:

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>

const char* ssid = "...";  //Name des bestehenden Wlan Netzwerks
const char* password = "...";  //Passwort des bestehenden Wlan Netzwerks

const IPAddress ThermostatMaster(192, 168, 10, 10); //IP-Adresse des Thermostat Masters 

int Relais=12; // Das Wort „Relais" steht jetzt für Pin „12" GPIO12. Daran sind das Relais und die blaue LED parallel angeschlossen.
int PowerLED=13; // Das Wort „PowerLED" steht jetzt für Pin „13" GPIO13. Daran ist die grüne LED angeschlossen.

int RelaisStatus = LOW;

unsigned long Relais_timestore;  // Variable Speicher für Systemzeit.


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

  // Start der WLan Verbindung

  Serial.println();
  Serial.println("Connecting to WiFi");
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");

  pinMode(Relais, OUTPUT); // Pin 12 (Pin „Relais") ist ein Ausgang.  
  pinMode(PowerLED, OUTPUT); // Pin 13 (Pin „PowerLED") ist ein Ausgang.
  }

  Serial.println();
  Serial.print("WiFi connected with ip ");  
  Serial.println(WiFi.localIP());

  Serial.print("Pinging ip ");
  Serial.println(ThermostatMaster);
}

void loop() {
  if (RelaisStatus == LOW) {
    if (millis() - Relais_timestore> 3 ) { //Später mal 250
      if(Ping.ping(ThermostatMaster)) {  //ESP8266-01 Pingen ob er verfügbar ist.
        digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
        digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
        Relais_timestore = millis();
        RelaisStatus = HIGH;
        }

 else {
        digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
        digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
        RelaisStatus = LOW;
      }
    }
  }
  }

Zur Erklärung meinerseits.
Da eine Stunde 1000 millis hierbei hat, habe ich, da bei der echten zeit 3600 Sekunden vorliegen, vorerst den Wert auf 3 gesetzt. 3,6x3 sind ca 10 Sekunden, was zu testen genügt.

Im Nachtwächter steht ja auch
if (millis() - Relais_timestore> 3 ), da ich aber die Ping Option als nächstes benötige, habe ich dies in einer weiteren if Schleife erledigt.

Ist das der Fall, dann soll er die Relais schalten etc.

Wenn ich das Ganze laufen lasse, so bleibt alles auch auf Grün stehen wie gewünscht, bis der Ping erfolgreich ist. Ist der Ping erfolgreich schaltet alles um.
Also funktioniert der if Code grundsätzlich.

Das else ist mein problem.
Egal was ich bisher versucht habe, da reichen die Positionen von {} ja schon zu aus, ich komme nicht mehr in den Ursprungszustand zurück.
Sprich obwohl der Ping ins leere läuft, schaltet nichts zurück.

Was ist da falsch??

Und gleich dazu gefragt. Da ich dann ja die Variable HIGH/LOW habe, kann diese doch, wenn die Grundfunktion steht in den Webserver übergeben werden oder sehe ich da was falsch??

Da eine Stunde 1000 millis hierbei hat, habe ich, da bei der echten zeit 3600 Sekunden vorliegen, vorerst den Wert auf 3 gesetzt. 3,6x3 sind ca 10 Sekunden, was zu testen genügt.

wohl kaum.

Eine Sekunde hat 1000 millis
Eine Minute hat 60000 millis
eine Stunde hat 3600000 millis

dein Vergleich auf > 3 ist somit quasi sofort true ... das ist nach 3 millisekunden so weit.

Ergänze doch deinen Sketch um Serial.print Ausgaben damit du genau siehst, was dein Sketch macht!!!

Oh man.
Klar. ich war dadurch die ganze Zeit eh schon irritiert.

Ich habe den satz 1h Wachmann entspricht 1 Sekunde Arduino komplett falsch interpretiert.

Ich habe die 1000 darin, was ja die Sekunde ist als Umrechnungsfaktor der Stunde genommen.
Oh man

So, entschuldigt bitte das Missverständnis.

Ich habe jetzt 10000 angegeben wegen der 10 Sekunden. Es geht nur immer noch nicht

FNBalu:
Es geht nur immer noch nicht

Eine wirklich sehr treffende Fehlerbeschreibung!!

Ich vermute Strom kaputt oder Sid macht ärger.

Gruß Fips

Und ich dachte die Fehlerbeschreibung von heute morgen wär noch aktuell.

Ich habe lediglich die Zeit angepasst.

Also er startet und wartet.
Ist der PingMaster an, so schaltet er durch.

Läuft der Ping wieder ins leere, so wird nicht mehr zurück geschaltet

void loop() {
if (RelaisStatus == LOW) { // wenn der Status High ist kommt er hier nicht rein
if (millis() - Relais_timestore> 3 ) { //Später mal 250
if(Ping.ping(ThermostatMaster)) { //ESP8266-01 Pingen ob er verfügbar ist.
digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
Relais_timestore = millis();
RelaisStatus = HIGH;
}

else {
digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
RelaisStatus = LOW;
}
}
}
}

Wenn du in der Arduino IDE die automatische Formatierung nutzt (STRG+T) siehst du es besser.

void loop() {
  if (RelaisStatus == LOW) {
  | if (millis() - Relais_timestore > 3 ) { //Später mal 250
  |   if (Ping.ping(ThermostatMaster)) { //ESP8266-01 Pingen ob er verfügbar ist.
  |     digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
  |     digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
  |     Relais_timestore = millis();
  |     RelaisStatus = HIGH;
  |   }
  |   else {
  |     digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
  |     digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
  |     RelaisStatus = LOW;
  |   }
  | }
  }
}

Gruß Fips

Demnach bräuchte ich für meine Zwecke die rot angemarkerte if Anweisung ja gar nicht, da er es ja immer checken soll, wenn die Zeit abgelaufen ist.

Sinngemäß if timestore, dann Ping, ist der erfolgreich, dann anschalten, Status schreiben (für die Webseite später)

Else abschalten und Status schreiben

Sodele.

Danke erst mal für die Hilfe.
Ich habe heute Morgen das Ganze in Code packen können, bzw die eine if Schleife nur entfernt und die Grundfunktion ist gegeben.

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>

const char* ssid = "FN-Friend";  //Name des bestehenden Wlan Netzwerks
const char* password = "!Friends@BiWa";  //Passwort des bestehenden Wlan Netzwerks

const IPAddress ThermostatMaster(192, 168, 10, 10); //IP-Adresse des Thermostat Masters

int Relais = 12; // Das Wort „Relais" steht jetzt für Pin „12" GPIO12. Daran sind das Relais und die blaue LED parallel angeschlossen.
int PowerLED = 13; // Das Wort „PowerLED" steht jetzt für Pin „13" GPIO13. Daran ist die grüne LED angeschlossen.

int RelaisStatus = LOW;

unsigned long Relais_timestore;  // Variable Speicher für Systemzeit.


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

  // Start der WLan Verbindung

  Serial.println();
  Serial.println("Connecting to WiFi");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");

    pinMode(Relais, OUTPUT); // Pin 12 (Pin „Relais") ist ein Ausgang.
    pinMode(PowerLED, OUTPUT); // Pin 13 (Pin „PowerLED") ist ein Ausgang.
  }

  Serial.println();
  Serial.print("WiFi connected with ip ");
  Serial.println(WiFi.localIP());

  Serial.print("Pinging ip ");
  Serial.println(ThermostatMaster);
}

void loop() {

  if (millis() - Relais_timestore > 10000 ) { //Später mal 6000000
    if (Ping.ping(ThermostatMaster)) { //ESP8266-01 Pingen ob er verfügbar ist.
      digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
      digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
      Relais_timestore = millis();
      RelaisStatus = HIGH;
    }

    else {
      digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
      digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
      RelaisStatus = LOW;
    }
  }
}

Ich habe auch schon angefangen die Weserver Geschichte mir anzusehen, aber mir raucht der Kopf.
Da scheint vieles bei zu sein, was ich nicht benötige.

Idealerweise hätte ich gerne ganz banal eine Stausabfrage.
Ich übergebe die Stausänderungen ja in die Variable RelaisStatus.

Nach meinem Verständnis muss ich jetzt die Webseitengeschichte haben und dann mit einer IF Abfrage arbeiten.
Ist der Status High, dann schreibe "Die Steckdose ist angeschaltet"
Ansonsten schreibe "Die Steckdose ist ausgeschaltet"

if else dafür.

Sehe ich das richtig?
Gibt es da vielleicht schon Beispiele von Projekten wovon Ihr wisst? Ich möchte nicht schalten, lediglich abfragen

Eine LED schalten kann ich mittlerweile und verstehe das, aber Webseiten... Puh :frowning:

So, hier noch mal für Nachahmer der Code den ich nutze.

Für mich reicht das so.

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <WiFiServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80); //Webserver Port
MDNSResponder mdns;

const char* ssid = "xxx";  //Name des bestehenden Wlan Netzwerks
const char* password = "xxx";  //Passwort des bestehenden Wlan Netzwerks

const IPAddress ThermostatMaster(192, 168, 10, 10); //IP-Adresse des Thermostat Masters

int Relais = 12; // Das Wort „Relais" steht jetzt für Pin „12" GPIO12. Daran sind das Relais und die blaue LED parallel angeschlossen.
int PowerLED = 13; // Das Wort „PowerLED" steht jetzt für Pin „13" GPIO13. Daran ist die grüne LED angeschlossen.

int RelaisStatus = LOW;

unsigned long Relais_timestore;  // Variable Speicher für Systemzeit.


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

  // Start der WLan Verbindung

  Serial.println();
  Serial.println("Connecting to WiFi");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");

    pinMode(Relais, OUTPUT); // Pin 12 (Pin „Relais") ist ein Ausgang.
    pinMode(PowerLED, OUTPUT); // Pin 13 (Pin „PowerLED") ist ein Ausgang.
  }

  Serial.println();
  Serial.print("WiFi connected with ip ");
  Serial.println(WiFi.localIP());

  Serial.print("Pinging ip ");
  Serial.println(ThermostatMaster);


  if (mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "Funktioniert");
  });

  server.begin();  //Starten des Webservers
}

void loop() {

  if (millis() - Relais_timestore > 10000 ) { //10 Minuten
    if (Ping.ping(ThermostatMaster)) { //ESP8266-01 Pingen ob er verfügbar ist.
      digitalWrite(Relais, HIGH); // Schalte das Relais und die blaue LED an.
      digitalWrite(PowerLED, HIGH); // Schalte die Grüne LED aus.
      Relais_timestore = millis();
      RelaisStatus = HIGH;
    }

    else {
      digitalWrite(Relais, LOW); // Schalte das Relais und die blaue LED aus.
      digitalWrite(PowerLED, LOW); // Schalte die Grüne LED an.
      RelaisStatus = LOW;
    }
  }

  server.handleClient();
  mdns.update();
}

void handleRoot() 
{
 if (RelaisStatus == LOW) {
  server.send(200, "text/html", "<html> <title>Steckdose 1</title> <p> <h1>Status Steckdose <b>1</b></h1><h2><b>Die Steckdose 1 ist <font color=red>ausgeschaltet</font>, da der Thermostatmaster nicht erreicht wird.</b></h2> </html>");  //hier HTML Code einfügen
}
else {
  server.send(200, "text/html", "<html> <title>Steckdose 1</title> <p> <h1>Status Steckdose <b>1</b></h1><h2><b>Die Steckdose 1 ist <font color=green>angeschaltet</font>, da der Thermostatmaster erreichbar ist.</b></h2> </html>");  //hier HTML Code einfügen
}  
}

Unten frage ich dann noch mal den Status des Relais ab und wenn es LOW ist, dann kommt die erste HTML Zeile, ansonsten die Zweite.

Das reicht mir so hin wie es dargestellt wird.

Entsprechend rot und ausgeschaltet dann der andere Text.

Danke für die Hilfe