0

I'm working through a tutorial about using esp8266 connected to an Arduino Uno to serve a webpage with Ajax that retrieves a json file (also served by the Arduino). The tutorial (won't link to it here) looks like it's a work of fiction because the author builds the webpage using Strings like this:

    String webpage = "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, minimumscale=1.0, maximum-scale=1.0, initial-scale=1\" />";
    webpage += "<style>body { background-color: #cccccc; text-align: center; max-width: 400px; margin: 10px auto; } #datavalues { max-width: 400px; display: block; margin-top: 30px; }</style>";
    webpage += "</head><body>";
    webpage += "<div id=\"datavalues\">";
    webpage += "<h1>Light: </h1><div id=\"light\">";
    webpage += lightval;
    webpage += "</div>";
    webpage += "<h1>Count: </h1><div id=\"count\">";
    webpage += count;
    webpage += "</div>";
    webpage += "</div>";
    webpage += "<script>function loadDoc() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var obj = JSON.parse(this.responseText); document.getElementById(\"light\").innerHTML = obj.data[0].datavalue; document.getElementById(\"count\").innerHTML = obj.data[1].datavalue; } }; xhttp.open(\"GET\", \"data.json\", true); xhttp.send(); } var timedEvent = setInterval(function(){ loadDoc(); }, 2000);</script>";
    webpage += "</body></html>";

and when you test it it looks like the webpage is either too long for a String or the uno runs out of memory. I've been trying with c type strings (reading that they are more efficent) like so:

    char webpage[1024] = "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, minimumscale=1.0, maximum-scale=1.0, initial-scale=1\" />";
    strcat(webpage, "<style>body { background-color: #cccccc; text-align: center; max-width: 400px; margin: 10px auto; } #datavalues { max-width: 400px; display: block; margin-top: 30px; }</style>");

but it doesn't seem to make much difference. Is there a way to serve a webpage this size from the arduino? / what is the most efficient way to build it and serve it?

garrettlynchirl
  • 790
  • 8
  • 23
  • Questions: is there a specific need you use an Arduino (Uno I guess). Are you using an ESP8266 wif module with 1 or 4 Mb memory. What is the make o fthe module (eg.12e or 1 or ?). You are right with the String problem, even chars wont help you because of the limited memory of the Uno(?) – Codebreaker007 Mar 11 '20 at 14:28
  • Yes I'm locked into using the uno, this is part of some teaching with undergraduates learning Arduino so even though we could go straight to the esp8266 I want to still to the uno for consistency of everything else they have been working through. I have everything working it's just the ajax is too long. – garrettlynchirl Mar 11 '20 at 15:20
  • https://github.com/jandrassy/WiFiEspAT/blob/master/examples/Basic/WebServer/WebServer.ino or https://github.com/jandrassy/WiFiEspAT/blob/master/examples/Advanced/ConfigurationAP/ConfigurationAP.ino – Juraj Mar 11 '20 at 15:28
  • Will look at this @Juraj but need to test the answer example below as that seems more robust. – garrettlynchirl Mar 12 '20 at 14:03

1 Answers1

2

Depending on the free memory on the Arduino (UNO) you could move the HTML to progmem
Example Code

//HTML Code Start-----------------------------------
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!doctype html>
<html>
.... your page code here
        <script>
   ...even with javascript
       </script>
     </body>
 </html>
 )rawliteral";
//HTML Code END-----------------------------------

You would use it then in your response (with a lib like simple webserver or similar for Uno) like

 server.on("/index.html", HTTP_GET, []() {
    server.send(200, "text/html", (const char *)INDEX_HTML);
});

For just sending over wifi you would do a

  client.print(...);

Start with a minimal page (watch your memory after compiling) - The next step should be to host the web function in the esp (SPIFFS/LittleFS) and connect via serial with the arduino and exchange data from/to the pins.
As a final tip: Never use Arduino String class and communication tasks - It will fragment the heap and crash the Arduino/ESP. Instead work with pre-defined char arrays and pointers.

Codebreaker007
  • 2,911
  • 1
  • 10
  • 22
  • "Never use Arduino String class and communication tasks - It will fragment the heap and crash the Arduino/ESP" so that's what's happening - have been trying to figure out why the Arduino bombs with the ajax. Works initially but then stops after about four of five calls. I thought the Arduino couldn't handle the frequency of the calls or that simply the string we too long. Will try your suggestion with PROGMEM. Many thanks @Codebreaker007. – garrettlynchirl Mar 12 '20 at 14:00
  • what is `server.on`? there is no library for Uno with esp8266 as network adapter with `server.om` – Juraj Mar 12 '20 at 14:58
  • @Juraj You could use the simple webserver lib for Uno or similar, which provide this functionality either over ethernet or esp modules. But you are right I edited my answer for newbies. thanks for the input, – Codebreaker007 Mar 12 '20 at 18:19
  • sorry, there is a library. ESP8266_AT_WebServer library – Juraj Mar 12 '20 at 18:40