Web server on ESP32: how to automatically update and display sensor values ​​from the server?

I have a web server on ESP32 and a home page on this server. I would like to update the sensor values ​​on the home page every x seconds automatically (without user input). I can not access the file system.

The sensor is connected directly to the ESP32. The sensor values ​​are in my C program, stored in variables, and regularly updated. Variables are global for easier use.

I was thinking about Ajax (I have no experience), but all the examples and methods that I can find use the file to load data from (in the url'-part of XMLHttpRequest (). Open (... url ..) ..) ) I don't have a file, but only lines in which HTML and Javascript code is generated and sent to the client.

I don’t know how to update my values ​​and hope for some help.

I was thinking of trying something like examples from w3schools, but I don't know how to get the values ​​there:

Example from another page (I do not use this code - I cannot use files!)

function loadDoc() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.responseText; } }; xhttp.open("GET", "ajax_info.txt", true); xhttp.send(); } 

Here is the code from my ESP program:

HTML lines:

 String html_document() { String sHTML; sHTML = "<!doctype html>"; sHTML +="<html>"; sHTML +="<html lang=\"de\">"; /***************** head ****************/ sHTML +="<head>"; /****** avoid favicon requests ** ** <link rel=\"shortcut icon\" href=\"data:image/x-icon;,\" type=\"image/x-icon\"> **/ sHTML +="<link rel=\"icon\" href=\"data:;base64,iVBORw0KGgo=\"> "; sHTML +="<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"; //Anpassung an Viewport für unterschiedliche Devices /***************** title ***************/ sHTML +="<title>LetsgoING IoT</title>"; sHTML +="<style>h1{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; sHTML +="<style>h1{ color: green;}</style>"; sHTML +="<style>h2{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; sHTML +="<style>h2{ color: blue;}</style>"; sHTML +="<style>h5{display: flex; flex-flow: row wrap; justify-content: center;} </style>"; sHTML +="<style>p{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 3%;} </style>"; sHTML +="<style>p1{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>"; sHTML +="<style>p2{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>"; sHTML +="</head>"; /***************** body ****************/ sHTML+= "<body>"; //onload=\"window.setInterval(updateDiv, 15000);\" sHTML+= "<h1>LetsgoING</h1>"; sHTML+= "<h2>Internet der Dinge</h2>"; sHTML+= "<p1><a style=\"width:38%;\"></a><a style=\"width:20%;color: green\">LED ein</a> <a style=\"width:15%;\" href=\"LEDON\"><button> EIN </button></a> </a><a style=\"width:27%;\"> </a></p1>"; sHTML+= "<p><a style=\"width:38%;\"></a><a style=\"width:20%;color: red\" >LED aus</a> <a style=\"width:15%\"; href=\"LEDOFF\"><button>AUS</button></a><a style=\"width:27%;\"> </a></p>"; sHTML+= "<h5>RGB-LED PWM-Werte</h5>"; sHTML+= "<form><p2>"; sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: red\"> Rot</a> <a style=\"width:15%;\" ><input name=\"rot\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\" ></a><a style=\"width:27%;\"> </a>"; sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: green\">Grün</a><a style=\"width:15%;\" ><input name=\"gruen\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>"; sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: blue\">Blau</a> <a style=\"width:15%;\" ><input name=\"blau\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>"; sHTML+= "</p2>"; sHTML+= "<p><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> </a> <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>"; sHTML+= "</form>"; sHTML+= "<h5>analoger Schwellwert</h5>"; sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"schwell\" type=\"number\" min=\"0\" max=\"1024\" step=\"10\" value=\"300\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>"; //sHTML+= "<p><a style=\"width:28%;\"></a> <a style=\"width:30%;\"> </a> <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>"; sHTML+= "</form>"; sHTML+= "<h5>PWM-Wert</h5>"; sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"pwm\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"0\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>"; sHTML+= "</form>"; sHTML+= "<h5>Messwerte</h5>"; sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an1\"; style=\"width:20%;\" href=\"anlg1\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 36 </a><a style=\"width:20%;\"></a></p>"; sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an2\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 39 </a><a style=\"width:20%;\"></a></p>"; sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"dig\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Digitaler Pin 5 </a><a style=\"width:20%;\"></a></p>"; sHTML+= "</body>"; sHTML+= "</html>"; return sHTML; } 

Loop:

 void loop() { if (millis() - startTime >= 2000) { startTime = millis(); /* Check if a client has connected */ client = server.available(); if (!client){ return; } /*Wait for the client to send data */ Serial.println("neuer Client verbunden------------------------------"); /*Count requests: */ request_counter ++; unsigned long clTimeout = millis()+250; while(!client.available() && (millis()<clTimeout) ) { delay(1); } /*** publish Homepage ***/ client.print(html_document()); /* Read the first line of the clients request string "sHTML" until carriage return \r */ sHTMLRequest = client.readStringUntil('\r'); #ifdef DEBUGMODE Serial.println("Antwort: "); Serial.println(sHTMLRequest); #endif client.flush(); /* stop client, if request is empty */ if(sHTMLRequest=="") { Serial.println("Leere Anfrage! - client gestoppt"); client.stop(); return; } #ifdef DEBUGMODE Serial.println("Antwort2: "); Serial.println(sHTMLRequest); Serial.println ("---------"); Serial.print("DEBUG: Remote IP - Address : "); for (int i = 0; i < 3; i++) { Serial.print( client.remoteIP()[i]); Serial.print("."); } Serial.println(client.remoteIP()[3]); Serial.print("Seitenaufrufe: "); Serial.println(request_counter); Serial.println ("---------"); #endif /**** call event handler **********/ eventHandler(); #ifdef DEBUGMODE Serial.println("Zugewiesene PWM-Werte"); Serial.print("rot: "); Serial.println(rot); Serial.print("gruen: "); Serial.println(gruen); Serial.print("blau: "); Serial.println(blau); #endif /* write PWM values for colors to channels*/ ledcWrite(1, rot); ledcWrite(2, gruen); ledcWrite(3, blau); #ifdef DEBUGMODE Serial.println(analog1); #endif } UpdateValues(); } /**** reads pin values **/ void UpdateValues() { analog1 = analogRead(pinAnalog1); analog2 = analogRead(pinAnalog2); DigiOut = digitalRead(LEDpin); } 

Here is a function that updates the values ​​and creates a JSON string:

 void UpdateValues() { analog1 = analogRead(pinAnalog1); analog2 = analogRead(pinAnalog2); DigiOut = digitalRead(LEDpin); String strJson; strJson = "(200,\"application/json\",\"{\"pin36\": "; strJson+=analog1; strJson+=", \"pin39\":"; strJson+= analog2; strJson+=", \"pin5\": "; strJson+=DigiOut; strJson+="}\")"; server.print(strJson); } 
+5
source share
1 answer

Option 1 :

The easiest way is to ask for a page refresh every 5 seconds by adding it to the <head> :

 sHTML +="<meta http-equiv=\"refresh\" content=\"5\">"; 

Then change the sHTML line to combine the values ​​of your global variables. Each time a page is refreshed, it (should) restore html and return the last values.

Option 2 :

You can use ajax to get the latest values, and then often update a small section of the webpage that displays the data.

What happens here, you configured your ESP32 to provide a second url that only returns the latest values ​​as a json object. Then the values ​​are entered on the page, overwriting the old ones.

First add the jQuery link in the <head> :

 sHTML +="<script src=\"https://code.jquery.com/jquery-3.2.1.min.js\"></script>"; 

In the <body> add spans with identifiers to hold the values ​​to be updated. Sort of:

 sHTML+= "<h5>Messwerte</h5>"; sHTML+="<p>Analoger Pin 36</p>&nbsp;<span id='pin36'></span>"; sHTML+="<p>Analoger Pin 39</p>&nbsp;<span id='pin39'></span>"; sHTML+="<p>Analoger Pin 5</p>&nbsp;<span id='pin5'></span>"; 

Create sHTML for the following javascript that makes an ajax request every 5 seconds and updates the latest values ​​in the browser:

 <script> $(function() { // request data every 5 seconds setInterval(requestData, 5000); function requestData() { // ajax request for latest sensor data $.get("/sensors") .done(function(data) { console.log(data); // debugging - remove when satisfied if (data) { // if the returned data is not null, update the values $("#pin36").text(data.pin36); $("#pin39").text(data.pin39); $("#pin5").text(data.pin5); } else { // a problem occurred $("#pin36").text("?"); $("#pin39").text("?"); $("#pin5").text("?"); } }).fail(function() { console.log("The was a problem retrieving the data."); }); } }); </script> 

When you find the line /sensors in sHTMLRequest , you want to return the following json format:

{"pin36": 5.2, "pin39": 0.322, "pin5": 1}

At this point, I don’t know enough about your setup to advise too much further, but these links hopefully help with the C code: http://www.iotsharing.com/2017/05/how-to-turn-esp32- into-web-server.html and http://randomnerdtutorials.com/esp32-web-server-arduino-ide/

If you use ESP32WebServer.h from https://github.com/nhatuan84/esp32-webserver (see second half http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web -server.html for more details), you can use something like:

 server.on("/sensors", handleSensorData); 

with

 /* this callback will be invoked when user request "/sensors" */ void handleSensorData() { /* server responds 200 with a json payload */ /* although preferably concatenate your real sensor data here */ server.send(200, "application/json", "{\"pin36\": 5.2, \"pin39\": 0.322, \"pin5\": 1}"); } 
+2
source

Source: https://habr.com/ru/post/1269302/


All Articles