• Skip to main content
  • Skip to primary sidebar

RNTLab.com

The Ultimate Shortcut to Learn Electronics and Programming with Open Source Hardware and Software

  • Courses
  • Forum
    • Forum
    • Ask Question
  • Shop
  • Account
  • Blog
  • Login

over-the-air-ota

Q&A Forum › Category: ESP32 › over-the-air-ota
0 Vote Up Vote Down
Jean Pierre Daviau asked 3 years ago

Hi,
If I close the browser, reopen it at IP address: 189.143.0.112,  it still present me with the login page then the upload page.  What if I don’t want to see the upload page and show another index.html instead ?

Start your code here
const char* indexHtml = 
the returned string from a function(){return indexH;}

 

Start your code here
Update: LED_OTAWebUpdater.ino.node32s.bin
Update Success: 758096
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:928
ho 0 tail 12 room 4
load:0x40078000,len:8740
load:0x40080400,len:5788
entry 0x4008069c
..
Connected to Network
IP address: 189.143.0.112
mDNS responder started
ets Jun 8 2016 00:22:57

Regards

JPD

Question Tags: OTA, over-the-air-ota
23 Answers
0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi.
Is this question related with this one: https://rntlab.com/question/over-the-air/?
You can have a button that redirects you to another URL that will request another HTML page, or if you don’t want to access the login page again, go directly to the URL that displays another HTML page.
I’m not sure if I really understood your question.
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Yes it does. But we will forget about that post. Don’t answer it.

In the Ruis Santos code OTA:
An extra button could call this function?:

server.on(“/serverIndex”, HTTP_GET, []() {
server.sendHeader(“Connection”, “close”);
server.send(200, “text/html”, webPage);
});

———————-
const char *webPage = // to be corrected
“”
“”
“Météo”
“”
“if (atoi(%CELSIUSTEMP%) >= 25)”
“{“
“”
“}”
“else if (atoi(%CELSIUSTEMP%) = 5)”
“{“
“”
“}”
“else if (atoi(%CELSIUSTEMP%) < 5)"
"{"
"”
“}”
“</SCRIPT"
"”
“myDate()”
“”
“PuissanceWifi =  %PUISSANCEWIFI%”
“
Page en ligne pour “
“%WEBPAGETIME%”
” minutes.”
” %CTEMP%”
“°C”
“Humidité du sol:  “
“%VAL1%”
“%,  “
“%VAL2%”
“%”
“Humidité: “
“%HUMIDITYTEMP%”
“%   Rosé: “
“%DEW%”
“°  “
“Ressenti: “
“%HIC%”
“°”
“”
“for (int i = newLinesCnt ; i >= 0 ; i–)”
“{“
“newLinesArray[i]
“
“}”
“
——————————————-
“
“for (int spiffDatas = decCnt; spiffDatas >= 0; spiffDatas–)”
“{“
“if (datArray[spiffDatas] != 0)”
“{“
“
“
“datArray[spiffDatas]”
“
“
“}”
“}”
“”
“”;

Regards,

JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi.
Yes,
Add something like this in your HTML text:

<p><a href="/serverIndex"><button>YOUR_TEXT_HERE</button></a></p>

It will create a button that when clicked, will redirect to the /serverIndex URL and that function will be called.
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,
What does that means:
 
src\main new.cpp: In function 'void setup()':
src\main new.cpp:883:12: error: 'class WiFiServer' has no member named 'on'

server.on(" / webPage", HTTP_GET, []()
^
src\main new.cpp: In lambda function:
src\main new.cpp:885:14: error: 'class WiFiServer' has no member named 'sendHeader'

 
server.on(” / webPage”, HTTP_GET, []()
{
server.sendHeader(“Connection”, “close”);
server.send(200, “text / html”, webPage);
});
 
JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi.
It means that server that is a WiFiServer object doesn’t have any method called on.
It probably means that you’re not using the right library for that method, or that you don’t have things declared in a proper way.
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,
 
I went in the C file , there is method on.
 
I copied paste from the genuine file:
 
#include <WiFi.h>
Used: …\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\libraries\WiFi
#include <WiFiClient.h>
#include <WebServer.h>
Used : …\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\libraries\WebServer
#include <ESPmDNS.h>
#include <Update.h>
 
#include <WiFiUdp.h>
#include <NTPClient.h>
#include “FS.h”
#include “SPIFFS.h”
#include <time.h>
#include “DHT.h”
 
Regards
 
JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

So, I don’t know what might be wrong.
Maybe the server object is not defined properly. How do you initialize your server object?
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

I found something.
It compiles and I can open the web page.
The problem is the processor function witch should replace the %PLACEHOLDER%
This is the one causing the compiler errors.

Start your code here

const char *webPage =
  ""
  ""
  "Météo"
  ""
  "if (atoi(%CELSIUSTEMP%) >= 25)"
  "{"
  ""
  "}"
  "else if (atoi(%CELSIUSTEMP%) = 5)"
  "{"
  ""
  "}"
  "else if (atoi(%CELSIUSTEMP%) < 5)"
  "{"
  ""
  "}"
  "</SCRIPT"
  ""
  "%MYDATE%"
  ""
  "PuissanceWifi =  %PUISSANCEWIFI%"
  "
Page en ligne pour " "%WEBPAGETIME%" " minutes." " %CTEMP%" "°C" "Humidité du sol:  " "%VAL1%" "%,  " "%VAL2%" "%,  " "Température du sol:  " "%GROUND%" "%" "Humidité: " "%HUMIDITYTEMP%" "%   Rosé: " "%DEW%" "°  " "Ressenti: " "%HIC%" "°" "" "%MORELINES%" "" ""; String processor(const String &var) { float t, h, hic, dew; int val1, val2; float_t pw; if (var == "PUISSANCEWIFI") { pw = WiFi.RSSI(); return isnan(pw) ? String("Error") : String(pw, 1); } else if (var == "CTEMP") { Read temperature as Celsius (the default) t = dht.readTemperature(); return String(t); } else if (var == "VAL1") { val1 = capacitiveProbe(1, 120, 1, probe1); return String(val1); } else if (var == "VAL2") { val2 = capacitiveProbe(1, 120, 1, probe2); return String(val2); } else if (var == "GROUND") { ground = fonction return String(); } else if (var == "HUMIDITYTEMP") { h = dht.readHumidity(); dtostrf(h, 6, 2, humidityTemp); ("Decimal to String Float"). return String(h); } else if (var == "HIC") { hif = dht.computeHeatIndex(f, h); hic = dht.computeHeatIndex(t, h, false); dtostrf(hic, 6, 2, celsiusTemp); return String(hic); } else if (var == "DEW") { dew = dewPoint(t, h); return String(dew); } else if (var == "MORELINES") { return moreLines(); } else if (var == "MYDATE") { return (myDate()); } return ""; }

Regards,

JPD

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Another thing:

Do I have to define the place holders (%PLACEHOLDER%) somewhere?

JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi again.
Instead of using % for the percentage sign for the humidity unit, use the HTML entity instead: https://www.freeformatter.com/html-entities.html
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,

Yet another thing.

The processor method creates the compiling problem. Is it because the method code has flaws?

The parameter receive the webPage const char* webPage?

From which class is that method from?

Could I use a string tokenizer to parse the string parameter and replace the placeholders by their values or does the processor method do the job?

Regards,

JPD

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi, ;o)

It compiles! With one flaw; see image.
Open image in a new window.

webPage

Start your code here
const char *webPage =
  "<!DOCTYPE HTML><html lang='fr'><head><meta name='viewport' content='width=device-width, initial-scale=1'>"
  "<meta http-equiv='refresh' content='30'></head>"
  "<body style='color:#f3d6e1;'><div style='font-size: 3.5rem;color:green;'><p style='text-align:center;'>Météo</p></div>"
  "<script language='Javascript' type='text/javascript'>"
  "if (%CELSIUSTEMP%>= 25){"
  "document.write(\"<div style='color: #930000;'><p style='text-align:center;'>\");"
  "}"
  "else if (%CELSIUSTEMP% < 25 && %CELSIUSTEMP%>= 5){"
  "document.write(\"<div style='color: #006601;'><p style='text-align:center;'>\");"
  "}else if (%CELSIUSTEMP% < 5){"
  "document.write(\"<div style='color: #009191;'>\");"
  "}"
  "</script>"
  "<p style='text-align:center;font-size:14pt;'>"
  "%MYDATE%"
  "</p><p></p><p style='text-align:center;font-size:14pt;'>"
  "PuissanceWifi&nbsp;=&nbsp; %PUISSANCEWIFI%"
  "<br>Page en ligne pour&nbsp;"
  "%WEBPAGETIME%"
  "&nbsp;minutes."
  "</p><p></p><p style='text-align:center;'> %CTEMP%"
  "&deg;C</p>"
  "<p style='text-align:center;'>Humidité du sol:&nbsp;&nbsp;"
  "%VAL1%"
  "%,&nbsp;&nbsp;"
  "%VAL2%"
  "%,&nbsp;&nbsp;"
  "Température du sol:&nbsp;&nbsp;"
  "%GROUND%"
  "%</p>"
  "<p style='text-align:center;font-size:20pt;'>Humidité:&nbsp;"
  "%HUMIDITYTEMP%"
  "%&nbsp;&nbsp;&nbsp;Rosé:&nbsp;"
  "%DEW%"
  "&deg;&nbsp;&nbsp;"
  "Ressenti:&nbsp;"
  "%HIC%"
  "&deg;</p>"
  "<p style='text-align:center;font-size:16pt;'>"
  "%MORELINES%"
  "</p></div>"
  "</body></html>";
String processor(const String &var)
{
  float t=0, h=0, hic, dew;
  int val1, val2, ground;
  float_t pw;
  if (var == "PUISSANCEWIFI")
  {
    pw = WiFi.RSSI();
    return isnan(pw) ? String("Error") : String(pw, 1);
  } else if (var == "CTEMP")
  {
    //Read temperature as Celsius (the default)
    t = dht.readTemperature();
    return String(t);
  } else if (var == "VAL1")
  {
    val1 = capacitiveProbe(1, 120, 1, probe1);
    return String(val1);
  } else if (var == "VAL2")
  {
    val2 = capacitiveProbe(1, 120, 1, probe2);
    return String(val2);
  } else if (var == "GROUND")
  {
    ground = analogRead(GROUND_PIN);	//String(analogRead(0), DEC); String(5.698, 3);
    return String(ground);
  } else if (var == "HUMIDITYTEMP")
  {
    h = dht.readHumidity();
    //dtostrf(h, 6, 2, humidityTemp); // ("Decimal to String Float").
    return String(h);
  } else if (var == "HIC")
  {
    hic = dht.computeHeatIndex(t, h, false);
    //dtostrf(hic, 6, 2, celsiusTemp);
    return String(hic);
  } else if (var == "DEW")
  {
    dew = dewPoint(t, h);
    return String(dew);
  } else if (var == "MORELINES")
  {
    return moreLines();
  } else if (var == "MYDATE")
  {
    return (myDate());
  }
  return String();
}


0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,
To find out what is not going on I felt on a simpler version using :
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, “text/html”, webPage, processor);
});
Right-clic and open in another tab.
webPage

Start your code here
/*
 * https://www.dfrobot.com/blog-1104.html
 * http://189.143.0.106/sensor
 * server.on("/sensor", HTTP_GET, [](AsyncWebServerRequest * request)
 * 
*/

#include "WiFi.h"
#include "ESPAsyncWebServer.h"


const char* host = "esp32";
const char *ssid = "23JANVIER-2012_Network_1";
const char *password = "cvq1-3bhy-afp6";
AsyncWebServer server(80);

const char *webPage =
  ""
  ""
  "Météo"
  ""
  "if (%CTEMP%>= 25){"
  "document.write(\"\");"
  "}"
  "else if (%CTEMP% = 5){"
  "document.write(\"\");"
  "}else if (%CTEMP% < 5){"
  "document.write(\"\");"
  "}"
  ""
  ""
  "%MYDATE%"
  ""
  "WIFISTRENGHT =  %WIFISTRENGHT%"
  "
Page en ligne pour " "%PAGETIME%" " minutes." " %CTEMP%" "°C" "Humidité du sol:  " "%VAL1%" "%,  " "%VAL2%" "%,  " "Température du sol:  " "%GROUND%" "°C" "Humidité: " "%HUMID_TEMP%" "%   Rosé: " "%DEW%" "°C  " "Ressenti: " "%HIC%" "°C" "" "%MORE_LINES%" "" ""; /* * CTEMP MYDATE WIFISTRENGHT PAGETIME VAL1 VAL2 * GROUND HUMID_TEMP DEW HIC MORE_LINES */ String processor(const String &var) { float t = 0, h = 0; int val, vale, ground , wpt, hic, dew; float_t pw; Serial.println(var); if (var == "MYDATE") { return String("45 date"); } else if (var == "WIFISTRENGHT") { pw = WiFi.RSSI(); return isnan(pw) ? String("Error") : String(pw, 1); }else if (var == "PAGETIME") { wpt = 111; return String(wpt);//* }else if (var == "CTEMP") { t = 34; return String(t); } else if (var == "VAL1") { val = 11; return String(val); } else if (var == "VAL2") { vale = 40; return String(vale); } else if (var == "GROUND") { ground = 33; //String(analogRead(0), DEC); String(5.698, 3); return String(ground); } else if (var == "HUMID_TEMP") { h = 17; return String(h); } else if (var == "HIC") { hic = 55; return String(hic); } else if (var == "DEW") { dew = 44; return String(dew); } else if (var == "MORE_LINES") { String strr = "--------------
------------"; return String(strr); } return String("-"); } void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println(WiFi.localIP()); server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/html", webPage, processor); }); server.begin(); } void loop(void) { // server.handleClient(); // delay(1); }  

All placeholders now work.
Why does it not work with .
  server.on(“/webPage”, HTTP_GET, []() {
server.sendHeader(“Connection”, “close”);
server.send(200, “text/html”, webPage);
}); ?
Regards
 
JPD

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

// server.on("/webPage", HTTP_GET, []() {
// server.sendHeader("Connection", "close");
// server.send(200, "text/html", webPage);
// });

server.on("/webPage", HTTP_POST, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", webPage, processor);
});

does not work

server.on(“/serverIndex”, HTTP_GET, []() {
server.sendHeader(“Connection”, “close”);
server.send(200, “text/html”, webPage);
});
gives this:
webPage1

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

When you use this method:

server.on("/webPage", HTTP_POST, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", webPage, processor);
});

The send() function accepts the processor as an argument. This way, it knows it needs to replace the placeholders with wathever we want on the processor().

The second snipet of code that you showed doesn’t do that, so it won’t call the procesor function and it won’t show the values.

Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,

It does not compile:

Arduino : 1.8.12 (Windows 10), Carte : “DOIT ESP32 DEVKIT V1, 80MHz, 921600, None”
OTA_Web_Updater.ino: In function ‘void setup()’:

OTA_Web_Updater:892:4: error: no matching function for call to ‘WebServer::on(const char [9], HTTPMethod, setup()::)’

WebServer.h:87:8: note: candidate: void WebServer::on(const String&, WebServer::THandlerFunction)

void on(const String &uri, THandlerFunction handler);

^

WebServer.h:87:8: note: candidate expects 2 arguments, 3 provided

WebServer.h:88:8: note: candidate: void WebServer::on(const String&, HTTPMethod, WebServer::THandlerFunction)

void on(const String &uri, HTTPMethod method, THandlerFunction fn);

^

WebServer.h:88:8: note: no known conversion for argument 3 from ‘setup()::’ to ‘WebServer::THandlerFunction {aka std::function}’

WebServer.h:89:8: note: candidate: void WebServer::on(const String&, HTTPMethod, WebServer::THandlerFunction, WebServer::THandlerFunction)

void on(const String &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);

^

WebServer.h:89:8: note: candidate expects 4 arguments, 3 provided

// server.on("/webPage", HTTP_GET, []() {
// server.sendHeader("Connection", "close");
// server.send(200, "text/html", webPage);
// });

server.on("/webPage", HTTP_POST, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", webPage, processor);
});
/**************************/
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});

Full code here in the third answer:

full code

Regards,

JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi.
Can you try the following snipet?

server.on("/webPage", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send_P(200, "text/html", webPage, processor);
});

Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,

This is what I did in the previous answer. See just on top of the line:
/**************************/

I red that there was an incompatibility between the includes on another post …. It was not proven.

This function woks on it’s own file (example at the link (full code)).

https://www.dropbox.com/s/bsnzdzh3hsb2usa/page%20forum.png?dl=0

So I know at least the *webPage text has no error.

Regards,

JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi again.
What I suggested is different, is HTTP_GET and not HTTP_POST. Try it out like this:

server.on("/webPage", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send_P(200, "text/html", webPage, processor);
});

I don’t know what else may be causing the issue.
Regards, Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

Hi,

It did not work either.

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

Hi.
I’m sorry but I don’t know what else can be wrong.
And at the moment, I can’t test the code on my own.
Try searching a bit more what might be causing the conflict, and return if you need further help.
Regards,
Sara

0 Vote Up Vote Down
Jean Pierre Daviau answered 3 years ago

By the way I updated my code on github.
I created my own processor function, , token, and unconstchar function as replacement for  send_P   function thus there ias no more conflict in the headers.
 
Regards
 
JPD

0 Vote Up Vote Down
Sara Santos Staff answered 3 years ago

That’s great.
I’ll mark this issue as resolved.
If you need further help, you just need to open a new question in our forum.
Regards,
Sara

Primary Sidebar

Login to Ask or Answer Questions

This Forum is private and it’s only available for members enrolled in our Courses.

Login »

Latest Course Updates

  • [eBook Updated] SMART HOME with RPi, ESP32, and ESP8266 (version 1.2) March 8, 2023
  • [eBook Updated] ESP32-CAM Projects (version 1.3) January 7, 2023

You must be logged in to view this content.

Contact Support - Refunds - Privacy - Terms - MakerAdvisor.com - Member Login

Copyright © 2013-2023 · RandomNerdTutorials.com · All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.