In this article, you will find a solution based on WiFi WEB server running on a ESP32 board developed with Arduino IDE 1.8.12.
Introduction
This article is a personal search on how one can interact with the single-board micro controllers like Arduino or ESP32 in order to control the functionality of the process in act.
Those devices can interact with the external world in many ways: by serial port, by LCD, by communications protocols like Bluetooth and Wi-Fi.
Serial port needs a cable linked to a PC or to a mobile phone; LCD is an output device so it needs some input devices; Bluetooth and WiFi are bidirectional and without cables.
For accessing a board by Bluetooth, we need a program on the inspecting device; with WiFi acting as WEB server, we can access the board by a browser being the control program downloaded from the board as HTML page containing JavaScript instructions.
In this post, I show a solution based on WiFi WEB server running on a ESP32 board developed with Arduino IDE 1.8.12. I have tried to create a not too trivial application to highlight the salient features of the connection: the application can show temperature and humidity, read by a three wire sensor DHT22, and can modify an internal clock.
Starting with WiFi
WiFi can be programmed acting in an existing WiFi network or, and is what is concerned here, like an Access Point. In all cases, we need two libraries: the WiFi.h library is used to set up the WiFi section and WebServer.h library to build a web page.
Here, I talk briefly on the instructions needed to realize the server, there are many pages on the Internet which illustrate them very well, instead, I will focus on the features that allow to create an effective application without excessive aesthetic concerns. In any case, you can refer to the attached source which, I hope, is self explanatory.
...
#include <WiFi.h>
#include <WebServer.h>
...
const char* ssid = "Sermig_Condor";
const char* password = "";
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WebServer server(80); ...
The interesting part starts in the setup
function:
void setup() {
...
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
...
server.on("/", handle_root);
server.onNotFound([](){server.send(404, "text/plain", "The content was not found.");
});
server.begin();
...
}
The WebServer
emulates an application event driven, i.e., server.on("/", handle_root)
attaches a function to a request, in the above case, the request of getting the root page "/"
will be satisfied by the function handle_root
. We can attach function at every "page" which the server must eventually provide and also attach a function to an unknown request: server.onNotFound([](){server.send(...);});
.
Interacting with WiFi
In the loop function, there is the listen
instruction together with a delay for simulating a board functionality, i.e., a temporized loop on controls, sensors, etc.
The serial communication is used to simulate an interrupt to activate WiFi that it needs constant listening (notate the little delay(10)
):
void loop() {
while (Serial.available() > 0) {
char cmd = Serial.read();
if (cmd == 115) listen = !listen; Serial.println(listen?"WEB on":"WEB off");
}
if(listen) server.handleClient();
else delay(1980);
delay(10);
}
The function that manages the request (at the right) isn't particularly interesting.
The number of parameters present in the url, obtained by the method args() , discriminate the request, i.e., if the number is 0 , the root page is sent with the JavaScript (see below the HTML page and the JavaScript code put in a more readable form), otherwise, it is (probably) an Ajax request and by the method arg("c") , the function retrieves and executes the desired command. |
void handle_root() {
if (server.args() == 0) {
server.send(200, "text/html", H+T); } else {
char command = server.arg("c").charAt(0);
char answer[50];
switch (command) {
case 104: setTime(server.arg("n").toInt());
sprintf(answer,"%s","New time");
break;
case 116: getTemperature();
strcpy (answer,workBuffer);
break;
}
sprintf(workBuffer, "%s %s", getTime(),answer);
Serial.println(workBuffer);
server.send(200, "text/html",workBuffer);
}
}
|
<!DOCTYPE html>
<html>
<meta name='viewport' content='width=device-width, initial-scale=1' />
<body>
<h1>Condor Web Server with ESP32 - AP Mode</h1>
<input type=button value='Set time' onClick='ajx("c=h&n="+$("n").value)'/>
<input type=number id=n value='36000'/>
<p><input type=button value='Get temp.' onClick='ajx("c=t")'/>
<pre id='f'></pre>";
</body>
</html>
<script type='text/javascript'>
$=i=>document.getElementById(i);
ajx=u=>{
var x = new XMLHttpRequest();
x.onreadystatechange = () => {
if (x.readyState == 4) {
if (x.status == 200) $('f').innerHTML += '\\n'+x.responseText;
else $('f').innerHTML = 'Err: ' + x.status;
}
};
x.open('GET', '?'+u, true);
x.send(null)
}
</script>
The meta
tag tells the browser to adapt to the client size so in mobile phone, the page is acceptable. The page contains two buttons, with associated onClick
event, a text input number and a pre
formatted tag for receiving the answers.
The Ajax function when it receives the data, adds it directly to the pre
formatted tag.
Accessing the Board
The inspecting device must connect the WiFi board (through the App Setting
in the section Network and Internet
) and in the browser insert the IP, in this example is 192.168.1.1
; it should appear a page where the user can ask the temperature and humidity or set the clock inputting the number of seconds from midnight.
Final Remarks
I am a novice in the field of automation, therefore any question, criticism or suggestion is welcome.
History
- 17th June, 2020: Initial version