espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.66k stars 7.42k forks source link

feature request / example code request: website by esp32 server, plus remote control also of esp8266 clients #4110

Closed dsyleixa closed 4 years ago

dsyleixa commented 4 years ago

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:

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)

atanisoft commented 4 years ago

With all of the options available to accomplish this sort of task, it doesn't exactly make sense for the arduino-esp32 repository to dictate what option is best as that is very subjective and project specific.

Now as to your issue, it isn't clear why it is not working as you haven't included any logs etc which might help shed light as to why the code you are using is not working as you expect. It doesn't look like an issue in arduino-esp32 at this point.

dsyleixa commented 4 years ago

as stated, it's just a request for an example code e.g. in the Webserver library examples. As to my code examples, I just wanted to show what does not work. Currently nowhere is explained so far how to build a website by a esp32 to connect and to communicate to an esp8266 client, which is hardware what probably 1000s of Arduino users have.

If esp32 code was 100% compatibel to esp8266 code then it was no issue, because esp8266 server to esp8266 client works. Nonetheless, an upgrade to an esp32 server does not work anymore.

Arduino users also are mostly no professionals but noobs or hobbyists and program just by c+p'ing functioning code and then modifying it a bit arbitrarily. So this topic about a code example is meant for general example code to Arduino noobs to c+p (like e.g. the "hello server" example).

Perhaps any a professional programmer would like to write such a thing, so I would appreciate if he did.

lbernstone commented 4 years ago

This is not instructables.com. The examples are to demonstrate the library and peripheral functions, and often to act as tests for them. There are 1000s of sites that are specifically for the sort of example you want.

dsyleixa commented 4 years ago

no, there is no single one - or show one. And "1000s of sites" is basically just hollow chatter. And it's not up to YOU to decide. It's a feature request to the esp-arduino developers, to the benefit of all Aduino users who like to purchase an esp32 and work with it.

chegewara commented 4 years ago

And it's not up to YOU to decide.

Neither up to you. This is not feature request either, it request to build app for you.

As you pointed, there is 1000s of users:

Currently nowhere is explained so far how to build a website by a esp32 to connect and to communicate to an esp8266 client, which is hardware what probably 1000s of Arduino users have.

There is also 1000s of users with RPi, nrf, arduino R3 etc. Im guessing we (community) have to write example that will show how to use those boards with esp32, just because noobs like you (you words) cant build it? If you dont know how to build code on esp32 then maybe its not for you and stay with esp8266.

dsyleixa commented 4 years ago

And it's not up to YOU to decide.

Neither up to you. This is not feature request either, it request to build app for you.

As you pointed, there is 1000s of users:

Currently nowhere is explained so far how to build a website by a esp32 to connect and to communicate to an esp8266 client, which is hardware what probably 1000s of Arduino users have.

There is also 1000s of users with RPi, nrf, arduino R3 etc. Im guessing we (community) have to write example that will show how to use those boards with esp32, just because noobs like you (you words) cant build it? If you dont know how to build code on esp32 then maybe its not for you and stay with esp8266.

seldom read such a shit like yours. But quite often here by you and different other snooty and arrogant "contributors" who troll around and think they have leased the wisdom and that they have decision-making powers over this repo.

lbernstone commented 4 years ago

Stop feeding the trolls, please. Github has a block user feature.

me-no-dev commented 4 years ago

@dsyleixa connections between devices happen over protocols. Such as TCP, UDP, HTTP, MQTT, etc. When support is added to a device for those, it is never intended to be specific to a particular device, be that ESP8266, Pi or whatever other micro/computer. There is no requirement ESP8266 Arduino to be the same as ESP32 Arduino. Different architectures and much more. But API has nothing to do with connecting the two chips. You just need a working code on both that uses the same protocols. That is it.

p.s. If you want to get help, it would be much easier if you are nice. Nobody owes you anything here and there are plenty more that need help. I strongly advise you to change your ways.

dsyleixa commented 4 years ago

I am always nice, like this time and all times before, when I asked this request, because source code examples about this topic are missing. But I am not supposed to be nice to insulting trolling idiots, from which I do not expect help actually (e.g., claiming that there existed already 1000s of examples about this in the web but are unable to link to just 1). It's also completely unreasonable that you close this issue because it's not solved yet, and instead take sides with the other fools. Honestly, I have rarely seen such a horde of narrow-minded professional idiots like here in this repo. You can be sure that I will share my esp32 experiences and I already started to advise users in different forums strictly against the ESP32 because of the effing poor (actually not even existing) support to reported issues.

PS, as to "There is no requirement ESP8266 Arduino to be the same as ESP32 Arduino. Different architectures and much more.": I guess that you don't even have understood 1 fundamental concept of Arduino/Wiring: cross-board-compatibility of API libs.

chegewara commented 4 years ago

You can be sure that I will share my esp32 experiences and I already started to advise users in different forums strictly against the ESP32 because of the effing poor (actually not even existing) support to reported issues.

Uh oh, we will miss you.

me-no-dev commented 4 years ago

I hope you realise that us fools also talk to each other. I am well aware of your history on the ESP8266 side. You were never nice, you do not chose who tries to help you, you do not even try to do what they propose. I am afraid you are expecting too much from an issue tracker. This is a tool to solve bugs and issues in the core, not to help user achieve their goals or add unnecessarily complex examples. You are free to submit such example as PR, discuss implementations and approaches in the gitter chat and so on.

The issue was closed because it's invalid in the scope of the "github issues" tracker. It can be discussed further here, but there is no point in it being shown as active.

p.s. You can continue to insult my competency, I am not bothered. You are the one that does not know how to do things though... And don't forget to link to your examples of our poor professionalism when you spread the word :)

dsyleixa commented 4 years ago

as stated, I am always nice, like this time and all times before, when I asked questions about issues and answering to constructive replies. But I never will be nice to insulting snooty idiotic trolls like e.g. chegewara and others, and admittedly on the esp8266 side there are also a couple of trolling assholes I am not expected to act nicely to. OTOH, feature requests about extensions are a permissible concern for issue trackers, especially like here if code works for esp8266 (or in other cases, e.g. for original Arduino.cc libs) but not for esp32 any more, so the the principle of cross-board compatibility is violated and thus working or fixed code is needed.