With the advancement in virtual assistants like Google Assistant and Alexa, Home automation and Voice controlled applications are becoming normal. Now, we ourselves have built many home automation projects, from simple Automatic Staircase Lights to IoT based web controlled Home Automation using Raspberry Pi. But this project here is different, the idea here is to create a practical Home automation board that can fit into our AC power units on our walls and stay concealed inside it. The board should not interrupt the normal working of our power unit switches, that is they should turn ON or OFF with manual switches as well. And without being said, it should also be able to control the same load with voice using google assistant and also set a timer so that any load can automatically turn ON or OFF during a preset time of the day.
This project is very similar to our ESP8266 Smart Wi-Fi plug but here since we will be using ESP12, we will have more GPIO pins allowing us to control four AC loads simultaneously. Also, since we have integrated Blynk and Google Assistant, the project gets interesting and practical to use. For this project we have built the circuit boards using PCBGOGO PCB manufacturing service. In the later section of the article we have provided the Gerber file designed for the circuit and also explained the complete procedure to order the PCBs from PCBGOGO.
Warning: This project involves working with the AC mains voltage. Be advised that extreme caution should be taken when working with high AC voltages. Make sure you are supervised by an experienced person if you are new.
Circuit Diagram for Google Assistant controlled Home Automation
The complete circuit diagram for home automation can be found below.
As you can see, the circuit is very simple, let’s start the explanation from the ESP12E Wi-Fi Module. You can also check out the video below for a detailed project explanation. The module can be programmed just like nodeMCU development boards and it reduces a lot of space. By default, when powered on, ESP12E will enter operation mode. In order to program it, we have to use the Reset and Flash button. That is to put the ESP12 in programming mode, press and hold both the Reset and Flash button, then release the reset button. This will boot the ESP12E with the flash button pressed, now release the flash button and ESP12E will enter programming mode. After programming, you have to press the reset button again to boot the ESP12E in normal operation mode to execute the uploaded Program. The programming pins Rx, Rx, and Ground are extended out to be able to connect with an FTDI board or USB to TTL converter. Make sure to connect the Tx pin of ESP12 to the Rx pin of the Programmer and vise versa.
The other flag pins I1 to I4 and R1 to R4 are used to connect the Switches and Relays. Pins I1 to I4 stand for Input pins. All these pins support internal pull-up resistor so we just have to connect the switches on extension box to our Input pin through a pull-down resistor as shown below.
Similarly, the Relay output pins R1 to R4 are used to control the Relays. We have used a standard relay driver circuit with BC547 and IN4007 Diode as shown below. Note that the relays should be triggered with 5V but the ESP12E output pins are only 3.3V. So, it is mandatory to use a transistor to drive the relays. We have also placed an LED in the base path of the transistor so that whenever the transistor is triggered, the LED will also turn on.
Finally, to power all our circuits, we have used the Hi-Link AC-DC converter to convert our 220V AC to 5V DC. This 5V DC is then converted to 3.3V using an AMS117-3.3V voltage regulator. The 5V is used to trigger the Relays and 3.3V is used to power the ESP21 Wi-Fi Module.
Setting up the Blynk Application
We have previously built many Blynk projects like Wi-Fi Controlled Arduino Robot, so we won't be getting into the details of setting up the blynk application. But to put it simple, just install the application, create a new project for NodeMCU and start placing your widgets as shown below.
I have used virtual pins V1 to V4 to control relay 1 to 4 on our project. Make sure to change the type of button to switch. The timer option can also be used to trigger the virtual pins automatically for the set time, even if the phone is turned off. I have used a timer for only virtual pin V1 here, for example, but you can use it for all four pins if needed.
Make sure to get your blynk auth token value from your project page. Just click on the nut icon (circled in red in the above picture) and copy the auth token using copy all option and paste it somewhere safe, we will need when programming the Arduino board.
Setting Up IFTTT with Google Assistant and Blynk to Read String
The easiest way to use Google Assistant for home automation is by using IFTTT. We have also built many IFTTT projects previously with NodeMCU and Raspberry Pi. In this project, we will be using the Blynk app to trigger a webhook using Google assistant. It is very similar to our voice controlled home automation and voice controlled FM radio project. Except, here we will be using blynk with IFTTT to send string which makes it a lot easier and interesting.
Basically, we will be using virtual pin V5 and V6 on blynk to send the trigger command. V5 will be used for turn-on commands and V6 will be used for turn off commands. For example, if we say turn on TV and Lamp. The string command here “TV and Lamp” will be sent to NodeMCU using an API. The syntax of API is as below.
http://188.166.206.43/[auth _token]/update/V5?value=TV and Lamp
Now all we have to do in IFTTT is that use google assistant as IF and webhooks as THAT so listen for this command and send the information to NodeMCU using the above-mentioned API. The turn-on applet form the same is shown below.
Note that you have to select say a phrase with text ingredient option when creating a recipe for Google Assistant. Similarly, you have to repeat the same for virtual pin V6 to turn off the relays. You can check the video at the bottom of this page for detailed information.
Programming Arduino for Blynk Home Automation
The complete Arduino code for this project can be found at the bottom of this page. The explanation of the same is as follows. Before that make sure you can use Blynk and Program NodeMCU from Arduino IDE. If not follow the getting started with ESP12 article. Also, add the blynk library to Arduino IDE using the board manager.
As always, we begin our code by defining the input and output pins, here the input will be from switches and output will be from relays. We have defined the pin names for all four switches as sw and relays as rel as you can see below.
#define sw1 13 #define sw2 12 #define sw3 14 #define sw4 16 #define rel1 4 #define rel2 5 #define rel3 9 #define rel4 10
In the next stage, you have to enter some credentials like blynk auth token and the user name and password for the Wi-Fi router to which your nodeMCU should connected with. The blink auth token can be obtained from the blynk application. We will learn more about that in the setting up blynk application section.
char auth[] = "Fh3tm0ZSrXQcROYl_lIYwOIuVu-E"; //get from blynk application char ssid[] = "home_wifi"; char pass[] = "fakepass123";
Next, we have given the definition for a function called read_switch_toggle(). In this function, we will compare the current state and previous state of our switches. If the switch has been turned on or turned off i.e. If the switch has been toggled. There will be a change in the state of the switch, the function will monitor this change and return the switch number. If no change is detected, it will return 0.
int read_switch_toggle() { int result = 0; //Note all previous values for (int i=0; i<=3; i++) pvs_state[i] = crnt_state[i]; //Read the current status of switchs crnt_state[0] = digitalRead (sw1); crnt_state[1] = digitalRead (sw2); crnt_state[2] = digitalRead (sw3); crnt_state[3] = digitalRead (sw4); //compare current and pvs state for (int i=0; i<=3; i++) { if (pvs_state[i] != crnt_state[i]) { result = (i+1); //if any switch is toggled we get switch number as result return result; } else result = 0; //if no change result 0 } return result; //return the resul }
Next, we have the code for blynk application. We will be using virtual pin V1 to V6 to control our smart junction box. Pins V1 to V4 will be used to control relays 1 to 4 respectively directly from the blynk application. The below code shows what happens when V1 is triggered from blynk application. We simply read the status (HIGH or LOW) and control the relay accordingly.
BLYNK_WRITE(V1) { digitalWrite(rel1,param.asInt()); Serial.println("V1"); }
Similarly, the virtual pins can also be used to read a string from blynk application. We will learn how to send a string from google assistant to NodeMCU using IFTTT and Google assistant later but for now, let's see how the NodeMCU code reads this string and searches for a particular keyword and triggers the relay accordingly.
In the below code, you can see that when virtual pin V5 is triggered, we get the string passed by it into a string variable called ON_message. Then using this string variable and inderOf method, we search if any keywords like “lamp”, “LED”, “music”, “TV” are present, if yes, we turn on that particular load. If the keyword “everything” is detected, we turn on everything. The same can also be done for V6 to turn off the relays. We will understand more about this when we get into the IFTTT section.
BLYNK_WRITE(V5) { String ON_message = param.asStr(); Serial.println (ON_message); if(ON_message.indexOf("lamp") >= 0) digitalWrite(rel1,HIGH); if(ON_message.indexOf("LED") >= 0) digitalWrite(rel2,HIGH); if(ON_message.indexOf("music") >= 0) digitalWrite(rel3,HIGH); if(ON_message.indexOf("TV") >= 0) digitalWrite(rel4,HIGH); if(ON_message.indexOf("everything") >= 0) { digitalWrite(rel1,HIGH);digitalWrite(rel2,HIGH);digitalWrite(rel3,HIGH);digitalWrite(rel4,HIGH); } }
Finally, inside the loop function, we only have to check if any buttons are switch position has changed. If yes, then we use a switch case like shown below to toggle the position of that particular relay.
switch (toggle_pin) { case 0: break; case 1: Serial.println("Toggling Relay 1"); digitalWrite(rel1,relay_state[toggle_pin -1]); break; case 2: Serial.println("Toggling Relay 2"); digitalWrite(rel2,relay_state[toggle_pin -1]); break; case 3: Serial.println("Toggling Relay 3"); digitalWrite(rel3,relay_state[toggle_pin -1]); break; case 4: Serial.println("Toggling Relay 4"); digitalWrite(rel4,relay_state[toggle_pin -1]); break; } }
Fabricating PCB using PCBGoGo
Now we understand how the schematics work, we can proceed with building the PCB for our Home automation project. The PCB layout for the above circuit is also available for download as Gerber from the link.
Now our design is ready, it is time to get them fabricated using the Gerber file. To get the PCB done from PCBGOGO is quite easy, simply follow the steps below-
Step 1: Get into www.pcbgogo.com, sign up if this is your first time. Then in the PCB Prototype tab, enter the dimensions of your PCB, the number of layers, and the number of PCB you require. Assuming the PCB is 80cm×80cm, you can set the dimensions as shown below.
Step 2: Proceed by clicking on the Quote Now button. You will be taken to a page where to set a few additional parameters if required like the material used track spacing, etc. But mostly, the default values will work fine. The only thing that we have to consider here is the price and time. As you can see the Build Time is only 2-3 days and it just costs only $5 for our PCB. You can then select a preferred shipping method based on your requirement.
Step 3: The final step is to upload the Gerber file and proceed with the payment. To make sure the process is smooth, PCBGOGO verifies if your Gerber file is valid before proceeding with the payment. This way, you can sure that your PCB is fabrication friendly and will reach you as committed.
Assembling the PCB
After the board was ordered, it reached me after some days through courier in a neatly labeled well-packed box, and like always, the quality of the PCB was awesome. The PCB that was received by me is shown below. As you see, both the top and bottom layer has turned out as expected.
The vias and pads were all in the right size. It took me around 15 minutes to assemble to PCB board to get a working circuit. The assembled board is shown below.
Connecting the Board with AC Power Units / Extension Boards
The board is designed to be fixed inside the AC power sockets in our homes. But for the sake of this project, we will be using an extension box. If you want a more permanent solution, then wire this up inside your AC power sockets, as you can see below the length of the PCB is compact enough to be placed inside an AC power socket.
Make sure you follow safety precautions while working with AC mains. Follow the circuit diagram below to understand how to connect your relays and switches to our PCB board.
The connection diagram is down only for one Relay and switch but you can just replicate the same for the remaining three as well. Once the connections are done, your board should look like this
Once the connections are made, make sure you have secured them tightly with screw terminals and also use hot glue for additional safety. Pack everything back into the box and we should be ready for testing. You can find the complete working of this project in the video below.
I hope you enjoyed the article and learned something useful. If you have any questions, please leave them in the comment section below or use our forums.
/* * Smart Spike Buster for Home Automation using Google Asistant with Manual Control * Switches connected to 13,12,14,16 * Relay are triggered by 4,5,9,10 */ #define sw1 13 #define sw2 12 #define sw3 14 #define sw4 16 #define rel1 4 #define rel2 5 #define rel3 9 #define rel4 10 #define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> char auth[] = "Fh3tm0ZSrXQcROYl_lIYwOIuVu-E"; //get from blynk application char ssid[] = "home_wifi"; char pass[] = "fakepass123"; //http://188.166.206.43/Fh3tm0ZSrXQcROYlwOIuVu-E/update/V1?value=0 //use D4,D5,V1 and V2 boolean crnt_state[] = {0,0,0,0}; boolean pvs_state[] = {0,0,0,0}; boolean relay_state[] = {0,0,0,0}; int read_switch_toggle() { int result = 0; //Note all previous values for (int i=0; i<=3; i++) pvs_state[i] = crnt_state[i]; //Read the current status of switchs crnt_state[0] = digitalRead (sw1); crnt_state[1] = digitalRead (sw2); crnt_state[2] = digitalRead (sw3); crnt_state[3] = digitalRead (sw4); //compare current and pvs state for (int i=0; i<=3; i++) { if (pvs_state[i] != crnt_state[i]) { result = (i+1); //if any switch is toggled we get switch number as result return result; } else result = 0; //if no change result 0 } return result; //return the result } void setup() { //Decalre all switchs as input pinMode(sw1, INPUT_PULLUP); pinMode(sw2, INPUT_PULLUP); pinMode(sw3, INPUT_PULLUP); pinMode(sw4, INPUT_PULLUP); //Decalre all relays as output pinMode(rel1, OUTPUT); pinMode(rel2, OUTPUT); pinMode(rel3, OUTPUT); pinMode(rel4, OUTPUT); //Initialize all pin to LOW digitalWrite (rel1,LOW);digitalWrite (rel2,LOW);digitalWrite (rel3,LOW);digitalWrite (rel4,LOW); Serial.begin(9600); Blynk.begin(auth, ssid, pass); } //Control relay usinf Blynk Virtual Pins BLYNK_WRITE(V1) { digitalWrite(rel1,param.asInt()); Serial.println("V1"); } BLYNK_WRITE(V2) { digitalWrite(rel2,param.asInt()); Serial.println("V2"); } BLYNK_WRITE(V3) { digitalWrite(rel3,param.asInt()); Serial.println("V3"); } BLYNK_WRITE(V4) { digitalWrite(rel4,param.asInt()); Serial.println("V4"); } BLYNK_WRITE(V5) { String ON_message = param.asStr(); Serial.println (ON_message); if(ON_message.indexOf("lamp") >= 0) digitalWrite(rel1,HIGH); if(ON_message.indexOf("LED") >= 0) digitalWrite(rel2,HIGH); if(ON_message.indexOf("music") >= 0) digitalWrite(rel3,HIGH); if(ON_message.indexOf("TV") >= 0) digitalWrite(rel4,HIGH); if(ON_message.indexOf("everything") >= 0) { digitalWrite(rel1,HIGH);digitalWrite(rel2,HIGH);digitalWrite(rel3,HIGH);digitalWrite(rel4,HIGH); } } BLYNK_WRITE(V6) { String OFF_message = param.asStr(); Serial.println (OFF_message); if(OFF_message.indexOf("lamp") >= 0) digitalWrite(rel1,LOW); if(OFF_message.indexOf("LED") >= 0) digitalWrite(rel2,LOW); if(OFF_message.indexOf("music") >= 0) digitalWrite(rel3,LOW); if(OFF_message.indexOf("TV") >= 0) digitalWrite(rel4,LOW); if(OFF_message.indexOf("everything") >= 0) { digitalWrite(rel1,LOW);digitalWrite(rel2,LOW);digitalWrite(rel3,LOW); digitalWrite(rel4,LOW); } } void loop() { Blynk.run(); int toggle_pin = read_switch_toggle(); if (toggle_pin !=0) //if any switch toggle is detected { relay_state [(toggle_pin-1)] = !relay_state [(toggle_pin-1)]; //change the particular bit switch (toggle_pin) { case 0: break; case 1: Serial.println("Toggling Relay 1"); digitalWrite(rel1,relay_state[toggle_pin -1]); break; case 2: Serial.println("Toggling Relay 2"); digitalWrite(rel2,relay_state[toggle_pin -1]); break; case 3: Serial.println("Toggling Relay 3"); digitalWrite(rel3,relay_state[toggle_pin -1]); break; case 4: Serial.println("Toggling Relay 4"); digitalWrite(rel4,relay_state[toggle_pin -1]); break; } } //delay (500); }