Arduino Web Server: What it is and how to set One Up. Should
you use a Synchronous or an Asynchronous web server? Are either of these
any use for your Arduino Application?
Arduino web server: A web server conjures
up images of huge machines dishing out pages from an underground
bunker...
...But even a small Arduino unit can serve web pages!
You are probably here because you want to find out how to control
your Arduino over the web, and in this tutorial you'll understand the
differences between a synchronous and an ascynchronous web server. In
addition you will learn the limitations of both these things and learn
why websockets can overcome these limitations.
What is a Web Server?
A web server is simply a processor with storage memory connected to
the web, that outputs a web page when it receives a request for a
specific page. Of course, for a global server of the type that ISPs
(Internet Service Providers) use, they need a lot of storage space, and
when a lot of people require access to the same page they need a lot of
processing power to deliver those pages.
An Arduino web server simply retrieves a
stored
piece of html code (the language that describes how to render web pages)
sending that information over the internet to your web browser. The
browser interprets the HTML code displaying it on the screen in readable
format.
One complication is that the HTML code itself often uses
Cascading Style Sheets (CSS) and Javascript to operate the web page. It
means that in order to get the needed operation of the web page you may
need to learn the basics of CSS and Javascript. For the simplest
operations its not too difficult but as things get more complicated it
becomes easier to use an external framework such as Blynk.
You can make a simple webserver using an internet capable
microcontroller. A good choice for that is an ESP32, as it has all the
Wifi hardware ready for you to use. You could of course use an Arduino
Uno with an Ethernet shield, and then connect that to your router using a
cable. The coding for that would be virtually the same but with the
ESP32 you don't need cables.
Synchronous Arduino Web Server
A synchronous web server is a pain in the butt and that's because:
It operates in a blocking manner.
When a request for a page is received it stops all other actions until that request has been completed.
During the current request the synchronous webserver will not respond to any other requests.
During the current request it won't allow any other actions!
From these statements alone you can see that you really should not
use a synchronous web server. It is in fact why most people use an
asynchronous web server.
You may find a use for it, if for instance you need to save memory or
resources, since a synchronous server is easier to implement.
Example Code Synchronous Web Server
Here's an example of a synchronous web server running on an ESP32.
For the code to operate put in your own router name and password.
Once programmed into the ESP32 look at the serial monitor to find out
the IP address of your ESP32. This is the local address assigned by
your router (yours will be different to mine). In my case it is:
IP address: 192.168.0.62
Type the IP address into your browser. This should result in the following text on the browser screen:
Hello from ESP32! SYNC
Note the difference in loop function between sync and async.
You can see, in the synchronous code (above), that the function
server.handleClient() is called in the main loop. This is because the
code is simpler and does not use interrupts or event driven actions so
it has to directly invoke code from the synchronous web server library.
Synchronous web server resources
Sketch uses 758613 bytes (24%) of program storage space. Maximum is 3145728 bytes.
Global variables use 44404 bytes (13%) of dynamic memory, leaving 283276 bytes for local variables.
Asynchronous Arduino Web Server
On the other hand, an asynchronous web server requires use of
interrupts and event driven code, and thus it uses more resources.
However its advantages far outweigh the extra resource usage because:
The server can handle multiple page requests.
The processor can continue with other tasks while waiting for events or responses.
Your code can continue while the asynchronous Arduino web server works
in the background. In addition, if several browsers request the same
page, your Arduino can handle it in a timely manner and deliver those
pages efficiently.
Example Code Asynchronous Web Server
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
constchar*ssid="YourWiFiSSID";
constchar*password="YourWiFiPassword";
AsyncWebServerserver(80);
voidhandleRoot(AsyncWebServerRequest*request){
request->send(200,"text/plain","Hello from ESP32! ASYNC");
}
voidhandleNotFound(AsyncWebServerRequest*request){
request->send(404,"text/plain","404 Not Found");
}
voidsetup(){
Serial.begin(115200);
WiFi.begin(ssid,password);
while(WiFi.status()!=WL_CONNECTED){
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/",HTTP_GET,handleRoot);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("Web server started.");
}
voidloop(){
// Nothing to be done here in an asynchronous server
}
Again enter your own router name and password and type the IP address into the browser. The text you see should is:
Hello from ESP32! ASYNC
Actually it does not look like anything has changed - but a lot more is
going on under the hood. You can see from the resource usage below that
more is being done.
Note the difference in loop function between sync and async.
You can see, in the asynchronous code (above), that the loop()
function is empty. This is because the
code is more complex using interrupts and event driven actions. It means
the asynchronous server is able to operate independently in the
background, while your own program does its thing!
Asynchronous web server resources
Sketch uses 777153 bytes (24%) of program storage space. Maximum is 3145728 bytes.
Global variables use 43100 bytes (13%) of dynamic memory, leaving 284580 bytes for local variables.
Comparison of memory used
In fact using the Asynchronous Arduino web server library increases the Flash usage by:
18540 - nearly 20kBytes.
That is not a lot for an ESP32 since:
(18540/3145728)*100 = 0.59%
If you were using an Arduino Mega 2560 with shield it is :
(18540/ 262,144)*100 = 7%
If you were using an Arduino Uno with a shield it is:
(18540/32768)*100 = 56%
So you probably don't want to use an asynchronous server with an Uno!
A practical (Useless/Informative) Example!
This example is going to show you why both synchronous and asynchronous servers are useless!
The example is going to send data from the ESP32 and send it to the
web page where you can read the value on the browser web page.
You would think that the following code does exactly what you want.
It updates a counter value every second and that value is inserted into the web page
ready for you to read.
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
constchar*ssid="YourWiFiSSID";
constchar*password="YourWiFiPassword";
AsyncWebServerserver(80);
intcounter=0;
voidsetup(){
Serial.begin(115200);
WiFi.begin(ssid,password);
while(WiFi.status()!=WL_CONNECTED){
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/",HTTP_GET,[](AsyncWebServerRequest*request){
Stringmessage="Counter: "+String(counter);
request->send(200,"text/plain",message);
});
server.begin();
}
voidloop(){
counter++;
delay(1000);// Increase the counter every second
}
So what is wrong with this?
Simply put you have to refresh the browser page every time you
want to find out the current counter value. This is an absolute
pain, and for looking at sensor data is really quite useless.
There are only two scenarios that you would do this:
You only want to see the data very infrequently.
You have a resource limited processor and must save memory.
What you really want is to connect the web page dynamically to the
ESP32 so that there is direct communication from the ESP32 to the web
browser and vice versa.
Instant bi-directional Comms
Old AJAX
It used to be that you had to use AJAX...
(Image created using AI has no relationship with the real product).
...No, not that Ajax!
The software AJAX stands for "Asynchronous JavaScript And XML". This code was
specifically designed to allow web pages to be updated without needing
to refresh the entire page, also allowing asynchronous page updates i.e.
exactly what you need to update a sensor reading to a web
page.
The advantage of AJAX is a set of techniques that use existing
technologies such as javascript, XML and JSON and is therefore
compatible with older browsers.
The only problem with AJAX is that it is client centric
meaning that the client (ESP32) must initiate a communication sequence
and requires slightly more work to make bidirectional communication
work. AJAX was initially designed for one way communincation from client
(browser) to server(ESP32). It is however possible to create a two-way
communication using AJAX techniques with more software and more effort
with specific techniques.
New Websocket
New websocket technology overcomes these problems because it allows real-time, bidirectional communication between the ESP32 and the
browser. Websockets may not be supported by older browsers (hence
mentioning AJAX which is supported by older browsers)
Websockets are the way to go if you want to have
real-time, bidirectional communication between the ESP32 and browser (and don't care about users of older browser versions).
Conclusions
For an Arduino Web server there are two options:
A synchronous Arduino Webserver.
An asynchronous Arduino Web Server.
Bottom line:
They are both fairly useless! when you want
to view sensor data in a web browser page!
You do need at least one type of html page server, so use the asynchronous server to serve your HTML pages; but:
If you want real time bi-directional communication:
How to get accurate DHT22 digital humidity sensor readings with an Arduino. Did you know it also measures temperature as Well? Find out why, in this page...
A PIR sensor lets your Arduino sense movement without contact. This tutorial covers PIR sensor basics, connecting one to an Arduino board and coding a motion detector.
Arduino Hall Effect Sensor: Add magnetic sensing superpowers to your Arduino projects with an easy-to-use hall effect sensor. With full code and layout...
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.