How to Build NodeMCU Webserver and control an LED from a Webpage
In this tutorial, you will know about how How to Build NodeMCU Webserver and control an LED from a WebpageWhat is a Webserver and How it works?
In simple terms, a Web server is a place where we can store the web pages, process them, and deliver them to the web clients. Now, what is a web client? It is nothing but a web browser installed on our mobiles and PCs. A protocol is used to establish and transfer information between web client and server. This protocol is known as Hypertext Transfer Protocol (HTTP).In this protocol, communication is initiated by making a request for a particular web page using HTTP GET request and the server responds with the content of that web page. If server does not respond it will through an error message i.e. 404 Error. Webpages delivered by the server are mostly in HTML coding.
All the websites are hosted on some webserver, mostly Linux based operating system is used on web servers. Any computer can be converted into a web server, provided that it is connected to the network. We have previously done many webserver projects with different microcontrollers. Raspberry pi already have inbuilt Wi-Fi module so it doesn’t need any other hardware to turn it into a webserver, whereas other microcontroller needs some network connecter (ESP module) for a webserver.
Operating Modes in ESP Modules
Most of us think that ESP can only connect with existing Wi-Fi networks but wait!!! ESP is more than you think. It can also set up its own network and allows other devices to connect directly to it. This is possible because ESP modules can operate in three different modes namely Station mode, Soft Access Point mode, and both at the same time. This helps in making mesh networks where you have more than one ESP module and want to establish a connection between these.
Let’s see the different modes to know more about them:
1. Station (STA) Mode
When the ESP module connects to an existing Wi-Fi network i.e. network created by your router then this is a Station mode (STA). In this mode, ESP gets IP from the wireless router to which it is connected. Using this IP address, ESP will set up a web server and send the web pages to all devices which are connected with the existing WiFi network.
2. Soft Access Point (AP) Mode
In this mode, ESP creates its own Wi-Fi network and sets SSID and IP address to it and acts like a Wi-Fi router. Unlike the WiFi router, it is not connected to a wired network. Using the generated IP address, it will send web pages to all devices which are connected with its own WiFi network. Also, the maximum number of devices that are connected to the ESP is limited to five.
In this tutorial, we will make a ESP12E web server using both the modes for controlling an LED.
Requirements
I believe this book will help you to increase your knowledge on this subject
Circuit Diagram
Code Explanation for NodeMCU Web server in Station Mode
First of all, we will include ESP8266WiFi.h library for accessing the Wi-Fi functions.
#include <ESP8266WiFi.h>
Declare variables for the Wi-Fi SSID, password and other variables
const char * ssid = "nodemcu";
const char * password = "12345";
String header;
String LED1State = "off";
const int LED1 = D0;
Next, we declare an object of the WifiServer library, so we will access its functions. The argument for the instance where the server is listening Since 80 is the default port for HTTP
WiFiServer server (80);
In the Void setup () function, we will initialize the baud rate, LED output, and will connect the module with the Wi-Fi using WiFi.begin (SSID, password); function
void setup () {Serial.begin (115200);
pinMode (LED1, OUTPUT);
digitalWrite (LED1, LOW);
...
..
WiFi.begin (ssid, password);
while (WiFi.status ()! = WL_CONNECTED) {
delay (500);
Serial.print (".");
}
After this, we will print the local IP address in serial monitor using WiFi.localIP (); function and then start the webserver using the server.begin (); function
Serial.println ("");
Serial.println ("WiFi connected ->");
Serial.println ("Copy this IP address:");
Serial.println (WiFi.localIP ());
server.begin ();
}
In the void loop () function, we will listen to the incoming clients using the server. available (); function and store the incoming data to a string variable and print the data on the serial monitor.
void loop () {
WiFiClient client = server.available ();
if (client) {
Serial.println ("new client connected");
String currentLine = "";
HTTP headers always start with a response code (e.g., HTTP / 1.1 200 OK) and a content-type so the client knows what's coming and then a blank line.
client.println ("http / 1.1 200 OK");
client.println ("Content-type: text / html");
client.println ("Connection: close");
client.println ();
Now, we will do the action i.e. we will check the request and turn on / off the LED accordingly.
if (header.indexOf ("GET / LED1 / on")> = 0) {
Serial.println ("LED1 on");
LED1State = "on";
digitalWrite (LED1, HIGH);
} else if (header.indexOf ("GET / LED1 / off")> = 0) {
Serial.println ("LED1 off");
LED1State = "off";
digitalWrite (LED1, LOW);
}
Next, we will use our web page using HTML and send each line using the client.println () function.
client.println ("<! DOCTYPE html> <html>");
client.println ("<head> <meta name = \" viewport \ "content = \" width = device-width, initial-scale = 1 \ ">");
client.println ("<link rel = \" icon \ "href = \" data:, \ ">");
You can use CSS to style the buttons and background. You can change the properties in the following lines.
client.println ("<style> html {font-family: Cairo; display: inline; margin: 0px auto; text-align: center; background-color: # ccffb3;}");
client.println (".button {background-color: # 006699; border: none; color: white; padding: 16px 40px;");
client.println ("text-decoration: none; font-size: 35px; margin: 2px; cursor: pointer;}");
client.println (". button2 {background-color: # 555555;} </ style> </ head>");
If you want to display a picture on the webpage, you can use an SVG image using this online SVG maker tool. Generate a SVG code from that page and paste it inside the client.println () as shown in the below line.
client.println ("<svg width =" 300 \ "height = \" 80 \ "> <text fill = \" # 00bfbf \ "font-family = \" serif \ "font-size = \" 24 \ " id = \ "svg_1 \" stroke = \ "# 000000 \" text-anchor = \ "middle \" transform = \ "matrix (1.35388 0 1.42308 -6.66283 -8.67308) \" x = \ "86.5 \" xml: space = \ "preserve \" y = \ "41.5 \"> Circuit Digest </ text> </ svg> ");
client.println ("<body> <h1> Welcome to ESP12e Web Server </ h1>"); // Webpage heading name
To display the current LED state we need the above code where we have turned on / off the led. If the LED1State is off, it displays the ON button and attaches the message ("/ LED1 / on \") with that button using the <a href> Html tag.
client.println ("<p> LED1_State:" + LED1State + "</ p>");
if (LED1State == "off") {
client.println ("<p> <a href=\"/LED1/on\"> <button class = \" button \ "> ON </ button> </a> </ p>");
Below the Html
client.println ("<svg width = \" 500 \ "height = \" 300 \ "> <ellipse cx = \" 258.5 \ "cy = \" 125.5 \ "fill = \" # ffffff \ "rx = \" 47 \ "ry = \" 52 \ "stroke =" "# ffffaa \" stroke-width = \ "5 \" /> <rect fill = \ "# cccccc \" height = \ "40 \" stroke = \ " #ffffaa \ "stroke-width = \" 5 \ "transform = \" rotate (-0.485546 261 187.5) \ "width = \" 39 \ "x = \" 241.5 \ "y = \" 167.5 \ "/> < / svg> ");
Similarly, make Html code for off button.
Now, we have completed all required code, finally, finish it by sending Html end tag with an empty client.println ().
client.println ("</ body> </ html>");
client.println ();
After uploading the code, open the serial monitor. Make the baud rate of serial monitor as 115200. You will see the IP address in the monitor, just copy this IP and paste it in the browser.
You will see a webpage in your browser as shown below. To test the page, connect an LED to your NodeMCU pin D0 and click ON button, LED should glow. You can also watch the actions in Serial Monitor.
This is how we can control an LED using station mode in the ESP module. Now, we will see the Soft Access Point web server.
NodeMCU Web server in Soft Access Mode
You do not need to change Just change some lines in the void setup () function to make the ESP12E work as AP mode.
In void setup (), we have to include the functions which are used to enable the AP mode WiFi.softAP (SSID, password) and get the server IP using WiFi.softAPIP () function. Just paste
void setup () {
Serial.begin (115200);
pinMode (LED1, OUTPUT);
digitalWrite (LED1, LOW);
WiFi.softAP (ssid, password);
Serial.println ();
Serial.print ("Server IP address:");
Serial.println (wifi.softAPIP ());
server.begin ();
}
Upload the code after editing the previous one. Then same as previous, open the Serial monitor and copy the server IP address.
Now, open Wi-Fi settings in your smartphone or laptop. There will be a Wi-Fi network with the SSID name and password that you had given in the beginning of the code. Connect your system with this network and open the browser and paste the IP address in it.
You will see the same web page as you observed previously.
Now, you can control your appliances using ESP as Soft access point.
To control Home appliances with this webpage, you just have to replace the LED with Relay and you will be able to control any AC appliance wirelessly.
Complete Code and demonstration Video is given below
Code
#include <ESP8266WiFi.h>
const char * ssid = "********"; // Enter SSID here
const char * password = "*******"; // Enter Password here
// Variable to store the HTTP request
String header;
String LED1State = "off";
const int LED1 = D0;
WiFiServer server (80);
void setup () {
Serial.begin (115200);
pinMode (LED1, OUTPUT);
digitalWrite (LED1, LOW);
Serial.print ("Connecting to");
Serial.println (ssid);
WiFi.begin (ssid, password);
while (WiFi.status ()! = WL_CONNECTED) {
delay (500);
Serial.print (".");
}
// Print local IP address and start web server
Serial.println ("");
Serial.println ("WiFi connected ->");
Serial.println ("Copy this IP address:");
Serial.println (WiFi.localIP ());
server.begin ();
}
void loop () {
WiFiClient client = server.available ();
if (client) {// If a new client connects,
Serial.println ("new client connected");
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected ())
if (client.available ()) {// if there is to read from the client,
char c = client.read ();
Serial.write (c);
header + = c;
if (c == '\ n') {// if the byte is a newline character
if (currentLine.length () == 0) {
client.println ("http / 1.1 200 OK");
client.println ("Content-type: text / html");
client.println ("Connection: close");
client.println ();
if (header.indexOf ("GET / LED1 / on")> = 0) {
Serial.println ("LED1 on");
LED1State = "on";
digitalWrite (LED1, HIGH);
} else if (header.indexOf ("GET / LED1 / off")> = 0) {
Serial.println ("LED1 off");
LED1State = "off";
digitalWrite (LED1, LOW);
}
// Display the HTML webpage
client.println ("<! DOCTYPE html> <html>");
client.println ("<head> <meta name = \" viewport \ "content = \" width = device-width, initial-scale = 1 \ ">");
client.println ("<link rel = \" icon \ "href = \" data:, \ ">");
client.println ("<style> html {font-family: Cairo; display: inline; margin: 0px auto; text-align: center; background-color: # ccffb3;}");
client.println (".button {background-color: # 006699; border: none; color: white; padding: 16px 40px;");
client.println ("text-decoration: none; font-size: 35px; margin: 2px; cursor: pointer;}");
client.println (". button2 {background-color: # 555555;} </ style> </ head>");
client.println ("<svg width =" 300 \ "height = \" 80 \ "> <text fill = \" # 00bfbf \ "font-family = \" serif \ "font-size = \" 24 \ " id = \ "svg_1 \" stroke = \ "# 000000 \" text-anchor = \ "middle \" transform = \ "matrix (1.35388 0 1.42308 -6.66283 -8.67308) \" x = \ "86.5 \" xml: space = \ "preserve \" y = \ "41.5 \"> Circuit Digest </ text> </ svg> ");
// Web Page Heading
client.println ("<body> <h1> Welcome to ESP12e Web Server </ h1>");
client.println ("<p> LED1_State:" + LED1State + "</ p>");
// If the LED1State is off, it displays the ON button
if (LED1State == "off") {
client.println ("<p> <a href=\"/LED1/on\"> <button class = \" button \ "> ON </ button> </a> </ p>");
client.println ("<svg width = \" 500 \ "height = \" 300 \ "> <ellipse cx = \" 258.5 \ "cy = \" 125.5 \ "fill = \" # ffffff \ "rx = \" 47 \ "ry = \" 52 \ "stroke =" "# ffffaa \" stroke-width = \ "5 \" /> <rect fill = \ "# cccccc \" height = \ "40 \" stroke = \ " #ffffaa \ "stroke-width = \" 5 \ "transform = \" rotate (-0.485546 261 187.5) \ "width = \" 39 \ "x = \" 241.5 \ "y = \" 167.5 \ "/> < / svg> ");
} else {
client.println ("<p> <a href=\"/LED1/off\"> <button class =" button button2 \ "OFF </ button> </a> </ p>");
client.println ("<svg width = \" 500 \ "height = \" 300 \ "> <ellipse cx = \" 258.5 \ "cy = \" 125.5 \ "fill = \" # ff7f00 \ "rx = \" 47 \ "ry = \" 52 \ "stroke =" "# ffffaa \" stroke-width = \ "5 \" /> <rect fill = \ "# cccccc \" height = \ "40 \" stroke = \ " #ffffaa \ "stroke-width = \" 5 \ "transform = \" rotate (-0.485546 261 187.5) \ "width = \" 39 \ "x = \" 241.5 \ "y = \" 167.5 \ "/> < / svg> ");
}
client.println ("</ body> </ html>");
client.println ();
break;
} else {
currentLine = "";
}
} else if (c! = '\ r') {
currentLine + = c;
}
}
}
header = "";
client.stop ();
Serial.println ("Client disconnected");
Serial.println ("");
}
}
No comments