Async Simple String Data to Webpage

Hi, after several days trying different websocket programs, never finding
one that wpould compile due to lib updates, misidentified libs, I found one
that comes close.

Idea is ~ 21 lines, simple text data, to be sent to page.

  1. I can get numeric converted to string to print 1 and only 1 line,
    but never feeding a standard string var in the send. Only one
    when it converts a numeric using String() does it display

  2. Note there are two sends here, as a test, only 1 gets displayed
    on webpage.

const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<style>
.card{
    max-width: 400px;
     min-height: 250px;
     background: #02b875;
     padding: 30px;
     box-sizing: border-box;
     color: #FFF;
     margin:20px;
     box-shadow: 0px 2px 18px -4px rgba(0,0,0,0.75);
}
</style>
<body>

<div class="card">
  <h4>The ESP32 Update web page without refresh</h4><br>
  <h1>Sensor Value:<span id="adcValue">0</span></h1><br>
  <br><a href="https://circuits4you.com">Circuits4you.com</a>
</div>
<script>

setInterval(function() {
  // Call a function repetatively with 2 Second interval
  getData();
}, 2000); //2000mSeconds update rate

function getData() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("adcValue").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "readADC", true);
  xhttp.send();
}
</script>
</body>
</html>
)=====";

index.h page above in project for formatting

below code segment sending data to page

void handleADC() {
 delay(5000);
 testval++;
 String adcValue = String(testval);
 //int a = analogRead(A0);
 //String adcValue = String(a);
 
 server.send(200, "text/plane", adcValue);  //Send ADC value only to client ajax request
 testval++;
 adcValue = String(testval);
 delay(1000);
 server.send(200, "text/plane", adcValue);  //Send ADC value only to client ajax request
}

main -

/*
 * ESP32 AJAX Demo
 * Updates and Gets data from webpage without page refresh
 * https://circuits4you.com
 */
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>

#include "index.h"  //Web page header file

WebServer server(80);

//Enter your SSID and PASSWORD
const char* ssid = "xxx";
const char* password = "xxxx";

int testval = 0;

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

void handleADC() {
 delay(5000);
 testval++;
 String adcValue = String(testval);
 //int a = analogRead(A0);
 //String adcValue = String(a);
 
 server.send(200, "text/plane", adcValue);  //Send ADC value only to client ajax request
 testval++;
 adcValue = String(testval);
 delay(1000);
 server.send(200, "text/plane", adcValue);  //Send ADC value only to client ajax request
}

//===============================================================
// Setup
//===============================================================

void setup(void){
  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");

/*
//ESP32 As access point
  WiFi.mode(WIFI_AP); //Access Point mode
  WiFi.softAP(ssid, password);
*/
//ESP32 connects to your wifi -----------------------------------
  WiFi.mode(WIFI_STA); //Connectto your wifi
  WiFi.begin(ssid, password);

  Serial.println("Connecting to ");
  Serial.print(ssid);

  //Wait for WiFi to connect
  while(WiFi.waitForConnectResult() != WL_CONNECTED){      
      Serial.print(".");
    }
    
  //If connection successful show IP address in serial monitor
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //IP address assigned to your ESP
//----------------------------------------------------------------
 
  server.on("/", handleRoot);      //This is display page
  server.on("/readADC", handleADC);//To get update of ADC Value only
 
  server.begin();                  //Start server
  Serial.println("HTTP server started");
}

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void loop(void){
  server.handleClient();
  delay(1000);
}

Any and all help greatly appreciated.

Regards, Dana.

I as able to correct getting the first string printed on page, still
the second send still not showing up on webpage.

Note in index.h name of variable as edited to "MyStrg"

void handleADC() {

 String MyStrg = "This is a pump";
 server.send(200, "text/plane", MyStrg);  //Send ADC value only to client ajax request
 
 MyStrg="Pump Off";
 server.send(200, "text/plane", MyStrg);  //Send ADC value only to client ajax request
 delay(100);
}

It won't work that way: one request yields one response.

But first, it's 2025: use fetch

// Call a function repetatively with 2 Second interval
setInterval(getData, 2000);

function getData() {
  fetch("/readADC")
    .then(response => response.status == 200 ? response.text() : response.statusText)
    .then(text => {
      document.getElementById("adcValue").innerText = text;
    })
}

First, if the response is 200, then continue to fetch the body as text with text(). If not, then the statusText (e.g. "Not Found") is resolved immediately.

Next, if the text is not actually HTML, then setting innerText is faster and safer than setting innerHTML

Irrelevant

  • the variable name used in your C++ sketch gets "compiled away"
  • no variable name goes "over the wire" -- good thing, because there is none
  • it's not clear which variable in the index.h you mean -- MAIN_page, xhttp adcValue (not a variable) -- but still irrelevant, because things aren't automatically linked that way.

And the content-type is text/plain, not "plane".

If you want 21 items to appear on the page, the easiest way is to have 21 <span>s, each with a unique id. Then the single response value would have the 21 values, each encoded as a separate field named with those IDs in a single JSON object. Then the content-type would application/json

{
  "adcValue": 42,
  "MyStrg": "This is a pump",
  "My2ndStrg": "Pump off",
  "MyOtherValueWithABetterName": "etc"
}

Then in the getData function, a loop can grab those names with the corresponding value and set the innerText

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.