Saturday, May 21, 2022

Control multiple ESP webservers

For an index to all my stories click this text

Some time ago there was a question posted on Reddit concerning a topic I was just working on so I answered the question: https://www.reddit.com/r/esp32/comments/uok455/is_it_possible_to_control_two_or_more_esp32/
Then I realised that this might need some explanation.

What is this about

Normally when we talk about a webserver in combination with the ESP8266 or ESP32 a program is discussed that puts up a webpage that ca be accessed from your computer, tablet or phone. So the webpage is send (served) from the ESP.
That webpage might contain buttons and/or sliders that control a led, relay, servo, neopixels etc etc etc attached to that same ESP.

This is however not necessary. You can start a webserver on the ESP (be it ESP8266 or ESP32) that does not put up a website but just uses the webserver framework for controlling the led(s). On your PC, tablet or phone you can the run a webpage with some Javascript code that controls the ESP's led(s).

Even better. The Javascript program can control multiple ESP's. And that is what the original poster wanted.

Hardware setup

This wil work with any ESP8266. I used two Wemos D1 Mini's with on both a led connected to pin D5.



So the actual hardware setup is easy. Just a led with a 220 OHM current delimiting resistor attached to D5.

For this test to be conducted properly you will need to build this two times. Although you can perform the test also with just 1 ESP with a led.

Those that follow this weblog regularly might notice that I normally draw my schematics in Fritzing but this one is made in Cirkit Designer. Cirkit has some advantages: like easily add your own components if they are not already in the included library. And just like Fritzing you download the software and work off-line. Check it out: https://www.cirkitstudio.com/

The ESP software.

Have a look at my story on building a webserver with the ESP8266. That example puts a button on a webpage with which you can control a led. You can find that story here: http://lucstechblog.blogspot.com/2019/07/esp-webserver-tutorial-part-2-button.html

I am going to use that program and leave some things out and put something else in. What I am leaving out is the part where the webpage is build. There will be just minimal HTML code.
I added code to receive a value. So the software will not only be able to set a led on or off but also receive a value.
Remember that this is a demonstration of what is possible. So you can add more leds, use the value to control a servo, add a display etc. etc. etc.

As usual I will give you the complete program first and then discus several parts in details.

// ======================================================
// Webserver program that has no webpage and the program
// only handles a received ON-OFF command by putting a
// led on or off.
// next to that it prints a received value 
// in the Serial Monitor.
//
// command is IPADRESS/?cmd=ON
// command is IPADRESS/?cmd=OFF
//
// value is IPADRESS/?val=anynumber
//
// By Luc Volders: http://lucstechblog.blogspot.com/
// ======================================================

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

ESP8266WebServer server(80);

// Your routers credentials
const char* ssid = "XXXXXXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYYY";

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

String ledcmd;
String value;

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

String getPage()
  {
  String page = "<!DOCTYPE HTML>";
  page += "<html>";
  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);
        } 
      if (ledcmd == "OFF")
        {
           digitalWrite(D5, LOW);
        }
      }


   if (server.hasArg("val"))
      {
        value = server.arg("val");
        Serial.print("The received value is:             ");
        Serial.println(value);
      }
    
  server.send(200, "text/html", getPage());       //Response to the HTTP request
}  


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


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

  // 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);
}


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


Now let us look at some details.

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

ESP8266WebServer server(80);

// Your routers credentials
const char* ssid = "XXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYY";


Nothing special here. The Wifi and Webserver libraries are loaded and a webserver is defined which uses port 80. The port number 80 is important in that way that this is the port used for HTTP communication. Further on we are going to build a webpage with Javascript to command the ESP. Javascript communicates over HTTP and therefore the port is 80.

String getPage()
  {
  String page = "<!DOCTYPE HTML>";
  page += "<html>";
  return page;
  }


A minimalistic webpage is build. This is needed for the webserver to operate. If you want you can expand it to a full webpage just as shown in the original program: http://lucstechblog.blogspot.com/2019/07/esp-webserver-tutorial-part-2-button.html
But more as this is not needed.

Skip some parts and look at the setup first.

void setup()
{
  delay(1000);
  Serial.begin(115200);

  // 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);
}


The first part of the setup contains the normal commands to start the Wifi communication. Nothing special in there. It also prints the IP number of the ESP when a connection with the router is established and that is important.

  server.begin();
  server.on("/", handleRoot);

This is where the webserver is started. When "/"is received the program jumps to the handleRoot routine.

The last part in the setup defines pin D5 as an outpit pin and sets it's value to LOW to make sure that the led is off when the program starts.

void handleRoot()
{   
  if (server.args() )
    {
    handlecmdreceived();
    }
}

In the handleRoot routine the program checks if some information is received. And if the received information is more as just "/" then the webserver received args() and the handlecmdreceived() routine is called.

void handlecmdreceived()
{  
   if (server.hasArg("cmd"))
      {
      ledcmd = server.arg("cmd");
      Serial.print("Thereceived command is:             ");
      Serial.println(ledcmd);
      //Serial.print("If it is an integer its value is:        ");
      //Serial.println(buttonON.toInt());
      if (ledcmd == "ON")
        {
           digitalWrite(D5, HIGH);
        }
      if (ledcmd == "OFF")
        {
           digitalWrite(D5, LOW);
        }
      }


   if (server.hasArg("val"))
      {
        value = server.arg("val");
        Serial.print("The received value is:             ");
        Serial.println(value);
      }


      
  server.send(200, "text/html", getPage());       //Response to the HTTP request
}  


This is the most important part of the program.
If the webserver receives some information the first check is if the received information starts with "cmd". If that is true we store whatever is send with cmd in the variable ledcmd.
Then we check wether ledcmd has the value "ON"or "OFF" and according to that we set the led HIGH or LOW

If the received information does not start with "cmd" but starts with "val" the information contains some value. That value is stored in the variable value and printed in the Serial Monitor.

Adapting for your own purpose.

This can easily be adapted for your own purposes. Just look at:

if (server.hasArg("command"))
  {
     variable = server.arg("command");
  }


Exchange "command" for example for servo or temp or whatever information you want to act upon and adapt the software between the brackets for controlling a servo, a fan or whatever you might need.

How to adress the webserver.

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


As you can see 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 send a value the command is:

IPADRESS/?val=value

in which value can be an integer or a floating point value.

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. Notice that you type this command in your web-browser but no web-page is coming up.

My second ESP8266 has IP number 192.168.1.85 so I set the led ON with 192.168.1.85/?cmd=ON from my phone. This proved that the setup worked from any browser.

Attach one of the ESP's to your computer and open the Arduino IDE. Open the Serial monitor and then type in your web-browser 192.168.1.83/?val=1256 Again: replace 192.168.1.83 by your own ESP's IP number.



And here you can see that the ESP indeed received the command val=1256

Basically that is all.

Control both ESP's with Javascript

As we have a good functioning setup and you know the IP numbers from the ESP's you can now detach the ESP from your computer and attach them to a phone's power supply or power bank.

To control the ESP's I will give you here a webpage with a Javascript program.

The command to send data from Javascript to the ESP's webserver is:

fetch('http://192.168.1.83/?cmd=ON')

As you can see it is just the HTTP line we used in the browser put into a fetch() command.

So here is the full webpage that puts 4 buttons on your screen to set the led's of both ESP's on or off.

<!DOCTYPE html>
<html>
<body>

<h2>Control for ESP webserver</h2>
<button onclick="putledon()">First ESP Led ON</button>
<br>
<br>
<button onclick="putledoff()">First ESP Led Off</button>
<br>
<p>====================================</p>
<br>
<button onclick="putledon2()">Second ESP Led ON</button>
<br>
<br>
<button onclick="putledoff2()">Second ESP Led Off</button>
<br>
<br>


<script>
function putledon() 
  {
     fetch('http://192.168.1.85/?cmd=ON')
  }

function putledoff() 
  {
     fetch('http://192.168.1.85/?cmd=OFF');
  }

function putledon2() 
  {
     fetch('http://192.168.1.83/?cmd=ON')
  };

function putledoff2() 
  {
     fetch('http://192.168.1.83/?cmd=OFF');
  }

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


Just as in the ESP's program you need to alter the IP numbers of both ESP's in the Javascript part of the page's code.

Save this code on your computer as espcontrol.html or any name you want to use. The code will be saved as a webpage.



Click on it and your browser will open with the above screen.

Push the buttons and watch the led's on both ESP's go on and off.

Save this webpage on your Android phone and control both ESP's from your phone.

You can easily convert this webpage into an Android App. Building App's for Android is actually easy with Javascript and I am going to show you how to do that in an upcoming story.

Famous last words

This story demonstrated that you can build a webserver on your ESP which does not produce a webpage. The server is just used as a framework for accepting commands.
The server is then controlled from a webpage that runs on a separate computer, tablet or phone.

This can easily be expanded to send more different commands to the ESP's so they can control led's, relays, servo's motors etc. etc. etc. For that to happen you need to make just minor alterations to the ESP's program and to your HTML page with Javascript.

If you want/need more or different example's drop me a not by email.

Till next time
Have fun

Luc Volders