zusammenfassen von zwei Sketchen für ESP (D1)

Moin
Ich habe vor 10 Jahren ein Smart Home gebaut, das immer noch die ein oder andere Verfeinerung braucht.
Aktuell soll mein Briefkasten schlau werden.
Zum einen möchte ich die integrierte Hausnummer indirekt per LED beleuchten, zum anderen möchte ich erfahren wenn ein Brief da ist. Mein LCN Hausbus kann über HTTP Requests komunizieren.
Die einzelnen Funktionen habe ich bereits zum laufen bekommen. (Beispiele sind toll)
Ich kann mit folgendem Code über eine URL einen Ausgang An und Aus schalten.

/*
 *    Der Server arbeitet abhängig vom HTTP Request
 *    http://server_ip/gpio/0 will set the GPIO2 low,
 *    http://server_ip/gpio/1 will set the GPIO2 high
 */

#include <ESP8266WiFi.h>

const char* ssid = "WLAN";
const char* password = "123456789";

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  // prepare GPIO2
  pinMode(4, OUTPUT);
  digitalWrite(4, 0);
  
  // Connect to WiFi network
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  // Start the server
  server.begin();

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  client.flush();
  
  // Match the request
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    client.stop();
    return;
  }

  // Set GPIO2 according to the request
  digitalWrite(4, val);
  
  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nHausnummer ist jetzt ";
  s += (val)?"beleuchtet":"unbeleuchtet";
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}

Als zweiten Sketch habe ich quasi genau die gegenrichtung gebastelt.
Der folgende Sketch ruft eine spezielle URL auf, die ein Relais für ein Terassenlicht ein und wieder ausschaltet.

//es wird  Relais2 an M 200 per PCHK geschaltet
// ein Befehl pro einganggsänderung
// Eingang Pin 5 mit Pulldown; relais aus wenn Pin 1 
// 
#include <ESP8266WiFi.h>
const char* ssid     = "WLAN";
const char* password = "123456789";
const char* host = "192.168.178.1";
const int buttonPin = 5;
int zustandan; 
int zustandneu;
int buttonState;
int buttondown = 0;

void setup() {
//  Serial.begin(115200);
  pinMode(buttonPin, INPUT);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(5);
    }
}
void loop() {
  buttonState = digitalRead(buttonPin);
   if (buttonState == HIGH) {  
   buttondown = 2;
   }else{
   buttondown = 4;
   }
  WiFiClient client;
  const int httpPort = 8000;
  if (!client.connect(host, httpPort)) {
  }
  zustandneu = zustandan + buttondown;
  if (zustandneu == 2) {  
  client.print(String("GET ") + "/pck?c=%3EM000200.RL-1------" + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  zustandan = 1;
  }
  if (zustandneu == 5) {  
  client.print(String("GET ") + "/pck?c=%3EM000200.RL-0------" + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  zustandan = 0;
  }
//Serial.print("buttondown ");
//Serial.println(buttondown);
  }

Meine WLan Daten sind hier ja sicherlich gut aufgehoben :wink: Spaß

Meine Frage in die Gruppe ist:
Kann ich diese beiden Sketche dazu bringen zweitgleich auf einen ESP (LoLin D1) zu laufen?
Wie kann ich das ganze in einen Sketch bringen? Oder widerspricht sich das rein und das raus?
Ich habe viele Beispiele gefunden mit einzelnen Funktionen, die ich auch oft zu meinen Zwecken umbauen kann, aber aus zwei mach eins habe ich noch nicht hinbekommen.
Ich würde mich über eure Hilfe freuen.

Nette Grüsse vom Weserdeich

Siebo

Ohne das ich jetzt groß in deine Sketche eingestiegen bin, sieh dir mal die Seite von fips an. Der ist auch hier im Forum aktiv.

Da kannst du dein Projekt sicher einfach lösen und alle möglichen Funktionen kombinieren.
Zusätzlich kannst du die ESP8266 (Lolin Wemos D1 mini) mit UDP unter einander verbinden und einfach Daten austauschen.

Kann ich diese beiden Sketche dazu bringen zweitgleich auf einen ESP (LoLin D1) zu laufen?
Wie kann ich das ganze in einen Sketch bringen? Oder widerspricht sich das rein und das raus?
Ich habe viele Beispiele gefunden mit einzelnen Funktionen, die ich auch oft zu meinen Zwecken umbauen kann, aber aus zwei mach eins habe ich noch nicht hinbekommen.

ja das geht. ich würde aber zunächst die zwei Sketche herichten, die Sachen aus der loop in eigene Funktionen, den webserver auf Basis Beispiel ESP8266Webserver | HelloServer aufbauen und dann dann erst zusammenfügen.

hier habe ich ein Beipsiel für einen kombinierten Webserver und Webclient auf einem ESP
http://werner.rothschopf.net/201809_arduino_esp8266_server_client_0.htm

Moin
Danke für die schnelle Antwort
die Funktion war das was mair gefehlt hat.
Der Umbau zu HelloServer habe ich gelassen, da ich keine html Seite brauche, sondern nur eine auswertung der Abfrage in Form von "192.168.178.1/GPIO/1" oder "0". Das Beispiel ist sehr umfangreich. echt schick, aber aktuell noch nichts für mich.
Ich habe jetzt folgendes zusammengeschustert und habe bisher damit auch Erfolg:

/*    http://server_ip/gpio/0 AUS http://server_ip/gpio/1 EIN
 */

#include <ESP8266WiFi.h>

const char* ssid = "WLAN";
const char* password = "987654321";
const char* host = "192.168.178.1";
const int buttonPin = 5;
const int ledpin = 4;
int aktiv; 
int neu;
int klappe;
int button = 0;
// Server und Port
WiFiServer server(80);

void setup() {
  pinMode(ledpin, OUTPUT);
  digitalWrite(ledpin, 0);
   WiFi.mode(WIFI_STA);
  // verbinde WIFI  
  WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  // Starte server
  server.begin();
}
  
void post() {
  klappe = digitalRead(buttonPin);
   if (klappe == HIGH) {  
   button = 2;
  }else{
   button = 4;
   }
  WiFiClient client;
  const int httpPort = 8000;
  if (!client.connect(host, httpPort)) {
  }
  neu = aktiv + button;
  if (neu == 2) {  
  client.print(String("GET ") + "/pck?c=%3EM000200.RL-1------" + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  aktiv = 1;
  }
  if (neu == 5) {  
  client.print(String("GET ") + "/pck?c=%3EM000200.RL-0------" + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  aktiv = 0;
  }
}  

void licht(){
  // Verbindungskontrolle
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  // Wait 
  while(!client.available()){
    delay(1);
  }
  // lesen der ersten Zeile
  String req = client.readStringUntil('\r');
  client.flush();
  // Auswertung
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    client.stop();
    return;
  }
  // Ausführen
  digitalWrite(ledpin, val);
  client.flush();
//  Antwort
//  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nHausnummer ist jetzt ";
//  s += (val)?"beleuchtet":"unbeleuchtet";
//  s += "</html>\n";
//  client.print(s);
//  delay(1);
}
void loop(){
  licht();
  post();
}

Das geht bestimmt noch schöner.
Ich weiß nur nicht ob das eventuell zeitkritisch sein kann. Der Button gibt später nur einen "Impuls". Dauer wahrscheinlich unter einer Sekunde. Kann ich die Funktion "post" irgendwie bevormunden?

Danke bis hierher.

Schöne Pfingsten

Siebo

Was meinst du mit bevormunden?
Was tut der Sketch was dir aktuell nicht gefällt?
Drücke mal STRG-T in der IDE und formatiere deinen Sketch vernünftig.
Was glaubst du dass dieser if bewirkt?

  if (!client.connect(host, httpPort)) {
  }

Und weil ich schon dabei bin, Naming Things: warum nennst du eine Funktion die ein GET abschickt post()?

Moin

Mit "Strg T" sieht alles gleich viel besser aus.
Danke.

Was das hier bewirkt?

 if (!client.connect(host, httpPort)) {
  }

In einer frühen Version (Copy Paste) folgte danach eine Serial Print Ausgabe. Wenn ich mich richtig erinnere
Wird entfernt!

"post" heisst "post" weil die meldung vom Briefkasten kommen wird und "POST ist da" signaliesieren soll.
Währe hier "r2d2" besser gewesen, oder ist der begriff schon anders belegt? :smiley: Sorry
"button1" oder "client" würde sicher auch gehen, aber "post" erschien mir irgendwie sinnvoll.

Vielen Dank für eure super Tips.
Es ist echt erstaunlich was diese kleinen Platinen alles können.

Danke
Siebo

Moin

Ich korrigiere:

if (!client.connect(host, httpPort)) {
  }

Ohne diese Zeile funktioniert der Sketch nicht mehr. Es wird damit wohl der Port 8000 freigeschaltet.

Was meinst du mit bevormunden?
Was tut der Sketch was dir aktuell nicht gefällt?

Das Relais in meinem Hausbus wir teilweise erst mit 1-2 sec verzögerung angesteuert. Da ich später nur einen Taster an meinen Briefkasten bauen möchte, befürchte ich das das Signal schon wieder weg ist, bis der ESP die URL aufgerufen hat. Ich kann nicht sagen ob der ESP oder der hausbus die verzögerung verursacht. Da teste ich noch.
Ich habe schon mal mit einem delay in einem anderen Sketch probiert. Da ist mir dann alles stehen geblieben. Das möchte ich nicht. Gibt es eine Möglichkeit einen

client.print(String("GET ") + "/p....

Befehl um einige Sekunden zu verzögern, ohne den ganzen Sketch zu pausieren?
Vom Gefühl muss ich warscheinlich irgendetwas hochzählen. Oder gibt es eine einfachere Lösung?

Vielen Dank im voraus

Siebo