IoT Using ESP8266-01 and Arduino

Contents hide

Ever asked how to control any device from any place in the world? In this tutorial, we’ll learn how to control things wirelessly over WiFi.

IoT Using ESP8266-01 and Arduino

Story

CSS: It stands for cascading style sheet. After building the web page main structure, you need to make this structure looks nice here comes CSS to make some styling. It’s a language that describes the style of an HTML element. It consists of some selectors and deceleration blocks.

CSS

Javascript: It’s a programming language that we will use to make the web page more interactive like adding some animations, maps and it allows us to make some complex things on the web page. Mainly, we will use it today to send an HTTP request from the client(web browser) to the webserver(ESP8266-01) to take some actions like turning on or off a light bulb.

Javascript

Build The Web Page Structure

To easily understand the upcoming explanation, I recommend Reading this cool HTML intro.

As we see our control panel is very simple. It contains two headers each one has a different size, one image, and two buttons one for turning on an LED and the second one for turning it off.

Code

<!DOCTYPE html>      
<html>      
<head>      
    <title>Smart Home System</title>      
</head>      
<body>      
    <h1> Smart Home Control Panel</h1>                                     
    <h4>Sorry But I'm a Meme Addict!</h4>      
    <img src="dogMeme.jpg" width="400px" height="400px">      
    <br>      
    <button id="111" class="button">LAMP ON</button>      
    <br>      
    <button id="110" class="button">LAMP OFF</button>      
</body>      
</html>      

Code Explanation

  • <!DOCTYPE html>: declaration defines that this document is an HMTL5 document.
  • <html>: the root element of an HTML page.
  • <head>: element contains meta information about the page.
  • <title>: element specifies the title of the document. this title appears on the web page browser tab.
  • <body>: element contains the visible web page content.
  • <h1>: element defines a large element.
  • <h4>: element defines a smaller header. when the header value decreases the font decreases.
  • <img>: element adds an image to the web page. the image that you want to display should be in the same project folder.
  • <br>: advance the cursor to a new line.
  • <button>: element adds a button to the page content.

Each button is our web page has very important two attributes the id, and the class attributes. we will talk about why we assigned these two values to the buttons in the Jquery code explanation.

Styling The Web Page

To easily understand the upcoming explanation, I recommend Reading this cool CSS intro.

Now, the web page looks nicer (NOT TOO MUCH xD) we gave it a cool green background color, we make the page content centered aligned, and we change the headers font color and font family which made the web page more alive. We used CSS to do all of this styling stuff.

Code

<!DOCTYPE html>      
<html>      
<head>      
    <title>Smart Home System</title>      
</head>      
<body style="background-color: seagreen; color: seashell; text-align: center;">      
    <h1> Smart Home Control Panel</h1>                                     
    <h4>Sorry But I'm a Meme Addict!</h4>      
    <img src="dogMeme.jpg" width="400px" height="400px">      
    <br>      
    <button style="margin: 10px;" id="111" class="button">LAMP ON</button>      
    <br>      
    <button style="margin:10px;" id="110" class="button"> LAMP OFF</button>      
</body>      
</html>      

Code Explanation

We added some few lines of code to make our web page looks nicer. We added style="background-color: seagreen; color: seashell; text-align: center;" inside the body tag to make all the web page content in the center of the page and to set the background color to seagreen also to set the font color to seashell.

Also, we added style="margin: 10px;" inside the two button tags to set a margin of 10 pixels around the four sides of each button.

Sending a Request To The Webserver

To easily understand the upcoming explanation, I recommend Reading this cool Jquery intro.

Now, after building our web page structure and styling it we need to add some functionality to the two buttons which we added earlier in the web page. we need when the user clicks the “LAMP ON” button his/her browser sends a request contains some unique data to the server(ESP8266-01) this unique data tells the Arduino to turn on the lamp. The same thing with the second button “LAMP OFF” when the user clicks it, the browser will send a request contains some unique data to the server(ESP8266-01) this unique data tells the Arduino to turn off the lamp. Let’s take a look at the code.

<!DOCTYPE html>      
<html>      
<head>      
    <title>Smart Home System</title>      
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>      
</head>      
<body style="background-color: seagreen; color: seashell; text-align: center;">      
    <h1> Smart Home Control Panel</h1>                                     
    <h4>Sorry But I'm a Meme Addict!</h4>      
    <img src="dogMeme.jpg" width="400px" height="400px">      
    <br>      
    <button style="margin: 10px;" id="111" class="button">LAMP ON</button>      
    <br>      
    <button style="margin:10px;" id="110" class="button"> LAMP OFF</button>      
        <script>                                                        //starting Javascript.      
        $(".button").click(function () {                            //if any button from the ".button" class is clicked      
            var p = $(this).attr('id');                             //get this button id and store it inside the "p" variable.      
            pin: p                                                  //a dictionary contains the button id to get sent to the web server.      
            $.get("http://192.168.1.4:80/", {                      //then send a get request to the web server"http://192.168.1.4:80/" (":80" means port number 80) with some data in a form of dictionary {pin: p} which is the butoon id. IMPORTANT NOTE: DON'T FORGET TO CHANGE THE IP ADDRESS WITH YOUR ESP8266 NEW IP ADDRESS.      
            pin: p      
            });      
        });      
    </script>      
</body>      
</html>      

Code Explanation

First Things First, we need to import the Jquery library in our code. So, we added this line in the head tag.<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

All the magic happens in this interesting part.

 <script>                                                        //starting Javascript.      
        $(".button").click(function () {                            //if any button from the ".button" class is clicked      
            var p = $(this).attr('id');                             //get this button id and store it inside the "p" variable.      
            pin: p                                                  //a dictionary contains the button id to get sent to the web server.      
            $.get("http://192.168.1.4:80/", {                      //then send a get request to the web server"http://192.168.1.4:80/" (":80" means port number 80) with some data in a form of dictionary {pin: p} which is the butoon id. IMPORTANT NOTE: DON'T FORGET TO CHANGE THE IP ADDRESS WITH YOUR ESP8266 NEW IP ADDRESS.      
            pin: p      
            });      
        });      
    </script>      
  • $(".button").click(function () {

When the user clicks on any button associated with the class “button”, trigger the following function.

  • var p = $(this).attr('id');

Get the value of the clicked button attribute “id” and store it inside the “p” variable.

  • pin: p

Put the variable “p” value in a dictionary (key-value) it’s key is “pin” and the value is “p” variable value.

  • $.get("http://172.20.10.11:80/", { pin: p });});

Then, send a GET request to the webserver which it’s IP address is “172.20.10.11”. this GET request contains the value of the attribute id pressed button.

In case the user pressed the “LAMP ON” button this id value will be 111, so the GET request header will contain some data like this pin=111. look at the next figure!

pin=111

At the opposite side, if the user pressed “LAMP OFF” button the request will contain this data pin=110.

Code Logic

I know you asking now why the heck did he choose 111 and 110 specifically? Ok, Lemme answer you fam. Actually, the number 111 and 110 divides into two parts.

  • Part one: is the first two numbers which are in both cases will be “11”, it refers to the Arduino pin number which the load I need to control is connected on.
  • Part two: is the third number which changes between 1 and 0 depending on the clicked button. And it refers to the pin state(ON or OFF).

In the Arduino code, we will receive this data and separate these two parts from each other and save each part in a different variable, part one in variable pinNumber and the second part in variable pinState, then we will write this simple line of code to control the connected loaddigitalWrite(pinNumber, pinState);

Connecting The Load

Now, we need to connect the load with the Arduino board to control it. Before connecting any high voltage device like the air conditioner or even the TV, we need to test our circuit and the code with some low voltage stuff like LEDs only to make sure that everything is working well. Here’s the wiring diagram

Connecting The Load

The wiring is pretty simple. We are connecting the LED positive leg to the Arduino digital pin 11, and the negative leg to the GND through a 1k ohm resistor.

Arduino Code

#include <SoftwareSerial.h>                         //including the SoftwareSerial library will allow you to use the pin no. 2,3 as Rx, Tx.      
SoftwareSerial esp8266(2,3);                        //set the Rx ==> Pin 2; TX ==> Pin3.      
#define serialCommunicationSpeed 9600               // <========= define a constant named "serialCommunicationSpeed" with a value 9600. it referes to the Software and hardware serial communication speed(baud rate).      
#define DEBUG true                                  //make a constant named "DEBUG" and it's value true. we will use it later.      
int redLED =12;                                     //assign a variable named "redLED" with an integer value 12, it refers to the pin which the red LED is connected on.      
int blueLED =11;                                    //assign a variable named "blueLED" with an integer value 11, it refers to the pin which the blue LED is connected on.      
void setup()      
{      
  pinMode(redLED,OUTPUT);                           //set the pin number 12 as an output pin.      
  pinMode(blueLED,OUTPUT);                          //set the pin number 11 as an output pin.      
        
  digitalWrite(redLED,LOW);                         //turn the red LED off at the beginning of the program.      
  digitalWrite(blueLED,HIGH);                       //turn the blue LED on at the beginning of the program.      
  Serial.begin(serialCommunicationSpeed);           //begin the Hardware serial communication (0, 1) at speed 9600.      
  esp8266.begin(serialCommunicationSpeed);          //begin the software serial communication (2, 3) at speed 9600.      
  InitWifiModule();                                 //call this user-defined function "InitWifiModule()" to initialize a communication between the ESP8266 and your access point (Home Router or even your mobile hotspot).      
  digitalWrite(blueLED,LOW);                        //after finishing the initialization successfully, turn off the blue LED (just an indicator).      
}      
void loop()                                                         //our main program, some fun are about to start)      
{      
  if(esp8266.available())                                           //if there's any data received and stored in the serial receive buffer, go and excute the if-condition body. If not, dont excute the if-condition body at all.      
  {      
    if(esp8266.find("+IPD,"))                                       //search for the "+IPD," string in the incoming data. if it exists the ".find()" returns true and if not it returns false.      
    {      
      delay(1000);                                                  //wait 1 second to fill up the buffer with the data.      
      int connectionId = esp8266.read()-48;                         //Subtract 48 because the read() function returns the ASCII decimal value. And 0 (the first decimal number) starts at 48. We use it to convert from ASCI decimal value to a character value.      
      esp8266.find("pin=");                                         //Advance the cursor to the "pin=" part in the request header to read the incoming bytes after the "pin=" part which is the pinNumer and it's state.      
      int pinNumber = (esp8266.read()-48)*10;                       //read the first Byte from the Arduino input buffer(i.e. if the pin 12 then the 1st number is 1) then multiply this number by 10. So, the final value of the "pinNumber" variable will be 10.      
      pinNumber = pinNumber + (esp8266.read()-48);                  //read the second Byte from the Arduino input buffer(i.e. if the pin number is 12 then the 2nd number is 2) then add this number to the first number. So, the final value of the "pinNumber" variable will be 12.      
      int statusLed =(esp8266.read()-48);                           //read the third byte from the Arduino input buffer. then save it inside the "statusLed" variable. At any case, it will be 1 or 0.      
      digitalWrite(pinNumber, statusLed);                           //then turn the LED at "pinNumber" on or off depending on the "statusLed" variable value.      
      Serial.println(connectionId);                                 //print the "connectionId" value on the serial monitor for debugging purposes.      
      Serial.print(pinNumber);                                      //print the "pinNumber" value on the serial monitor for debugging purposes.      
      Serial.print("      ");                                       //print some spaces on the serial monitor to make it more readable.      
      Serial.println(statusLed);                                    //print the "statusLed" value on the serial monitor for debugging purposes.      
      String closeCommand = "AT+CIPCLOSE=";                         //close the TCP/IP connection.      
      closeCommand+=connectionId;                                   //append the "connectionId" value to the string.      
      closeCommand+="\r\n";                                         //append the "\r\n" to the string. it simulates the keyboard enter press.      
      sendData(closeCommand,1000,DEBUG);                            //then send this command to the ESP8266 module to excute it.      
            
    }      
  }      
}      
/******************************************************************************************************************************************************************************************      
* Name: sendData      
* Description: this Function regulates how the AT Commands will ge sent to the ESP8266.      
*       
* Params: command - the AT Command to send       
*                 - timeout - the time to wait for a response       
*                 - debug - print to Serial window?(true = yes, false = no)      
*                       
* Returns: The response from the esp8266 (if there is a reponse)      
*/      
String sendData(String command, const int timeout, boolean debug)      
{      
    String response = "";                                             //initialize a String variable named "response". we will use it later.      
          
    esp8266.print(command);                                           //send the AT command to the esp8266 (from ARDUINO to ESP8266).      
    long int time = millis();                                         //get the operating time at this specific moment and save it inside the "time" variable.      
    while( (time+timeout) > millis())                                 //excute only whitin 1 second.      
    {            
      while(esp8266.available())                                      //is there any response came from the ESP8266 and saved in the Arduino input buffer?      
      {      
        char c = esp8266.read();                                      //if yes, read the next character from the input buffer and save it in the "response" String variable.      
        response+=c;                                                  //append the next character to the response variabl. at the end we will get a string(array of characters) contains the response.      
      }        
    }          
    if(debug)                                                         //if the "debug" variable value is TRUE, print the response on the Serial monitor.      
    {      
      Serial.print(response);      
    }          
    return response;                                                  //return the String response.      
}      
/******************************************************************************************************************************************************************************************      
* Name: InitWifiModule      
* Description: this Function gives the commands that we need to send to the sendData() function to send it.      
*       
* Params: Nothing.      
*                       
* Returns: Nothing (void).      
*/      
void InitWifiModule()      
{      
  sendData("AT+RST\r\n", 2000, DEBUG);                                                  //reset the ESP8266 module.      
  //delay(1000);      
  sendData("AT+CWJAP=\"PUT YOUR SSID\",\"PUT YOUR PASSWORD\"\r\n", 2000, DEBUG);        //connect to the WiFi network.      
  delay (3000);      
  sendData("AT+CWMODE=1\r\n", 1500, DEBUG);                                             //set the ESP8266 WiFi mode to station mode.      
  delay (1000);      
  sendData("AT+CIFSR\r\n", 1500, DEBUG);                                                //Show IP Address, and the MAC Address.      
  delay (1000);      
  sendData("AT+CIPMUX=1\r\n", 1500, DEBUG);                                             //Multiple conections.      
  delay (1000);      
  sendData("AT+CIPSERVER=1,80\r\n", 1500, DEBUG);                                       //start the communication at port 80, port 80 used to communicate with the web servers through the http requests.      
}      

code explanation

the code is pretty straightforward, we implemented two different functions InitWifiModule() and sendData()

The sendData() function job is regulating how the AT commands will get sent to the ESP8266-01 module.

the InitWifiModule() function job is to provide the sendData() function the AT commands that we need to send to the ESP8266-01.

In the loop() function we read the income HTTP request header and search for the “+IPD, ” which means that the request has successfully arrived, then we read the pin value which it will be “111” if the user clicked the “LAMP ON” button and “110” if the user clicked “LAMP OFF” button.

Don’t forget to put your wifi SSID and Password in the Arduino code line no. 103sendData("AT+CWJAP=\"PUT YOUR SSID\",\"PUT YOUR PASSWORD\"\r\n", 2000, DEBUG);

For more code explanation please read the comments in the code, it’s well documented

How It Works

After uploading the code to the Arduino board, open the Serial monitor and read the responses that the ESP module is sending.

How It Works

At the beginning of the program, if you see something like the previous figure with “OK” at the end of the page, it means that the ESP8266-01 module is successfully connected to your wifi (Access point) and got an IP and MAC address. Now, you can open your fancy web page and try to control some stuff.

connected to your wifi

But, if you see something like the previous figure with a “FAIL” or “ERROR” at the end of the page, it means that your ESP module can’t connect to your wifi (Access point) for some reasons. Try to check if entered the right SSID and password for your network.

Adding a High Voltage Load

After we tested our code and got sure that everything is working like a charm. We need to replace this boring LED with a High voltage load like an air conditioner, TV or a light bulb. But to control all of these high voltage appliances we have to deal with relays.

relay module

What’s and why relays? Ok, the relay is a mechanical switch, which is toggled on or off by energizing a coil. It’s mainly used to control a high powered circuit using a low power signal (5V or 0V). So we can control a high powered device like an air conditioner or an AC lamp turning it on or off only by a 5V or 0V signal. Which is amazing!

2 channel relay

The Two-channel relay module has two control pins(IN1, IN2) these pins should get connected to two Arduino digital pins to control the state of the two coils, closes or opens the load circuit.

AC load relay wiring

At the opposite side of the relay module, the COM(common) should get connected to one end of the load. The other end of the load is either connected to the NC(Normally Close) or NO(Normally open). If connected to the NO the load remains Disconnected before trigger and vice versa.

Wiring Diagram

Wiring Diagram

As you see, we are using a two-channel relay module that gives us the ability to control two different AC loads. We are connecting the first relay at digital output pin11(Arduino) and the second relay to digital output pin 12(Arduino).

Make a small modification to our web page. We will add another two buttons(ON and OFF) to control the second connected load.

<!DOCTYPE html>      
<html>      
<head>      
    <title>Smart Home System</title>      
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>      
</head>      
<body style="background-color: seagreen; color: seashell; text-align: center;">      
    <h1> Smart Home Control Panel</h1>                                     
    <h4>Sorry But I'm a Meme Addict!</h4>      
    <img src="dogMeme.jpg" width="400px" height="400px">      
    <br>      
    <button style="margin: 10px;" id="111" class="button">Blue LED ON</button>      
    <button id="110" class="button">Blue LED OFF</button>      
    <br>      
    <button style="margin:10px;" id="121" class="button"> Red LED ON</button>      
    <button id="120" class="button">Red LED OFF</button>      
    <script>                                                        //starting Javascript.      
        $(".button").click(function () {                            //if any button from the ".button" class is clicked      
            var p = $(this).attr('id');                             //get this button id and store it inside the "p" variable.      
            pin: p                                                  //a dictionary contains the button id to get sent to the web server.      
            $.get("http://192.168.1.4:80/", {                       //then send a get request to the web server"http://192.168.1.4:80/" (":80" means port number 80) with some data in a form of dictionary {pin: p} which is the butoon id. IMPORTANT NOTE: DON'T FORGET TO CHANGE THE IP ADDRESS WITH YOUR ESP8266 NEW IP ADDRESS.      
            pin: p      
            });      
        });      
    </script>      
</body>      
</html>      

Source: IoT Using ESP8266-01 and Arduino


About The Author

Muhammad Bilal

I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top