Do you want to learn how to make this? (show a real example of turning on a light bulb with a Relay and ESP32 and the web platform on the smartphone). Or this? (Show example of alarm on the smartphone when a lighter is placed in front of ESP32 sensor) Or maybe a real time graph with data from the ESP32? Well, let me show you some examples and you will learn how to make a cool local connection between the ESP32 and a web platform.
by: ELECTRONOOBS on 2026-06-28
We will use these two main libraries. Wifi.h and WebServer.h Since we are running on a LAN connection, we have no website with a hosting and a server behind it. So we will use the ESP32 to create its own local server using this cool library. Let’s just make a simple connection between the ESP and my web browser.
We add our wifi data, name and password. We start a server on port 80 which is the common port for local. Then in the setup loop we use wifi.begin with the name and password to connect to the WIFI. Once connected, we print the local IP that was assigned to the ESP32 using this line. And we start the server.
Now we have a basic server on our ESP32. What we need is a client. What's a client? Well, anyone with a web browser that connects to this IP we have just created. That’s why in the void loop, the only thing that we do is to constantly handle the client. If this handleClient function is not running, when I do something on the webpage, the server wont respond. I’ve uploaded the code and as you can see, it gives me the IP of the ESP32. Copy this and let’s open a browser. Paste it on the browser and press enter. As you can see we get the HTML code. This title here, is the same that we have on the ESP32 code. So we are connected.
#include <WiFi.h>
#include <WebServer.h>
// WiFi Network Credentials
const char* ssid = "Your Wifi NameG";
const char* password = "Your Wifi Password";
WebServer server(80);
// Simple baseline HTML response stored in RAM
void handleRoot() {
String html = "<html><head><meta charset='UTF-8'></head>";
html += "<body style='background:#030704;color:#33ff33;text-align:center;font-family:monospace;padding-top:100px;'>";
html += "<h1>NOOBIX BASIC NODE ONLINE</h1>";
html += "<p style='color:#888;'>Connected via raw IP Address mapping.</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
// Initialize serial communication at 115200 baud rate
Serial.begin(115200);
delay(500);
Serial.println("\n========================================");
Serial.println(" NOOBIX OS - BASIC IP TEST BOOT ");
Serial.println("========================================");
Serial.print("[WIFI] Seeking connection to: ");
Serial.println(ssid);
// Initialize the WiFi radio profile in station mode
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Non-blocking wait loop prints dots until connection is acknowledged
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
// CRITICAL VIDEO SHOT: Print the raw IP node allocation out to the terminal [INDEX]
Serial.println("\n\n[WIFI] Infrastructure bridge complete!");
Serial.println("----------------------------------------");
Serial.print("TARGET IP ADDRESS: ");
Serial.println(WiFi.localIP()); // <-- This forces the user to check the monitor [INDEX]
Serial.println("----------------------------------------");
// Bind the root directory route and start the internal background server
server.on("/", handleRoot);
server.begin();
Serial.println("[OK] HTTP background daemon active on port 80.\n");
}
void loop() {
server.handleClient(); // Keep processing local web query packets from the LAN
}
But copy pasting the IP is quite boring. A better way of accessing the server is using MDNS. This is the second example code. I’ve added this extra library for MDNS. Again we create the server on port 80. Se start wifi with name and password. But now we use MDNS begin and we give it a name. Let’s name it noobix. So now, instead of using the IP to access the esp32, we use noobix.local. The browser will automatically go to the IP of the ESP32 that has that name. So copy this and go to a web browser and paste it. As you can see, we are connected once again but a lot more elegant than using the IP.
Not just that, but if at some point the router changes the IP it assigns to the ESP32, with this code you don’t care. It will still connect to the same device. If you think about it is the same with websites. Electronoobs.com has a name but it also has a real IP. When I type electronoobs.com, the DNS will tell the browser the IP and automatically takes me to the page. Pretty easy to understand, right?
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h> // mDNS library for local naming
WebServer server(80);
void handleRoot() {
server.send(200, "text/html", "<h1>NOOBIX NODE ONLINE</h1><p>Welcome to local LAN IoT.</p>");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin("Your Wifi Name", "Your Wifi Password");
while (WiFi.status() != WL_CONNECTED) { delay(250); Serial.print("."); }
// Start the mDNS responder for http://noobix.local
if (MDNS.begin("noobix")) {
Serial.println("[OK] mDNS started. Access via http://noobix.local");
}
server.on("/", handleRoot);
server.begin();
}
void loop() { server.handleClient(); }
We start the code in the same way but to keep it organized I click these 3 dots on the top right corner in Arduino IDE and select add tab. I name it html.h. I cut the html code from the main tab and paste it inside the html file. In this way we have a page for the Arduino code and a file for the webpage code. But we have to include that html file so add this line.
Now, instead of using MDNS begin and the word noobix, I create a variable called device name. In that way, each control could have its own name. Relay, fan, light bulb, sensor or who knows what. I set the relay pin to 25. Ok so now we send to the server this html page.
This page has a title, a paragraph and a button. Whenever the button is pressed, we run this java script code. This function toggle, will make a fetch to the server with the tag toggle. Back to the arduino code, if the server detects that a client makes a toggle fetch, it changes the state of the relay and makes a digital write. Just like that we turn on and off the relay. Even more, the html script also changes the color of the button for on and off. Upload the code and this time we go to relay.local since that’s the device name.
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h> // Include mDNS library
#include "html.h"
// 1. CONFIGURATION MATRIX
const String DeviceName = "relay"; // This will become http://relay.local
const char* ssid = "Your Wifi Name";
const char* password = "Your Wifi Password";
const int RELAY_PIN = 12;
bool relayState = false;
WebServer server(80);
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(250);
Serial.print("[OK] Connected. Operational Node IP: "); Serial.println(WiFi.localIP());
// Dynamic mDNS initialization using your DeviceName variable [INDEX]
if (MDNS.begin(DeviceName.c_str())) {
Serial.print("[OK] mDNS engine running. Access layout via: http://");
Serial.print(DeviceName);
Serial.println(".local");
}
server.on("/", []() { server.send(200, "text/html", html_page); });
server.on("/toggle", []() {
relayState = !relayState;
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
server.send(200, "application/json", "{\"status\":" + String(relayState ? 1 : 0) + "}");
});
server.begin();
}
void loop() {
server.handleClient();
}
This time the html script makes a fetch with the word data. The ESP32 server gets that data, makes an analog read and gives a response.The json response will tell the webpage that the variable val is equal to the readed adc value. The html code, after the fetch will get that response and set the text and graph value to that val variable. And this function executes each 50ms as you can see here. (You might want to add a bigger delay like 200ms or so) Upload the code and go to sensor.local
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h> // Include mDNS library
#include "html.h"
// 1. CONFIGURATION MATRIX
const String DeviceName = "sensor"; // This will become http://sensor.local
const char* ssid = "Your WIFI Name";
const char* password = "Your WIFI Password";
WebServer server(80);
const int SENSOR_ADC_PIN = 32;
void setup() {
Serial.begin(115200);
pinMode(SENSOR_ADC_PIN, INPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(250);
Serial.print("[OK] Connected. Operational Node IP: "); Serial.println(WiFi.localIP());
// Dynamic mDNS initialization [INDEX]
if (MDNS.begin(DeviceName.c_str())) {
Serial.printf("[OK] mDNS running. Access via: http://%s.local\n", DeviceName.c_str());
}
server.on("/", []() { server.send(200, "text/html", html_page); });
server.on("/data", []() {
int sensorRaw = analogRead(SENSOR_ADC_PIN);
server.send(200, "application/json", "{\"val\":" + String(sensorRaw) + "}");
});
server.begin();
}
void loop() {
server.handleClient();
}
The server now waits for the fetch status and it returns if the sensor was tripped or not, true or false. The html page, each 1000ms, makes a fetch to the server with the work status. If the alarm is true, we create a modal as a notification and display this text. Upload the code and go to security.local Now if I push the button on pin 19, simulating the sensor, as you can see I get a notification. That’s an easy alarm system.
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h> // Include mDNS library
#include "html.h"
// 1. CONFIGURATION MATRIX
const String DeviceName = "security"; // This will become http://security.local
const char* ssid = "Your WIFI Name";
const char* password = "Your WIFI Password";
const int SECURITY_PIN = 19;
const int HARDWARE_SIREN = 5;
bool alarmActive = false;
WebServer server(80);
void setup() {
Serial.begin(115200);
pinMode(SECURITY_PIN, INPUT_PULLUP);
pinMode(HARDWARE_SIREN, OUTPUT);
digitalWrite(HARDWARE_SIREN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(250);
Serial.print("[OK] Connected. Operational Node IP: "); Serial.println(WiFi.localIP());
// Dynamic mDNS initialization [INDEX]
if (MDNS.begin(DeviceName.c_str())) {
Serial.printf("[OK] mDNS running. Access via: http://%s.local\n", DeviceName.c_str());
}
server.on("/", []() { server.send(200, "text/html", html_page); });
server.on("/status", []() {
server.send(200, "application/json", "{\"alarm\":" + String(alarmActive ? "true" : "false") + "}");
});
server.begin();
}
void loop() {
server.handleClient();
// Continuous localized machine state checks run parallel with web tasks
if (digitalRead(SECURITY_PIN) == LOW) {
alarmActive = true;
digitalWrite(HARDWARE_SIREN, HIGH); // Engage localized audio transducer warning system
} else {
alarmActive = false;
digitalWrite(HARDWARE_SIREN, LOW); // Clear line outputs
}
}
Leave a comment
Please login in order to comment.