ESP32 Web Server -- HTML -- AJAX -- Hospital Visitors Counter

Introduction: ESP32 Web Server -- HTML -- AJAX -- Hospital Visitors Counter

This experimentation is about creating an ESP32 (Station Mode), stand-alone HTTP web server and processing / populating incremented counter value at regular interval on HTTP client interface. The web page is developed by using HTML, AJAX and CSS as the subject of “Hospital Visitors Count”

Visit the "VESZLE - The Art Of Electronics" you tube channel for further information and videos.

ESP32 – HTTP Web Server – HTML – AJAX – Hospital Visitors Counter conclusion You tube Video

Step 1: Abstract

The ESP32 is constructed with Xtensa dual-core (or single-core) 32-bit RISC architecture, operating at 160MHz or 240MHz, with up to 520KiB internal SRAM, integrated with Wi-Fi (802.11 b/g/n) and Bluetooth (v4.2 BR/EDR and BLE (shares the radio with Wi-Fi). The ESP32 provides peripheral interfaces like ADC, DAC, touch sensors, SPI, I2C, I2S, UART, CAN, PWM etc. The ESP32 supports all IEEE 802.11 standard security feature (WFA, WPA/WPA2 and WAPI), and cryptographic hardware acceleration (AES, RSA, SHA-2, ECC, RNG etc). It supports wake up from GPIO / Sensor interrupts, timers and 5uA deep sleep current consumption.

ESP32 Wi-Fi interface provides

· Station Mode

· Soft Access Point Mode

· Both at the same time, (Station + Access Point)

This experimentation is about creating an ESP32 (Station Mode), stand-alone HTTP web server and processing / populating incremented counter value at regular interval on HTTP client interface. The web page is developed by using HTML, AJAX and CSS as the subject of “Hospital Visitors Count”.

Step 2: Reference

“ESP32 – Getting Started MicroPython -- on Board Blink LED” Instruct-able / You-tube by PugazhM

ESP32-HTTP-Web-Server-HTML-CSS-Simple-Counter Instruct-able / You-tube by PugazhM

MicroPython Network TCP sockets

Step 3: Components

ESP32 Development Board

Micro USB Cable

Wi-Fi Router

Tablet or Laptop

Step 4: Schematic

Connect the ESP32 board to USB port of the PC / Laptop as illustrated.

The ESP32 development board provides on board LED, which is connected to GPIO2.

It has inbuilt Wi-Fi 802.11 b/g/n module / stack, can be configured as Wi-Fi station mode.

The Wi-Fi router provides the wireless connectivity between Wi-Fi client to Wi-Fi station and then to external internet world, can form a Local Area Network (LAN)

The Google Brower running on Laptop or Tablet, connected to a Wi-Fi network act as a Wi-Fi client.

Step 5: ESP32 HTTP Web Server

The ESP32 web server is representing the ESP32 hardware and firmware

ESP32 web server hardware stores / provides the web server software and needed files (example, HTML page, CSS stylesheet, Java Scripts, fonts, video, audio, images etc.) to “web client”, on request.

An HTTP server is a software that understands URLs (web addresses) and HTTP protocol. The web browser uses HTTP protocol to view webpages.

An HTTP server can be accessed through the domain name or IP address. HTTP server stores, and delivers the content of these hosted websites to the end user's device (Desktop PC, laptop, tablet, mobile phone etc.)

A “Static web server” sends, hosted HTML web pages / files, as is to “web client”.

A “Dynamic web server” updates the hosted HTML web pages / files, and then sends to “web client”.

Usually the ESP32 is a “dynamic web server” and it updates the HTML web pages / files with real time connected sensor data (example temperature, humidity, pressure, key event, GPIO, ADC, DAC, system parameters etc.) and then sends it to “web client”

A “web client” is nothing but a web browser (Google Chrome, Microsoft Edge, Firefox, Safari, Internet Explorer, Opera etc.)

A web server provides support for Hyper Text Transfer Protocol (HTTP), is a “Textual” (all commands are plain human readable text), “State less” (neither the server nor the client remembers previous communications) protocol.

Generally, “web clients” make HTTP request to “web server”, and then “web server” responds to the request.

For AJAX method, “web clients” make HTTP data request to “web server”, and then “web server” formulates the data and responds to the request.

A “web server” can also populate data into “web client” via sever push mechanism.

The “web server” must answer every HTTP request, at least with error message (404 error).

Step 6: Cascading Style Sheet (CSS)

Cascading Style Sheet (CSS) is a stylesheet language used for describing the HTML presentation, those can be displayed on screen, paper or in other media.

CSS is designed to enable the separation of presentation and content, including layout, colors, and fonts.

CSS describes how elements should be rendered on screen, on paper, in speech, or on other media

CSS uses a number of simple English keywords to specify the names of various style properties.

CSS is among the core languages of the open web and is standardized across Web browsers according to W3C specifications

The CSS structure consists of list of rules. Each rule or ruleset consists of one or more Selectors, Declarations, Properties and Property Values

Step 7: Asynchronous Java-script and XML (AJAX)

AJAX stands for Asynchronous Java-script And XML.

AJAX is a method for exchanging data asynchronously between browser and server, thereby avoiding page reloads.

AJAX’s fundamental function is to create fast and dynamic web pages. It does this by sending HTTP requests to the server asynchronously, this means that the entire web page doesn’t need to reload in order to update most content. The response data is parsed using the DOM (Document Object Model).

Uses HTTP protocol to communicate.

Does not require entire browser window to reload to change data.

JSON is the current returned data format of choice for the web

Step 8: ESP32 HTTP Web Server System Overview

A simple counter implementation is deployed on “web-server” as illustrated above

ESP32 act as “web-server” and Google Chrome running on a laptop act as a “web-client”

timer_1 is initiated and toggles the on-board LED at regular interval, via “BlinkLED()”call back function

timer_2 is initiated and updates the visitor_count variables at a regular interval, via “UpdateCounter()”call back function, validates the counters for upper limit. If counter value exceeds upper limit, then the python program resets the counters to initial value.

Whenever the “web-client” requests data via “HTTP Client Page Request” method, then the “web-server”, will construct the complete web page and then sends back to “web-client”.

Whenever the “web-client” requests data via “HTTP Client Data Request” method, then the “web-server”, will construct the data and then sends back to “web-client”.

The “web-client” refreshes the “web page” at 3 seconds interval.

Step 9: ESP32 HTTP Web Server GUI

A simple counter deployment on a ESP32 “web-server”, with “Hospital Visitor Counter” as theme is illustrated above.

The web page is constructed by using “Font Awesome” fonts and material icons.

Font Awesome icons are designed to be simple, modern, friendly, and sometimes quirky. Each icon is reduced to its minimal form, expressing essential characteristics.

The style sheet uses “”, for constructing a web page.

The web page is divided into 5 equal vertical columns and 2 rows. Totally 10 boxes.

A box type drawing which uses icon and fonts is used for formulating the “Hospital Visitor Counter” GUI. Example, following divider formula is used for calculating the visitors for each category.

General visitor count. Resets at 800.

General Physician. Twice in 3 visitors

Pediatrician. Once in 4 visitors

Cardiologist. Once in 8 visitors

Psychiatrists. once in 20 visitors

Radiologist. Once in 30 visitors

Dentist. Once in 3 visitors

Ophthalmologist. Once in 7 visitors

First Aid. Once in 25 visitors

Step 10: ESP32 Web Server MicroPython Program

The timer_one is initialized and callbacks the “BlinkLED” functionality for toggling on board LED at 200mS duration. (frequency = 5)

The timer_two is initialized and callbacks the “UpdateCounter” functionality for updating the system variables at 2S duration. (frequency = 0.5)

The MicroPython program, first creates and configures the ESP32 as Station Mode, and then connects to the Wi-Fi router using user provided SSID and Password

§ ssid = 'WiFi Router SSID'

§ password = 'WiFi Router Password'

§ station = network.WLAN(network.STA_IF)


§ station.connect(ssid, password)

§ # Wait until the ESP32 get connected to the router

§ while station.isconnected() == False:

§ pass

The MicroPython program creates a stream TCP web-server socket and then binds it into HTTP port 80. Listens from maximum five web clients

§ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

§ s.bind(('', 80))

§ s.listen(5)

The system checks the web-client request at endless while loop.

Whenever the web-server receives the “HTTP Client page request”, then it reconstruct the web page and sends the “HTTP Server Page Response” to web-client.

Whenever the web-server receives the “HTTP Client data request”, then it reconstruct the data and sends to web-client.

 Demonstrates HTML and CSS ESP32 Web server implementation
 Simple Counter usage as "Hospital Visitors Counter"
 Simple counter example for counting visitors at regular interval
 ESP32 Web server count event happens at 0.5 seconds interval, and validates / resets against the MAX count
 Web client request at 3 Seconds interval.
 * The ESP32 onboard LED pin connections
 * On board LED pin to GPI2
 Name:- M.Pugazhendi
 Date:-  08thOct2021
 Version:- V0.1
from machine import Pin, Timer
import network
import time
import socket

import esp

import gc

ssid = 'WiFi Router SSD'
password = 'WiFi Router Password'

station = network.WLAN(network.STA_IF) # Congigure WLAN as station # Activate the Station
station.connect(ssid, password) # Connect to the router using SSID and password

# Wait until the ESP32 get connected to the router
while station.isconnected() == False:

print('Connection successful')

led = Pin(2, Pin.OUT)
timer_one = Timer(0) # Initialize timer_one. Used for toggling the on-board LED
timer_two = Timer(1) # Initialize timer_two. Used for updating counter variables

toggle = 1
visitor_count = 0

def UpdateCounter(timer_two):
    global visitor_count
    visitor_count = visitor_count + 1
    if visitor_count > 800:
        visitor_count = 1

def BlinkLED(timer_one):
    global toggle
    if toggle == 1:
        toggle = 0
        toggle = 1

def ConstructWebPage():
  html = """<html>   
    <!-- add the following google font / icon to the webpage -->  
	<link rel="stylesheet" href="" 
	 integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    * {   
        box-sizing: border-box;   
    body {  
    /* background-color: #76ff03; */ /*Green */
	background-color: #76ff03;
    background-size: cover;  
    .column {   
        /* box toward left of the window screen */  
        float: left;   
        /*divide each counter box in equal size*/  
        /* 4 counters of 20% of screen size*/  
        width: 20%;   
        /*spacing between each box */  
        padding: 4px;   
        padding: 3px;   
        background-color: #db1b60;   
        color: white;
    .row {   
        /* Specify the margin for the row class */  
        margin: 3px;  
    /* Style the class named block*/  
    .block {   
        padding: 3px;   
        text-align: center;   
        /* background-color: #0100ca; */
		background-color: #1d00db; 		
        color: white;   
    .fa {   
        font-size: 50px;   
       var ajaxRequest = new XMLHttpRequest();   
       function ajaxLoad(ajaxURL)  
       { 'GET',ajaxURL,true);  
        ajaxRequest.onreadystatechange = function()  
         if(ajaxRequest.readyState == 4 && ajaxRequest.status==200)  
            var ajaxResult = ajaxRequest.responseText;  
            var tmpArray = ajaxResult.split("|");
            document.getElementById('visitor_count').innerHTML = tmpArray[0];
			document.getElementById('general_physician').innerHTML = tmpArray[1];			
			document.getElementById('pediatrician').innerHTML = tmpArray[2];
			document.getElementById('cardiologist').innerHTML = tmpArray[3];
			document.getElementById('psychiatrists').innerHTML = tmpArray[4];
			document.getElementById('radiologist').innerHTML = tmpArray[5];
			document.getElementById('dentist').innerHTML = tmpArray[6];
			document.getElementById('ophthalmologist').innerHTML = tmpArray[7];
			document.getElementById('first_aid').innerHTML = tmpArray[8];
			document.getElementById('diagnostic_lab').innerHTML = tmpArray[9];
       function UpdateVisitorCounters()   
       setInterval(UpdateVisitorCounters, 3000);
    <h1 style="color:black"> ESP32 HTTP Web Server </h1>
    <h1 style="color:black"> Hospital Visitor Counter </h1>
    <h3> HTML, AJAX and CSS formulated GUI on ESP32 Web server </h3>   
     <div class="row">   
			<div class="column">   
				<div class="block" >
					<h3> Visitor Count </h3>
					<p><i class="fas fa-users fa-5x" style="color:#FFFFFF;"></i></p>
				<div id="count">
					<h1><span id='visitor_count'>--</span></h1>	
			<div class="column">   
				<div class="block"> 
				<h3> General Physician </h3>
						<!-- Add bi cycle  icon -->  
				<p><i class="fas fa-user-md fa-5x" style="color:#FFFFFF;"></i></p>
				<div id="count">		
					<h1><span id='general_physician'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> Pediatrician </h3>
					<!-- Add motor bike icon -->  
				<p><i class="fas fa-child fa-5x" style="color:#FFFFFF;"></i></p>       
				<div id="count">		
					<h1><span id='pediatrician'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> Cardiologist </h3>
					<!-- Add car icon -->  
				<p><i class="fas fa-heartbeat fa-5x" style="color:#FFFFFF;" style="font-size:90px;"></i> </p>
				<div id="count">		
					<h1><span id='cardiologist'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> Psychiatrists </h3>
					<!-- Dentist fa-tooth -->  
				<p><i class="fas fa-brain fa-5x" style="color:#FFFFFF;" style="font-size:90px;"></i> </p>
				<div id="count">		
					<h1><span id='psychiatrists'>--</span></h1>   
    <div class="row">   
			<div class="column">   
				<div class="block" >
					<h3> Radiologist </h3>
					<p><i class="fas fa-x-ray fa-5x" style="color:#FFFFFF;"></i></p>
				<div id="count">
					<h1><span id='radiologist'>--</span></h1>	
			<div class="column">   
				<div class="block"> 
				<h3> Dentist </h3>
						<!-- Add bi cycle  icon -->  
				<p><i class="fas fa-tooth fa-5x" style="color:#FFFFFF;"></i></p>
				<div id="count">		
					<h1><span id='dentist'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> Ophthalmologist </h3>
					<!-- Add motor bike icon Diagnostic Lab fa-microscope-->  
				<p><i class="fas fa-eye fa-5x" style="color:#FFFFFF;"></i></p>       
				<div id="count">		
					<h1><span id='ophthalmologist'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> First Aid </h3>
					<!-- Add car icon -->  
				<p><i class="fas fa-first-aid fa-5x" style="color:#FFFFFF;" style="font-size:90px;"></i> </p>
				<div id="count">		
					<h1><span id='first_aid'>--</span></h1>   
			<div class="column">   
				<div class="block">
				<h3> Diagnostic Lab  </h3>
					<!-- Add car icon -->  
				<p><i class="fas fa-microscope fa-5x" style="color:#FFFFFF;" style="font-size:90px;"></i> </p>
				<div id="count">		
					<h1><span id='diagnostic_lab'>--</span></h1>   
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create Stram TCP web-server socket
s.bind(('', 80)) # Assign and bind port 80 for HTTP web-server socket
s.listen(5) # Configure for listening maximum 5 web-clients

# Timer one initialization for on board blinking LED at 200mS interval
timer_one.init(freq=5, mode=Timer.PERIODIC, callback=BlinkLED)

# Timer two initialization for updating the counter variables at 500mS interval
timer_two.init(freq=2, mode=Timer.PERIODIC, callback=UpdateCounter)

while True:
        if gc.mem_free() < 102000:
        conn, addr = s.accept() # Call accpept method for collecting the client address
        print('Got a connection from %s' % str(addr)) # Print the client address
        request = conn.recv(1024) # Collect client request
        request = str(request)
        print('Content = %s' % request) # Print the web-client request
        update = request.find('/getVisitorCounters')
        if update == 6:
            a1 = visitor_count # General visiotr count
            a2 = int(a1 / 1.5) # General Physician. Once in two visitors
            a3 = int(a1 / 4) # Pediatrician. Once in 4 visitors
            a4 = int(a1 / 8) # Cardiologist. Once in 8 visitors
            a5 = int(a1 / 20) # Psychiatrists. once in 20 visitors
            a6 = int(a1 / 30) # Radiologist. Once in 30 visitors
            a7 = int(a1 / 3) # Dentist. Once in 3 visitors
            a8 = int(a1 / 7) # Ophthalmologist. Once in 7 visitors 
            a9 = int(a1 / 25) # First Aid. Once in 25 visitors
            a10 = int(a1 / 5) # Diagnostic Lab. Once in 5 visitors
            response = str(a1) + "|"+ str(a2) + "|"+ str(a3) + "|"+ str(a4)+"|"+ str(a5)+"|"+ str(a6)+"|"+ str(a7)+"|"+ str(a8)+"|"+ str(a9)+"|"+ str(a10)
            #response = '16|15|17|18|19|20|21|22|23|24|25'
            response = ConstructWebPage() # Construct the web page
        conn.send('HTTP/1.1 200 OK\n') # Send the web-server response to web-client
        conn.send('Content-Type: text/html\n')
        conn.send('Connection: close\n\n')
        # Clsoe connection
    except OSError as e:
        print('Connection closed')

Step 11: Conclusion

The project is successfully completed with ESP32 development board, Wi-Fi router and Tablet. The web-server handles

HTML-AJAX request / response at regular interval to web-client running on tablet, android mobile and laptop google chrome, and updates the end user GUI.

Step 12: Results and Video Links

Please Visit You Tube for the conclusion video

Visit the "VESZLE - The Art Of Electronics" you tube channel for further information and videos.

ESP32 – HTTP Web Server – HTML – AJAX – Hospital Visitors Counter conclusion You tube Video

Be the First to Share


    • Origami Speed Challenge

      Origami Speed Challenge
    • Woodworking Contest

      Woodworking Contest
    • Go Big Challenge

      Go Big Challenge