Friday, October 6, 2023

ESP8266 send data to a webpage

For an index to all my stories click this text.

Normally when you run a webserver on your ESP you can adress that ESP to send commands to it. The ESP has a webserver that sends a webpage to your device (pc, tablet, phone). To command several ESP's that way is not easy. You need to re-open the browser on your device to get the webpage's from each individual ESP.

In a previous story I adressed this problem and showed how you could build a webpage with Javascript that adressed several ESP's and send commands to them. That webpage runs on your PC, tablet or phone. So NOT on the ESP itself. The ESP's are running a webserver that actually does not serve a webpage. Only the framework is used to receive commands from the webpage on your PC. Yoy can re-read that story here http://lucstechblog.blogspot.com/2022/05/control-multiple-esp-webservers.html

Getting information back.

As this works great I have used it in several of my projects. But it is a one-way-road. You can send only information to the ESP's. Well actually no. You can also get information from the ESP's back like a temperature or a confirmation that the information has been received.

Simply said: Set a switch on the webpage ON and the chosen ESP will set a led, relay, motor, fan etc etc on. Then the ESP will send back a confirmation that the led is indeed set on. Another example is to send a request to the ESP and the ESP sends the temperature or any other value or sensor reading back.

To achieve this the ESP sends a webpage back to the webpage it was getting the request from (the PC, tablet, phone). And that webpage that is send is just one line of text with the information we need.

Sounds complicated and actually it is not. Bear with me, and this story shows how to do this.

I am gong to show you how to send a random value to the Javascript page on your PC. To make it a bit lifelike I am going to pretend that that random value is a temperature reading from a sensor.

The hardware setup

Nothing special here.



Just an ESP8266 Wemos D1 mini with a current delimiting resistor attached to I/O pin D5. This is exactly the same setup as used in the previous story: http://lucstechblog.blogspot.com/2022/05/control-multiple-esp-webservers.html

The ESP8266 code

Actually this is also basically the same code as the code used in the previous story: http://lucstechblog.blogspot.com/2022/05/control-multiple-esp-webservers.html with some minor expansions.
Please re-read that story because I am only going to discus the alterations.

here is the full code:

// ======================================================
// Webserver program that has a simple webpage and the 
// program only handles a received ON-OFF command by 
// putting a led on or off.
// command is IPADRESS/?cmd=ON
// command is IPADRESS/?cmd=OFF
//
// value is IPADRESS/?TEMP
//
// this command prints a random value in the
// Serial monitor and sends that value
// back to the Javascript page that accessed the server.
// for that see Fetch-webserv2-4.html
// http://lucstechblog.blogspot.com/
// ======================================================

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

// Your routers credentials
const char* ssid = "XXXXXXXXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYYYYYY";

// ==========================================
// initial variables
// ========================================== 

String ledcmd;
String value;

const int analogInPin = A0;

// =========================================
// Here is the HTML page
// =========================================

String getPageON()
  {
  String page = "The led is set ON";
  return page;
  }

String getPageOFF()
  {  
  String page = "The led is set OFF";
  return page;
  }  

String getPageTEMP()
  {  
  String page = "The temperature is ";
  value = String(random(25));
  page += value;
  Serial.println(page);
  return page;
  }   



// ==================================================
// Handle submit form
// ==================================================
void handlecmdreceived()
{  
   if (server.hasArg("cmd"))
      {
      ledcmd = server.arg("cmd");
      Serial.print("Thereceived command is:             ");
      Serial.println(ledcmd);
      if (ledcmd == "ON")
        {
           digitalWrite(D5, HIGH);
           server.sendHeader("Access-Control-Allow-Origin", "*");
           server.send(200, "text/html", getPageON());       //Response to the HTTP request
        } 
      if (ledcmd == "OFF")
        {
           digitalWrite(D5, LOW);
           server.sendHeader("Access-Control-Allow-Origin", "*");
           server.send(200, "text/html", getPageOFF());       //Response to the HTTP request
        }
        
      }
      
      if (server.hasArg("TEMP"))
           {
           server.sendHeader("Access-Control-Allow-Origin", "*");
           server.send(200, "text/html", getPageTEMP());       //Response to the HTTP request
           }  
}  


// ===================================================
// Handle root
// ===================================================
void handleRoot() 
{   
  if (server.args() ) 
    {
    handlecmdreceived();
    } 
}


// ===================================================
// Setup
// ===================================================
void setup()
{
  delay(1000);
  Serial.begin(9600);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid,password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
  server.on("/", handleRoot);

  server.begin();
  delay(500);

  pinMode(D5, OUTPUT);
  digitalWrite(D5,LOW);

  randomSeed(analogRead(analogInPin));
}


// ===================================================
// Loop
// ===================================================
void loop()
{  
  server.handleClient(); 
  delay(50);
}

If you are going to copy this code replace the XXXXX and YYYY with your own routers name and password.

I am only going to discus the expansions from the previous code here in some detail.

const int analogInPin = A0;


This line makes the program aware that the analog pin on the ESP8266 is A0. We are not going to do anything special with this analog pin. It is only used to get a seed for the random function.

String getPageON()
  {
  String page = "The led is set ON";
  return page;
  }

String getPageOFF()
  {  
  String page = "The led is set OFF";
  return page;
  }


The variable page will hold the very simple webpage we are going to send back to the requesting webpage on your PC.
Three different webpages will be build in this example. The first page is a confirmation that "The led is set ON"
The second page is a confirmation that the "The led is set OFF"

String getPageTEMP()
  {  
  String page = "The temperature is ";
  value = String(random(25));
  page += value;
  Serial.println(page);
  return page;
  } 


This is the third webpage which will send the fake temperature value to the HTML page with Javascript.
The string variable value will get a random value between 0 and 25. This value is put into the page string together with the text "The temperature is "

On your PC there will be a webpage with a Javascript program that will send the commands:
fetch('http://ESP8266-IP-ADRESS/?cmd=ON')
fetch('http://ESP8266-IP-ADRESS/?cmd=OFF')

To set the led on or off. What the ESP8266 has to do is to analyse that incoming command and send a confirmation that the command has been received and processed.

      if (ledcmd == "ON")
        {
           digitalWrite(D5, HIGH);
           server.sendHeader("Access-Control-Allow-Origin", "*");
           server.send(200, "text/html", getPageON());       //Response to the HTTP request
        } 



And this is where the magic happens.

If the received command is ON then first the led is set ON.

Next a header is send to the requesting webpage with the following text: "Access-Control-Allow-Origin", "*"

Normally we do not use this if the webserver is coming from the same ESP as where the requests are coming from. But in this case we are using a PC to send commands to the ESP8266 and that PC is expecting an answer. The PC and the ESP8266 have different IP adresses and therefore this is absolutely necessary cause this tells the Javascript code on the requesting page to accept information from another IP adress. Without this command Javascript will not accept any information coming from the ESP8266.

And lastly the server.send command sends the string build in the getPageON() routine.

The same code with some minor alterations is used when the OFF command is received, and also when the TEMP command is received.

How to adress the webserver

Program your ESP with this software and open the Serial monitor.



My ESP got the IP number 192.168.1.83

The general command to set the led on is:

IPADRESS/?cmd=ON

and to set the led off:

IPADRESS/?cmd=OFF

To get the fake temperature made by the random function use this command:

IPADRESS/?TEMP

A first test.



To test wether everything works as expected open a webbrowser on your PC or phone and type in the adress bar: 192.168.1.83/?cmd=ON and the led should go on.

You need to replace 192.168.1.83 with the IP number your ESP displayed in the serial monitor. Typing this command will put the text The led is set ON on your webpage. And of course the led on the ESP8266 will go ON.



The command 192.168.1.83/?cmd=OFF will set the led of and also put the text The led is set OFF on the webpage.


Putting http://192.168.1.83/?TEMP in the browsers adress bar will set the text The temperature is 10 on your webpage. The number 10 will be different every time you give this command. It will be the random generated value from 0 to 25.

If this all works then we have accomplished sending a command to the ESP8266 and receiving information back !!!!

Control the ESP8266 from a webpage

Now that we can control the ESP8266 from our browser the next step is to build a simple webpage that controlls the ESP8266.

The webpage consists of some html code and some Javascript. Nothing to fancy to keep things as simple as possible. Basically this is the same code as used in the previous story. Left out are the commands for a second ESP and added are the code for displaying the fake random temperature values.

<!DOCTYPE html>
<html>
<body>

<h2>Control for ESP webserver</h2>

The ESP led is <output id="ledstat1"> ?? </output>
<br>
<br>
<button onclick="putledon()">ESP Led ON</button>
<br>
<br>
<button onclick="putledoff()">ESP Led Off</button>
<p>=======================================</p>
<h2>Temperature</h2>
<button onclick="gettemp()">Get Temperature</button>
<p id="gettemp"></p>

<script>

var rectext;
var first;
var second;
var led1stat;

function putledon() 
{
     fetch("http://192.168.1.83/?cmd=ON").then(function(response) 
      {
     return response.text().then(function(text) 
         {
         [first, second]=text.split("set ");
         document.getElementById("ledstat1").innerHTML = second;
         });
      });
  }

function putledoff() 
{
     fetch("http://192.168.1.83/?cmd=OFF").then(function(response) 
      {
     return response.text().then(function(text) 
         {
         [first, second]=text.split("set ");
         document.getElementById("ledstat1").innerHTML = second;
         });
      });
  }

function gettemp() 
  {
     fetch("http://192.168.1.83/?TEMP").then(function(response) 
      {
     return response.text().then(function(text) 
         {
         [first, second]=text.split("is ");
         document.getElementById("gettemp").innerHTML = second;        
         });
      });
     
  }

</script>
</body>
</html>


It is beyond the intention of this story to give you a complete course on HTML and Javascript but I will highlight some important parts in this code which are different from the code of the previous story.

Firts (of course) you will need to exchange the ESP's IP-adress for the one you found in the serial monitor when the ESP8266 boots.

Copy the code and paste it on your PC in a text editor like notepad and then save this code on your computer as espcontrol.html or any name you want to use. The code will be saved as a webpage.

Clicking that file will open your default web-browser and show the just created webpage.

That webpage is obviously NOT running on your ESP but running on your PC (or Raspberry or Phone or tablet etc). But it will send and receive commands from the ESP.

function putledon() 
{
     fetch("http://192.168.1.83/?cmd=ON").then(function(response) 
      {
     return response.text().then(function(text) 
         {
         [first, second]=text.split("set ");
         document.getElementById("ledstat1").innerHTML = second;
         });
      });
  }



The fetch command is a lot more complicated as the command used in the previous story. That is because the ESP8266 is sending an answer back which has to be processed.

After the fetch command is send to the ESP8266 a response is received and that response is stored in the variable text.

Next step is to split the at the word "set " (don't forget the space behind set). This is because the ESP sends the sentence The led is set ON and we need the part after set.

At this moment the variable second contains the value ON or OFF and that is placed on the webpage at the <output> tag which has the ID ledstat1.

Almost the same code is used for the command to set the led OFF and the command to get the temperature.

The webpage in Real Life

Here is how the page will look in your browser.



As you can see initially the state of the led is unknown and no temperature information is available.



And after pressing the ESP led ON button and Get Temperature button this is what the page looks. The state of the led is now displayed and the temperature is fetched.

So there we have it. An independend webpage that runs on your PC, Raspberry Pi, Phone or Tablet that sends commands to your ESP8266 and receives information back.

Adapt this to your own needs.

Again look to the previous story: http://lucstechblog.blogspot.com/2022/05/control-multiple-esp-webservers.html
Studying that story combined with the code from this story makes it possible to command several ESP's from a central webpage running on your PC, Raspberry, Phone or Tablet.

The previous story also showed how to send not just ON/OFF commands to the ESP8266 but also how to send values to the ESP8266. Use that to dim a led/lamp or to set a servo at a certain position, or control the speed of a motor, build a remote controlled car etc. etc.

You can combine : http://lucstechblog.blogspot.com/2019/08/esp-webserver-tutorial-part-4-slider.html with this story to put sliders in your webpage and send their value to the ESP8266.

The ESP8266 code can easily be altered to get real temperature values from a Dallas DS18B20 for example, or door sensors or light sensors etc. etc. etc.

Multiple sensors can be attached to one ESP or like stated before you can have one webpage control a multitude of ESP's.

Javascript is a very extensive language and the program can be made so that the ESP's are polled automatically for example every 30 seconds to get the status of important sensors.



If you are interested in Javascript please consider buyimg my book. The book is not a course or tutorial on Javascript but contains more than 500 tips for working with time and dates, sorting, objects, html manipulation etc. etc. etc. The book is available through your local bookshop and Amazon. 

Amazon link: Javascript tips by Luc Volders

Click on the picture of the book or on the previous link to order this book. As I do not have advertisements on these pages a donation or buying one of my books is the best way to support me.

Future plans

Wel I am using this in a real-life project which I am building at the moment and that will be a furure story.

Another thing coming up is how to easily convert an HTML page with Javascript into an Android App.

So a lot of things coming up. Stay tuned and have fun

Luc Volders