Arduino Variable in HTML using PROGMEM R"=====(

const char root[] PROGMEM = R"=====( //putyourhtmlcodehere)=====";

This is usually what you do when designing HTML for PROGMEM, but what I want to do is the following:

const char root[] PROGMEM = R"=====(//htmlcode here)=====";
IPAddress ip = WiFi.localIP();
ip.toString() //This is the value that must be diplayed in the HTML that puts the IPaddress there.
R"=====(//rest of HTML code here)=====";

Can anyone help me, because I haven't had any succes implementing variables in HTML with the use of PROGMEM.

I think you mean something like this where you send the first part of the constant text, then send the variable part in the middle, then send the second part of the constant text.

const char firstPart[] PROGMEM = R"=====(//htmlcode here)=====";
const char secondPart[] PROGMEM = R"=====(//rest of HTML code here)=====";

void InAFunction()
{
  client.print((*__FlashStringHelper)firstPart);
  IPAddress ip = WiFi.localIP();
  client.print(ip.toString()); //This is the value that must be diplayed in the HTML that puts the IPaddress there.
  client.print((*__FlashStringHelper)secondPart);
}

The __FlashStringHelper cast is to let '.print()' know that the string is in PROGMEM. I may not have the spelling right.

johnwasser:
I think you mean something like this where you send the first part of the constant text, then send the variable part in the middle, then send the second part of the constant text.

const char firstPart[] PROGMEM = R"=====(//htmlcode here)=====";

const char secondPart PROGMEM = R"=====(//rest of HTML code here)=====";

void InAFunction()
{
 client.print((__FlashStringHelper)firstPart);
 IPAddress ip = WiFi.localIP();
 client.print(ip.toString()); //This is the value that must be diplayed in the HTML that puts the IPaddress there.
 client.print((
__FlashStringHelper)secondPart);
}




The __FlashStringHelper cast is to let '.print()' know that the string is in PROGMEM. I may not have the spelling right.

Let me explain it with the whole code:

// This function returns an HTML formated page in the correct type for display
// It uses the Raw string macro 'R' to place commands in PROGMEM
const char root[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name="description" content="WiFi Meter">
<meta name="keywords" content="Wifi, Meter">
<meta name="author" content="Leonardo van de Weteringh">
<title>WiFi-O-MeTeR</title>
  <style>
    .displayobject{
       font-family: sans-serif;
       margin: auto;
       text-align: center;
       width: 50%;
       border: 3px solid #000000;
       padding: 10px;
       background: #558ED5;
    }
    h1 {
      font-size: 36px;
      color: white;
    }
    h4 {
      font-size: 30px;
      color: yellow;
    }
  </style>
  </head>
  <body>
  <div class = "displayobject">
       <h1>WiFi-O-MeTeR</h1>

       <h4>Time: <span id='P_time'>0</span></h4>
       <h4>RSSI: <span id="RSSIvalue">0</span>%</h4>
       <h4>RSSI: <span id="dBmvalue">0</span>dBm</h4>
<-----HERE MUST COME THE IP ADDRESS----->
       
<a href="/api">API Page </a>
<a href="/login">WiFiOMeTeR UpDaTeR</a>
     </div>
     <script>
       setInterval(function() {getSensorData();}, 100); // Call the update function every half second
  
       function getSensorData() {
          var xhttp = new XMLHttpRequest();
          xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            document.getElementById("RSSIvalue").innerHTML = this.responseText;
          }
        };
        xhttp.open("GET", "RSSIread", true);
        xhttp.send();
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            document.getElementById("dBmvalue").innerHTML = this.responseText;
          }
        };
        xhttp.open("GET", "dBmread", true);
        xhttp.send();
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      }
      function updateTime() {  
   var d = new Date();
   var t = "";
   t = d.toLocaleTimeString();
   document.getElementById('P_time').innerHTML = t;
}
var myVar2 = setInterval(updateTime, 1000);  
     </script>
  </body>
</html>
)=====";

Since the IP address is not dynamic it is useless to make another XMLHTTP requests because the value will never change and it will only cause delay at the other values.

server->on("/", handleRoot); //Index Page
//Index Webpage
void handleRoot() {
  server->send(200, "text/html", root); //Send data to HTML
}

Maybe this will clarify it a bit more :slight_smile:

Another way of doing this is to keep the HTML entirely static. Then leave it to the browser to make a return call to the server to collect and add in all the dynamic data. The browser triggers some javascript in the form's onload event looking something like this:

    // http://stackoverflow.com/questions/3038901/how-to-get-the-response-of-xmlhttprequest
    // needs error handling
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            document.getElementById("jsonIn").value = xhr.responseText  ;
        }
     }
     xhr.open('GET', '/json', false);   // was true
     xhr.send(null);

This populates a field on the form, in this case "jsonIn", with some JSON which represents all the field values. Another piece of Javascript parses that JSON which has been delivered to that field jsonIn, and updates theHTML with the obtained values.

It is a bit more complicated, but then it is easy to lift all the HTML out and use an HTML design tool to make it all pretty.

You can use the send_P method with a static template in progmem that contains placeholders for your values, and a function that returns the values for your placeholders.
See this recent thread, for example https://forum.arduino.cc/index.php?topic=720165

Personally, I prefer 6v6gt's method using static HTML with XMLHttpRequest requests in JavaScript.

Pieter

The problem is, is that the page uses dynamic values as well as static values will be implemented. So I cannot make the page entirely static :slight_smile:

I guess I didn't explain clearly enough the method of populating a static web page with dynamic data obtained in a return call to the server following the initial load. There is an example of it here: https://forum.arduino.cc/index.php?topic=559652.0 (see the three files WebServer* in the source code) However, it is rather complex.

Anyway, if you need a complete example of the simpler "placeholder editing" method, here is another one where the whole PROGMEM resident HTML is dumped out into a String. The placeholders in the String are edited to replace them which the real data then the whole lot sent to the browser.

PieterP:
You can use the send_P method with a static template in progmem that contains placeholders for your values, and a function that returns the values for your placeholders.
See this recent thread, for example https://forum.arduino.cc/index.php?topic=720165

Personally, I prefer 6v6gt's method using static HTML with XMLHttpRequest requests in JavaScript.

Pieter

6v6gt:
Another way of doing this is to keep the HTML entirely static. Then leave it to the browser to make a return call to the server to collect and add in all the dynamic data. The browser triggers some javascript in the form's onload event looking something like this:

    // http://stackoverflow.com/questions/3038901/how-to-get-the-response-of-xmlhttprequest

// needs error handling
   var xhr = new XMLHttpRequest();
   xhr.onreadystatechange = function() {
       if (xhr.readyState == XMLHttpRequest.DONE) {
           document.getElementById("jsonIn").value = xhr.responseText  ;
       }
    }
    xhr.open('GET', '/json', false);   // was true
    xhr.send(null);




This populates a field on the form, in this case "jsonIn", with some JSON which represents all the field values. Another piece of Javascript parses that JSON which has been delivered to that field jsonIn, and updates theHTML with the obtained values.

It is a bit more complicated, but then it is easy to lift all the HTML out and use an HTML design tool to make it all pretty.

I think I will try the first example of Pieter with the send_P and will let you know later if that worked for me :slight_smile: