Cloud Home Automation Series Part 4 : Connected Light Bulb using AWS, ESP32 & Arduino

Written by gourav-das | Published 2020/02/16
Tech Story Tags: cloud | aws | arduino | esp32 | home-automation | light-bulb-switch-on-off | iot | hackernoon-top-story

TLDR Cloud Home Automation Series Part 4 : Connected Light Bulb using AWS, ESP32 & Arduino. This is the last part of the series and here we will achieve our ultimate goal to Power ON the Light bulb with just one-click from anywhere, literally from anywhere even from the Antarctic as they got internet there. Bonus - Toggle the light by using Google Assistant or Alexa. We will leverage the power of Device Shadow which is very effective in case of power loss and connectivity issue. The following series split into four parts (refer below) with very simple and clear instructions to provision a home automation system to control house appliances through the web.via the TL;DR App

[Updated - 1st March, 2020] : Course updated, now you can control your connected light either using Google Assistant or Alexa. Kindly check out the Bonus section at the end of the course.
Welcome to
SIMPLE LEARNING
 AWS Cloud Home AutomationZero to Hero Series. 
In the fourth part, we will create an automated system to make the home light bulb connected to the web using AWS, an ESP32 board, a relay module and Arduino Code.
This is the last part of the series and here we will achieve our ultimate goal to Power ON the Light bulb with just one-click from anywhere, literally from anywhere even from the Antarctic as they got internet there. IoT empowers everyone to make life smarter & easier. Though this is just a beginning, if readers show up enthusiasm, I will make more tutorials where the primary focus is to teach from
scratch and make cost-effective solutions
[Do let me know on LinkedIn].
The following series split into four parts (refer below) with very simple and clear instructions to provision a home automation system to control house appliances through the web.
Everything covered from scratch you won't face any difficulty understanding. In case of any clarification, drop me a note on LinkedIn. Feel free to explore them with ease, skip to the one which is relevant to you.
Prerequisites:
  1. It's the continuation of the following series. Make sure you have exercised Part I - Connect your device (ESP32) to AWS cloud rigorously.
  2. This tutorial mostly covers hands-on, prior knowledge of AWS IoT is an advantage. Click here to check AWS Official IoT Documentation.
  3. A 2 channel relay module (Easily available in Amazon.com/Amazon.in /Aliexpress or Local Robotics Shop) and a power bank to power up the ESP32.
Learning Objectives:
  1. By using a web client, we will turn ON/OFF the light bulb by using AWS, an ESP32 board, a relay module and Arduino Code. We will leverage the power of Device Shadow which is very effective in case of power loss and connectivity issue. The device shadow stores the desired state and when the light bulb establishes the connection, the desired state gets synced.
  2. Bonus - Toggle the light by using Google Assistant or Alexa. 

So let's see something happen now.

We will copy the below Arduino code, do some minor changes in Arduino IDE and make the code functional. Alternatively, you can download the Arduino Code as ino file here
/*********
  Gourav Das
  Complete project details at https://hackernoon.com/cloud-home-automation-series-part-4-connected-light-bulb-using-aws-esp32-and-arduino-94n377d
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <AWS_IOT.h>
#include <WiFi.h>
#include <ArduinoJson.h>

AWS_IOT lightbulb;
int relay_pin = 13; // Relay Pin

char WIFI_SSID[]="Wifi-Name";
char WIFI_PASSWORD[]="Wifi_Password";
char HOST_ADDRESS[]="************-***.iot.us-east-1.amazonaws.com";  //AWS IoT Custom Endpoint Address
char CLIENT_ID[]= "ESP32";
char SHADOW_GET[]= "$aws/things/{Thingname}/shadow/get/accepted";
char SENT_GET[]= "$aws/things/{ThingName}/shadow/get";
char SHADOW_UPDATE[]= "$aws/things/{ThingName}/shadow/update";

int status = WL_IDLE_STATUS;
int msgReceived=0;
char payload[512];
char reportpayload[512];
char rcvdPayload[512];

void mySubCallBackHandler (char *topicName, int payloadLen, char *payLoad)
{
    strncpy(rcvdPayload,payLoad,payloadLen);
    rcvdPayload[payloadLen] = 0;
    msgReceived = 1;
}

void updateShadow (int power)
{ 
  sprintf(reportpayload,"{\"state\": {\"reported\": {\"power\": \"%d\"}}}",power);
  delay(3000);   
    if(lightbulb.publish(SHADOW_UPDATE,reportpayload) == 0)
      {       
        Serial.print("Publish Message:");
        Serial.println(reportpayload);
      }
    else
      {
        Serial.println("Publish failed");
        Serial.println(reportpayload);   
      }  
} 

void setup() {
  Serial.begin(115200);
  pinMode(relay_pin, OUTPUT);
  delay(2000);  

    while (status != WL_CONNECTED)
    {
        Serial.print("Attempting to connect to SSID: ");
        Serial.println(WIFI_SSID);
        // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
        status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

        // wait 5 seconds for connection:
        delay(5000);
    }

    Serial.println("Connected to wifi");

    if(lightbulb.connect(HOST_ADDRESS,CLIENT_ID)== 0) //Connect to AWS IoT COre
    {
        Serial.println("Connected to AWS");
        delay(1000);

        if(0==lightbulb.subscribe(SHADOW_GET,mySubCallBackHandler)) //Subscribe to GET Shadow Service
        {
            Serial.println("Subscribe Successfull");
        }
        else
        {
            Serial.println("Subscribe Failed, Check the Thing Name and Certificates");
            while(1);
        }
    }
    else
    {
        Serial.println("AWS connection failed, Check the HOST Address");
        while(1);
    }
  
  //Sent Empty string to fetch Shadow desired state
  delay(3000);   
    if(lightbulb.publish(SENT_GET,"{}") == 0)
      {       
        Serial.print("Empty String Published\n");
      }
    else
      {
        Serial.println("Empty String Publish failed\n");
      }     
}

void loop() {
  
 if(msgReceived == 1)
    
  {
        msgReceived = 0;
        Serial.print("Received Message:");
        Serial.println(rcvdPayload);
        StaticJsonDocument<256> doc;
        deserializeJson(doc, rcvdPayload);
        
    // Test if parsing succeeds.
        if (doc.isNull()) {
        Serial.println("parseObject() failed");
        return;
        }
    
        int power = doc["state"]["desired"]["power"];
        Serial.println(power);
        if(power == 1)
        digitalWrite(relay_pin, LOW);
        else if(power == 0)
        digitalWrite(relay_pin, HIGH);
    updateShadow(power);  
    }  
}
We need to add a library in Arduino IDE, go to Tools → Manage Libraries. Search for ArduinoJson (by Benoit Blanchon), select the latest 6.x.x version only and click install. The code won't work on 5.x.x and below versions. Also, remember that we have used AWS_IOT library in the code to integrate ESP32 with AWS. If you are unaware, go to Part 1 of the series. Also, check the Certificates enrollment section under Hardware integration.

Code Modifications

char WIFI_SSID[]="Wifi-Name";
char WIFI_PASSWORD[]="Wifi_Password";
char HOST_ADDRESS[]="************-***.iot.us-east-1.amazonaws.com";  //AWS IoT Custom Endpoint Address
char CLIENT_ID[]= "ESP32";
char SHADOW_GET[]= "$aws/things/{Thingname}/shadow/get/accepted";
char SENT_GET[]= "$aws/things/{ThingName}/shadow/get";
char SHADOW_UPDATE[]= "$aws/things/{ThingName}/shadow/update";
Update the necessary details, skip
CLIENT_ID[]= "ESP32"
(Keep it as it is). In
HOST_ADDRESS[]
put the AWS IoT Endpoint Address which you can retrieve from IoT Dashboard, settings(check sidebar). Next, we will replace
{ThingName}
in the code with the actual thing name (e.g. ESP32) we gave at the time of thing creation in Part 1 of the series. To check the
Thing Name
, Click Here to go to AWS IoT Console (Region: N. Virginia), select Things under the
Manage
option from the Sidebar and check for the name as highlighted below.
Now plug your ESP32 board with your Desktop/Laptop using a USB cable and upload the code.

ESP32 Wiring

Warning:
In this exercise, we’re dealing with the mains voltage . Playing with mains voltage is like playing with fire. If you’re not familiar with mains voltage seek help. While programming the ESP or wiring your circuit make sure everything disconnected from the mains voltage.
At first, we will connect the jumper wires (F/F) with 2 channel relay module, as shown below. We will use an extension cord to light up the bulb, as a
precautionary measure
you should avoid putting the plug to mains voltage while making all the following connections. Next, put the live wire coming out of the plug into relay's COM1 port and make a connection from relay's NO1 port to the bulb. Thus, by making this connection, ESP32 will able to control the Relay Module and instruct it when to switch ON/OFF the light bulb.
Note: Never touch the relay module when powered from the mains voltage.
First, understand the fundamentals and by take some basic electrical courses you would be able to light up your entire home with just a click of a button.
  • ESP32 VIN to Relay VCC
  • ESP32 GND to Relay GND
  • ESP32 D13 to Relay IN1
  • Relay COM1 to Main Power Source
  • Relay NO1 to Bulb
Once we have built the above connection we are almost done. Now, power on the ESP32 by using an external power source (Power Bank), wait for some time for the connection to establish and also we need to Switch ON the main power of the bulb for to make the circuitry functioning. Now we are going to test the web endpoints we have created in part 3, hit your Node-RED primary URL followed by /ON, AWS (e.g.
http://52.90.186.136:1880/ON
) and IBM Cloud (e.g.
https://aws-iot.eu-gb.cf.appdomain.cloud/ON
). It will load a website, click on the light bulb to turn ON/OFF the bulb. If you have come so far, tadaa! You did it finally 💪 and be proud of your new achievement and show the world what are you capable of 👩‍💻 👨‍💻.
Few things to remember:
  1. Be gentle while turning ON/OFF the bulb, it may get stuck if clicked very fast. Reset will surely help in that case, press EN in ESP32 to re-establish the connection with AWS.
  2. AWS Device shadow is a powerful tool. In case of power loss or connectivity issue, the device shadow stores the desired state which it receives from the web-client hosted in Node-RED. When the light bulb establishes the link, the desired state gets synced. You can try it out by taking the mains power supply of the bulb after that send the desired state (ON/OFF) request from the web-client. When you powered back the Bulb you will see the magic. 🧙‍♀️ 🧙‍♂️
Congratulations on completing the 4th part :)
. It is an immense pleasure to see you here and reading this, I thank you individually. Stay curious and if you want more tutorials do let me know on LinkedIn. It will help me to come back with more tutorial on various topic of public interest.
Bonus
: After getting a few feedbacks, I thought to integrate the following tutorial with Voice Assistance. You can now continue with the tutorial & integrate it either with Google Assistant or Alexa. Click here 
for step-by-step instructions. 
Kindly Share & Comment only if you find it useful and help me on my mission to educate and familiarize people in the world of digitization 💪 #This is a Free tutorial and all my upcoming tutorials will be free and accessible from Public forums.# Appreciate if you drop me a note on 
LinkedIn
 & share your opinion. Don't worry, I don't bite 👻 so don't shy away 🏃🏻‍♀️ 🏃🏻. Your feedback will help me to come up  with more awesome contents on the internet. 

Written by gourav-das | Tech Enthusiast and Clouder. AWS 6x & Azure 2x Certified. & I still watch One piece and spongebob
Published by HackerNoon on 2020/02/16