-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
feature request / example code request for noobs:
code for a website by esp32 with buttons, connect with an extra remote esp8266 client and contol remote pins.
Problems:
- no example code in this repo available how to connect an esp8266 to an esp32 web-or wifiserver over a website,
- different source codes for esp8266 (!!)-server(!!) and esp8266 clients to connect to each other work fine, but cannot be ported to work with an esp32 server.
e.g., to start from:
https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/
now with 1st button still for esp32 LED_BUILTIN (that part of course works already)
but 2nd button instead for remote esp8266 client LED_BUILTIN
what I tried (but failed):
problem:
both programs run, but esp8266 client can never connect to esp32 server/website.
So a working example for all noobs in this repo would be highly appreciated.
If already exists somewhere: a link would be appreciated.
ESP32 Server:
// Create A Simple ESP32 Web Server In Arduino IDE
// https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/
#include <WiFi.h>
#include <WiFiClient.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <WebServer.h>
//#include <WiFiServer.h>
String version = "0.03a";
/*Put your SSID & Password*/
const char* ssid = "WLAN"; // Enter SSID here
const char* password = "18658"; //Enter Password here
char www_username[64] = "admin";
char www_password[64] = "esp32";
IPAddress this_ip(192, 168, 2, 202); // <<< static local IP of this ESP-webserver
IPAddress gateway(192, 168, 2, 1); // <<< LAN Gateway IP
IPAddress subnet(255, 255, 255, 0); // <<< LAN Subnet Mask
#define wwwport 8008
#define wifiport 8081 // Port für die esp clients
WebServer webserver(wwwport); // www website: website http port
WebServer server(wifiport); // client comm: router wifi port
// allows you to set the realm of authentication Default:"Login Required"
const char* www_realm = "Custom Auth Realm";
// the Content of the HTML response in case of Unautherized Access Default:empty
String authFailResponse = "Authentication Failed";
uint8_t LED1pin = LED_BUILTIN;
bool LED1status = LOW;
uint8_t LED2pin = 12;
bool LED2status = LOW; // c4out1
volatile int8_t c4out1=0, C4OUT2=0, C4OUT3=0; // Client4; actual output pin states; stop=0, fwd=1, rev=-1;
//----------------------------------------------------------
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += webserver.uri();
message += "\nMethod: ";
message += (webserver.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += webserver.args();
message += "\n";
for (uint8_t i = 0; i < webserver.args(); i++) {
message += " " + webserver.argName(i) + ": " + webserver.arg(i) + "\n";
}
webserver.send(404, "text/plain", message);
}
//----------------------------------------------------------
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(LED1pin, OUTPUT);
pinMode(LED2pin, OUTPUT);
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
WiFi.config(this_ip, gateway, subnet); // static IP
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
ArduinoOTA.begin();
webserver.on("/", []() {
if (!webserver.authenticate(www_username, www_password))
//Basic Auth Method with Custom realm and Failure Response
//return webserver.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
//Digest Auth Method with realm="Login Required" and empty Failure Response
//return webserver.requestAuthentication(DIGEST_AUTH);
//Digest Auth Method with Custom realm and empty Failure Response
//return webserver.requestAuthentication(DIGEST_AUTH, www_realm);
//Digest Auth Method with Custom realm and Failure Response
{
return webserver.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse);
}
handle_OnConnect();
});
/*
webserver.on("/inline", []() {
webserver.send(200, "text/plain", "this works as well");
});
*/
webserver.on("/led1on", handle_led1on);
webserver.on("/led1off", handle_led1off);
webserver.on("/led2on", handle_led2on);
webserver.on("/led2off", handle_led2off);
webserver.onNotFound(handle_NotFound);
webserver.begin();
Serial.println("HTTP webserver started");
server.on("/client/client1/", handleClientIOs);
server.on("/client/client4/", handleClientIOs);
server.begin();
Serial.println("ESP server started");
}
//----------------------------------------------------------
void loop() {
ArduinoOTA.handle();
webserver.handleClient();
if(LED1status)
{digitalWrite(LED1pin, HIGH);}
else
{digitalWrite(LED1pin, LOW);}
// LED2 jetzt nicht mehr lokal, sondern auf remote ESP8266
/*
if(LED2status)
{digitalWrite(LED2pin, HIGH);}
else
{digitalWrite(LED2pin, LOW);}
*/
handleClientIOs();
delay(1000);
}
//----------------------------------------------------------
void handle_OnConnect() {
LED1status = LOW;
LED2status = LOW;
Serial.println("GPIO13 Status: OFF | GPIO12 Status: OFF");
webserver.send(200, "text/html", SendHTML(LED1status,LED2status));
}
//----------------------------------------------------------
void handle_led1on() {
LED1status = HIGH;
Serial.println("GPIO13 Status: ON");
webserver.send(200, "text/html", SendHTML(true,LED2status));
}
void handle_led1off() {
LED1status = LOW;
Serial.println("GPIO13 Status: OFF");
webserver.send(200, "text/html", SendHTML(false,LED2status));
}
//----------------------------------------------------------
void handle_led2on() {
LED2status = HIGH;
c4out1 = HIGH;
Serial.println("clientIO Status: ON");
handleClientIOs();
webserver.send(200, "text/html", SendHTML(LED1status,true));
}
void handle_led2off() {
LED2status = LOW;
c4out1 = LOW;
Serial.println("clientIO Status: OFF");
handleClientIOs();
webserver.send(200, "text/html", SendHTML(LED1status,false));
}
//----------------------------------------------------------
void handle_NotFound(){
String message = "File Not Found\n\n";
message += "URI: ";
message += webserver.uri();
message += "\nMethod: ";
message += (webserver.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += webserver.args();
message += "\n";
for (uint8_t i = 0; i < webserver.args(); i++) {
message += " " + webserver.argName(i) + ": " + webserver.arg(i) + "\n";
}
webserver.send(404, "text/plain", message);
//webserver.send(404, "text/plain", "Not found");
}
//----------------------------------------------------------
String SendHTML(uint8_t led1stat,uint8_t led2stat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>LED Control</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; /*text-align: center*/;}\n"; // text-align
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
//ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none; color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>ESP32 Web Server</h1>\n";
ptr +="<h3>Using Station(STA) Mode</h3>\n";
ptr +="<h1><p>version=" + version + "</p></h1><br>\n";
ptr+="<p>";
if(led1stat) {ptr +="LED1 Status: ON_ ";}
else {ptr +=" LED1 Status: OFF ";}
ptr += ("<a href=\" /led1on\"\"> <button style=\"height:70px;width:140px\" > ON </button></a> ");
ptr += ("<a href=\" /led1off\"\"> <button style=\"height:70px;width:140px\" > OFF </button></a> ");
ptr+="</p>";
ptr+="<br><br><p>";
if(led2stat) {ptr +="LED2 Status: ON_ ";}
else {ptr +=" LED2 Status: OFF ";}
ptr += ("<a href=\" /led2on\"\"> <button style=\"height:70px;width:140px\" > ON </button></a> ");
ptr += ("<a href=\" /led2off\"\"> <button style=\"height:70px;width:140px\" > OFF </button></a> ");
ptr+="</p>";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
//----------------------------------------------------------------------------
void handleClientIOs() {
//printUrlArg(); //fuer Debug Zwecke
double ftmp;
String msgtok;
//Werte auch bei Url-Aufruf zurückgeben
String message="***";
message += "&c4out1="+(String)c4out1 ;
message += "&LED2status="+(String)LED2status ; // alias
message += ";###";
Serial.println(message);
server.send(200, "text/plain", message);
}
ESP8288 remote Client:
/* ESP8266 NodeMCU
ESP8266WiFi Client für Remote Sensor Werte
Client 4, Port 8081, wifi server .202
Arduino IDE 1.8.9
*/
char * clientname = "Client 4"; //
char * ver = "4.014-";
//----------------------------------------------------------------------------
#include <Wire.h>
#define ESPSDA D2 // GPIO4
#define ESPSCL D1 // GPIO5
//----------------------------------------------------------------------------
// IO pins
//----------------------------------------------------------------------------
#define PIN_OUT0 D6
#define PIN_OUT1 LED_BUILTIN
#define PIN_OUT2 D8
//----------------------------------------------------------------------------
// OLED SSD1306
#include <ESP_SSD1306.h> // Modification of Adafruit_SSD1306 for ESP8266 compatibility
#include <Adafruit_GFX.h> // Needs a little change in original Adafruit library (See README.txt file)
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeMono8pt7b.h>
ESP_SSD1306 display(-1);
//----------------------------------------------------------------------------
// outputs + signals
int16_t c4out0=0,
c4out1=0,
c4out2=0;
int32_t timeoutcnt;
//----------------------------------------------------------------------------
#include <ESP8266WiFi.h>
/*Put your SSID & Password*/
const char* ssid = "WLAN"; // Enter SSID here
const char* password = "18658"; //Enter Password here
const char* hostIP = "192.168.2.202"; // Server der die temperatur empfangen soll
const int wifiPort = 8081; // Port für die esp clients
const char* script = "/client/client4/"; // URL/Verzeichnis das wir gewaehlt haben
//----------------------------------------------------------------------------
const int MAXLEN = 1024;
const int TOKLEN = 64;
int16_t strstrpos(char * haystack, char * needle) // find 1st occurance of substr in str
{
char *p = strstr(haystack, needle);
if (p) return p - haystack;
return -1; // Not found = -1.
}
//-------------------------------------------------------
char * cstringarg( char* haystack, char* vname, char* sarg ) {
int i = 0, pos = -1;
unsigned char ch = 0xff;
const char* kini = "&"; // start of varname: '&'
const char* kin2 = "?"; // start of varname: '?'
const char* kequ = "="; // end of varname, start of argument: '='
char needle[TOKLEN] = ""; // complete pattern: &varname=abc1234
strcpy(sarg, "");
strcpy(needle, kini);
strcat(needle, vname);
strcat(needle, kequ);
pos = strstrpos(haystack, needle);
if (pos == -1) {
needle[0] = kin2[0];
pos = strstrpos(haystack, needle);
if (pos == -1) return sarg;
}
pos = pos + strlen(vname) + 2; // start of value = kini+vname+kequ
while ( (ch != '&') && (ch != '\0') ) {
ch = haystack[pos + i];
if ( (ch == '&') || (ch == ';') || (ch == '\0') || (ch == '\n')
|| (ch == ' ') // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< for login!
|| (i + pos >= strlen(haystack)) || (i > TOKLEN - 1) ) {
sarg[i] = '\0';
return sarg;
}
if ( (ch != '&') ) {
sarg[i] = ch;
i++;
}
}
return sarg;
}
//----------------------------------------------------------------------------
char * dashboard(int mode) {
// OLED
}
//----------------------------------------------------------------------------
// SETUP
//----------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
delay(10);
pinMode( PIN_OUT0, OUTPUT);
pinMode( PIN_OUT1, OUTPUT);
pinMode( PIN_OUT2, OUTPUT);
pinMode( LED_BUILTIN, OUTPUT); // alias
// i2c + OLED
//Wire.begin(ESPSDA,ESPSCL); // SDA, SCL
Wire.begin(); // default
delay(1);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.setRotation(2);
display.setFont();
display.setTextSize(1);
display.setTextColor(WHITE);
display.clearDisplay();
display.setCursor( 0, 0); display.print("OLED TEST OK");
display.display();
// WiFi start
Serial.println();
Serial.println();
Serial.print("Verbinde mich mit Netz: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Verbindung aufgebaut");
Serial.print("Eigene IP des ESP-Moduls: ");
Serial.println(WiFi.localIP() );
display.setCursor(0,15); display.print("WiFi Verbindung aufgebaut");
display.display();
delay(500); // debug
}
//----------------------------------------------------------------------------
// LOOP
//----------------------------------------------------------------------------
// Bei deepSleep wird die loop Schleife eigentlich nur einmal durchlaufen
void loop() {
static float ftmp;
static unsigned long tms=0;
static unsigned long dtms=0;
unsigned long timeout;
if(timeoutcnt>60*30) { // > 30min timeout
Serial.println("\n timeout => restart \n");
display.print("timeout => restart");
ESP.restart();
}
WiFiClient client;
delay(10);
//---------------------------------------
// msg string
String vals = ""; // for sensor values
//---------------------------------------
// connect to ESP8266 webserver
int versuche=1;
int IOres=0;
do
{
Serial.print("Verbindungsaufbau zu Server ");
Serial.println(hostIP);
IOres =client.connect(hostIP, wifiPort);
if (!IOres) {
versuche++;
timeoutcnt++;
dashboard(1);
Serial.println("Verbindungsaufbau nicht moeglich!!!");
if (versuche>10) {
Serial.println("Klappt nicht, versuche es spaeter noch mal!");
client.stop();
delay(1000);
}
}
delay(1000);
} while (IOres!=1);
//---------------------------------------
// msg string to server
String url = script; //Url wird zusammengebaut: script = "/client/client4/";
url += "?pw=";
url += password;
url += vals;
Serial.print("Folgende URL wird aufgerufen: ");
Serial.println((String)hostIP + "?pw="+"*****"+vals);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"hostIP: " + hostIP + "\r\n" +
"Connection: close\r\n\r\n");
timeout= millis();
while ( !client.available() ) {
timeoutcnt+=1;
if( (millis()-timeout < 20000)) {
Serial.print("Timeout svr count: "); Serial.println( timeoutcnt );
Serial.println("Rueckmeldung von Server verzoegert, ich warte noch...");
//client.stop();
delay(1000);
}
else {
Serial.println("\nAbbruch, keine Rueckantwort vom Server!\n");
break;
}
}
timeout=millis();
String msgline;
Serial.println("Rueckgabe vom Server:\n");
if(client.available()) {
timeoutcnt=0;
while(client.available()) {
msgline = client.readStringUntil('\r');
//Serial.print("msgline="); Serial.println(msgline);
}
String Sargval="";
char carg[TOKLEN], ctok[TOKLEN], cmsg[MAXLEN];
Sargval="";
msgline.toCharArray(cmsg, MAXLEN-1);
Serial.println();
Serial.print("cmsg="); Serial.println(cmsg);
c4out0=0; // default
c4out1=0;
c4out2=0;
if(cmsg!="") {
cstringarg(cmsg, "c4out0", carg); // alert pin (D6) switch on/off
Sargval=(String)carg;
if(Sargval!="") {
c4out0=Sargval.toInt();
}
cstringarg(cmsg, "c4out1", carg); // switch on/off
Sargval=(String)carg;
if(Sargval!="") {
c4out1=Sargval.toInt();
}
cstringarg(cmsg, "c4out2", carg); // switch on/off
Sargval=(String)carg;
if(Sargval!="") {
c4out2=Sargval.toInt();
}
}
// debug
Serial.println( (String)"c4out0=" + (String)c4out0 + " <<<<<<<<<<<<" );
Serial.println( (String)"c4out1=" + (String)c4out1 + " <<<<<<<<<<<<" );
Serial.println( (String)"c4out2=" + (String)c4out2 + " " );
if(c4out0==0) digitalWrite(PIN_OUT0, LOW); else digitalWrite(PIN_OUT0, HIGH);
if(c4out1==0) digitalWrite(PIN_OUT1, LOW); else digitalWrite(PIN_OUT1, HIGH);
if(c4out2==0) digitalWrite(PIN_OUT2, LOW); else digitalWrite(PIN_OUT2, HIGH);
} // if(client.available())
client.flush();
client.stop();
Serial.println("\nPausiere jetzt ... \n");
delay(3000);
}
(PS, additionally also reading esp8266 client remote values would be highly appreciated)