Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / IoT / Arduino

Connect ESP32 Board via Browser

5.00/5 (6 votes)
7 Apr 2021CPOL3 min read 22.8K   487  
Board based automation and environment control
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.

C++
...
#include <WiFi.h>
#include <WebServer.h>
...
// SSID & Password ******************************************************
const char* ssid = "Sermig_Condor";
const char* password = "";
// IP Address ***********************************************************
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WebServer server(80);  // Object of WebServer(HTTP port, 80 is default)
...

The interesting part starts in the setup function:

C++
void setup() {
...
  // Create SoftAP
  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)):

C++
void loop() {
    while (Serial.available() > 0) {
      char cmd = Serial.read();
      if (cmd == 115) listen = !listen;	// s start/stop listening
      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.
C++
void handle_root() {
  if (server.args() == 0) {    
     server.send(200, "text/html", H+T); // Handle root url (/)
  } else {
    char command = server.arg("c").charAt(0);
    char answer[50];
    switch (command) {
      case 104:        // h set time
        setTime(server.arg("n").toInt());
        sprintf(answer,"%s","New time");
        break;
      case 116:        // t temperature and humidity
        getTemperature();
        strcpy (answer,workBuffer);
        break;
    }
    sprintf(workBuffer, "%s %s", getTime(),answer);
    Serial.println(workBuffer);
    server.send(200, "text/html",workBuffer);
  }
}
HTML
<!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 preformatted tag for receiving the answers.

The Ajax function when it receives the data, adds it directly to the preformatted 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)