Simple Logistic Regression in C/C++ (ESP32 Arduino) with Embedded Web Application

Introduction

In the previous tutorial, we have built a simple linear regression model for predicting rain in C. Then, we have implemented the system in ESP32 Arduino. We have used humidity value fetched by DHT11 sensor as input in inference process (prediction).

System Overview

The following figure shows the block diagram of this tutorial. We have got the ESP32 DevKit v1 board connected to the WiFi access point (AP). Then, we have an embedded web server runs on the ESP32. The development host is connected to the the same AP. Then, we can use a web browser to make an HTTP request to the web server. After that, the web server sends an HTTP response which contains the web page. The web page displays the rain prediction result that is calculated on the ESP32 web server.

Schematic Diagram

The following figure shows the schematic diagram of the ESP32 (in this case, I use the ESP32 DevKit v1).

  • First, connect the VCC and GND from ESP32 to DHT11.
  • Second, connect a GPIO (in this case, I use D4, you can use other pins) from ESP32 to the data pin of DHT11.
  • Third, connect a 10k resistor from the VCC to the GPIO.

Recommended reading: ESP32 DHT11/DHT22 Web Server – Temperature and Humidity using Arduino IDE

Arduino Library

In order to follow this tutorial, we need the following libraries installed:

  • Adafruit unified sensor
  • DHT sensor library
  • ESPAsyncWebServer
  • AsyncTCP for ESP32
Arduino Sketch

In this section, we are going to build an embedded web server that can predict whether it is going to rain or not based on real-time humidity value from DHT11 sensor. The Arduino sketch consists of three parts: logistic regression, DHT11 sensor, and web server. The following code shows the complete Arduino sketch.

Logistic Regression

First, let us define the sigmoid function and predictRain function in line 96-99 and line 101-108, respectively. In predictRain function, we define the \(\theta_{0}\) and \(\theta_{1}\) as theta_0 and theta_1. Then, we initialize them with pre-trained values in line 103-104.  After that, we define the hypothesis function in line 105. Finally, we return the rounded prediction as string in line 107.

DHT11 Sensor

Second, let us configure the DHT11 and create a function for reading humidity value. In line 9-10, we define the DHT GPIO pin and DHT type. Then, in line 15 and 24, we initialize the DHT11. After that, we define a function called readDHT11Humidity. In this function, we read the humidity value from DHT11 by using readHumidity method, which is part of DHT library. The humidity global variable stores the humidity value.

Web Server

Third, let us create the web server and put the code all together. The web server consists of three parts: SPIFFS, WiFi, and the server itself. We use SPIFFS for storing the web files (HTML, CSS, and JS). The WiFi is configured as client that connects to the AP.

This is how to put the code all together:

  • Firstly, we initialize the peripherals, such as serial, DHT, SPIFFS, and WiFi in line 22, 24, 27-31, and 34-39, respectively.
  • Then, we define the server in line 16. It listens on port 80, the default HTTP port.
  • After that, we define the handlers that correspond to each HTTP request.
  • In line 45-68, the handles send the web files (HTML, CSS, JS, and image) to the web client.
  • In line 69-74, the handles send the humidity value and prediction result to the web client.
  • Finally, we start the server in line 77.

When the web server receives HTTP request on /humidity and /predict URLs, then it calls the readDHT11Humidity and predictRain functions, respectively. These functions return the humidity value and prediction result, respectively.

Web Page

In this section, we are going to build a web page that can display the humidity value and prediction result from the web server. We also use Bootstrap library for styling the HTML elements. The following code shows the complete HTML code.

HTML

First, let us build the layout. We use Bootstrap container-fluid class as the main container. Within the main container, we use Bootstrap grid system that consists of one vertically and horizontally centered column. Then, within the column, we use Bootstrap card class. Finally, within the body of the card, we create a text placeholder for displaying the humidity value (line 22) and use img tag to display an image that shows the rain prediction result (line 23). The humidity value and rain prediction result are updated using the JavaScript.

JavaScript

Second, let us build the functionality of the web page using JavaScript. We use setInterval function for requesting humidity value and rain prediction result every 5 seconds. So, every 5 seconds we send HTTP GET request on /humidity and /predict URLs to the web server. Then, the web server sends the response that will be displayed on the web page. In line 36-37, the code updates the humidity value. In line 48-52, the code updates the rain prediction result. It changes the src attribute of the img tag with the correct image.

Demonstration

First of all, we should compile and upload the sketch to the ESP32. After that, upload the sketch data (the web files). Then, wait till the ESP32 is connected to the AP. The ESP32 should get an IP address from AP, i.e. we use the DHCP feature on the AP.

Next, let us open a web browser, and the IP address of the ESP32 on the URL input. You should see the web page loaded to the web browser. After that, check that the humidity value and rain prediction are being read correctly from the web server.

Source Code

You can get the source code from this repository.

Summary

In this tutorial, we have learned how to build an embedded web server for rain prediction application. We have used real-time humidity value from DHT11 as input for the logistic regression model. Then, we have built a web UI for displaying the humidity value and rain prediction result.