Designing a Home Automation IoT device

Ari Mahpour
|  Created: November 23, 2021  |  Updated: November 26, 2021
Designing a Home Automation IoT device

Assistants in the form of speakers, such as Google Home and Amazon’s Alexa, have managed to find their way into countless homes these days. They connect with our smart lights, our smart speakers, our smart thermostats, and almost anything that begins with “smart.” Tinkerers and engineers have discovered that they can also make their widgets “smart” and control them with their smart speakers as well. Tutorials for projects like smart robotic arms, homemade smart switches, or even smart cocktail mixers can be found on the web. One thing I don’t like about my smart speaker is that I always have to talk to it in order to control my smart devices. What if I’m not in the mood to talk? Maybe I don’t want my 5 year old constantly asking it to tell him jokes. Why do I have to go hoarse just to turn my lights on and off? I slowly became more and more nostalgic for what we used to have back in the old days: a light switch. I decided to venture off into “maker” land and create my own series of IoT connected buttons that would enable me to run some home automation routines without the use of my voice or smartphone. In this tutorial I’m going to show you how to put that circuit together and write all the firmware needed to get that up and running using cheap, easy to get, electronic devices.

Getting Started

To get started we’re going to need a few things. We’ll also need to set up some software both on our desktop and online. Here is a list of hardware that you’ll need to complete this project:
1. NodeMCU board
2. Breadboard, 10k Ohm resistor, SPST pushbutton, and Jumper wires (The kit contains these items and more)

Additionally, you’ll need to set up your NodeMCU device. See Getting Started with ESP8266 to get that going. Once you have all your parts and your environment set up we’ll get our circuit together first and then move on to the code.

The Circuit

We’ll need to put the circuit together first before implementing the code. In this case I want two buttons: one to turn on my lights and one to turn them off. Here’s what the circuit diagram looks like:


 

Figure 1: Circuit diagram of NodeMCU module with Push Button

There are really only two components (in addition to the NodeMCU) here that we are using: a resistor and a pushbutton. By connecting the 10k Ohm resistor between D0 and GND we are creating a weak pull-down on D0, setting it to a default state of “0” when nothing else is driving this input. As soon as the pushbutton is pressed a connection will be made between D0 and the 3.3V bus on the NodeMCU device. This means that the device will now register a “1” as the digital input since the 3.3V pull-up is stronger than the weak, 10k Ohm, pull-down to ground.

The Linker

Before we move forward with writing the code we need to set up a system that will act as an intermediary between our IoT devices (i.e. smart light bulbs) and our “smart” buttons. In theory, we could write code that directly speaks to my smart light bulbs (via their API server) but that would take much more time and effort. Instead I am leveraging IFTTT, also known as “If this then that.” Essentially, you connect your home devices with their service, create some sort of condition (e.g. arriving home, hitting a button on your phone, etc.) and then an action as a result (e.g. turn on some lights, play music on your smart speaker, etc.). In this example I have set up a webhook to be my trigger and the action to turn my lights on and off. Let’s walk through how to set up IFTTT first.

To get started you’ll need to create an account with IFTTT. After creating your account and logging in click on the Create button at the top right corner:


Figure 2: Create button on IFTTT
 

Let’s first create the If condition by clicking on “Add.”

 

Figure 3: Adding an “if” condition

Type in “webhooks” in the search box and select the Webhooks service.

 

Figure 4: Webhooks service

We want to make it as simple as possible so we’re going to start with a basic web request. Click on the “Receive a web request” button.

 

Figure 5: Receive a web request

In the next step let’s fill in the event name (I used “lights_on” as an example) and then click on “create trigger.”

 

Figure 6: Naming the trigger

After creating the “If” condition we’ll now add the “Then That” response. Click on “Add” in the “Then That” box.

Figure 7: “Then That” box

Everyone’s home automation setup is going to be different. I’m using a Wyze smart bulb to light up my living room. This is what I will be controlling with my smart button. If you’re also using a Wyze product then go ahead and type “Wyze” in the search bar and the Wyze icon should show up:

 

Figure 8: Wyze service

Since I want to turn on a light bulb (or all my light bulbs) I will select “Turn bulb on” from the list of tiles. A drop down will show up on the list of devices (or all devices) and then you can click on “Create Action.” Once you come back to the create page you will see that both the “If” and “Then” boxes have been populated. Click on “Continue” and then “Finish” to create the applet. Repeat this step to turn off your light bulb. You can call it “lights_off.”

The final step is to get the web address to trigger this webhook. On the top right corner of any IFTTT page click on the little profile picture and then click on “My Services.”

Figure 9: My Services

Scroll down until you see Webhooks and click on it. You’ll be taken to a page that looks like this:

Figure 10: Your key and how to use it

The top red square is your key. Do not share this with anyone. Consider it like a password. The second red box will generate the URL for you once you fill in the event name. Since the event that we used is “lights_on” I filled that in the box. The third red box contains the full URL needed to trigger this event. Save this URL because this is what we will be using in our code. To test it just copy the text starting with “https” and paste it into your browser. Your light bulb(s) should turn on within 10 seconds or so. We’re now ready to move onto the code portion of this project.

The Code

The code for this project is very straightforward. It is built off two examples found in the Arduino Examples. The first example is the digital button input example (File > Examples > 02.Digital > Button). We’re just looking to snatch the button portion of the code and not the LED piece. The second example we’re going to need is the Basic HTTP Client example from the ESP8266 libraries (File > Examples > ESP8266HTTPClient > BasicHttpClient). As mentioned above you need to make sure you’ve set up your environment with the NodeMCU ESP8266 module using the Getting Started with ESP8266 guide. Once that’s all up and running create a new sketch and paste the following code in there:

// Includes
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// Constant Definitions
#define ON_BUTTON 16          // The on push button is hooked up to D0 (pin 16)
#define OFF_BUTTON 5          // The off push button is hooked up to D1 (pin 5)
#define DELAY_COUNT_MS 3000   // Timeout to wait in between button presses
#define SSID "<YOUR ROUTER SSID>"
#define PASSWORD "<YOUR ROUTER PASSWORD>"

void setup() {
  // Configure all hardware interfaces
  pinMode(ON_BUTTON, INPUT);
  pinMode(OFF_BUTTON, INPUT);
  Serial.begin(115200);

  // Printing a few empty lines to clear the buffer
  Serial.println();
  Serial.println();
  Serial.println();

  // Initialize the Wi-Fi
  WiFi.begin(SSID, PASSWORD);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // Wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {

    // Check for button press
    // Turn the lights on
    if (digitalRead(ON_BUTTON) == 1) {
      Serial.println("Turning on lights...");
      runHttpRequest("http://maker.ifttt.com/trigger/lights_on/with/key/b01-GqZi4tPPo822AK0nBk");
    }
    // Turn the lights off
    else if (digitalRead(OFF_BUTTON) == 1) {
      Serial.println("Turning off lights...");
      runHttpRequest("http://maker.ifttt.com/trigger/lights_off/with/key/b01-GqZi4tPPo822AK0nBk");
    }
  }

  delay(1);
}

// This method runs an HTTP GET using the ESP8266 libraries
void runHttpRequest(String url) {
  WiFiClient client;
  HTTPClient http;

  Serial.println("Sending the following URL request: " + url);

  if (http.begin(client, url)) {  // HTTP 
    Serial.print("[HTTP] GET...\n");
    // Start connection and send HTTP header
    int httpCode = http.GET();
  
    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
  
      // File found at server
      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        String payload = http.getString();
        Serial.println(payload);
      }
    } 
    // Something went wrong with the HTTP GET
    else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }
  
    http.end();
  }
  
  else {
    Serial.printf("[HTTP} Unable to connect\n");
  }

  delay(DELAY_COUNT_MS);
}

 

There are just a few places where you need to modify this code. There are two defines at the top, SSID and PASSWORD. This is your router SSID (i.e. name) and router password. You’ll need to put those values in there and make sure you keep them in quotes. There are also two repeated functions that require changing the URL. About halfway down through the code you will see that the runHttpRequest() function is being called with a URL as a parameter. This is the test URL that you generated in Figure 10 (and then subsequently for your second web service, lights_off). You can just replace the key at the very end of the URL as well. Take note of the fact, however, that I am using HTTP and not HTTPS. We did not implement HTTPS in this example so you will get a 400 HTTP return error code if you attempt to run this example using HTTPS. As a result you need to use “http://” instead of “https://” as your IFTTT webhook link. If you plan on using this code permanently it’s good practice to use HTTPS. The Basic HTTPS Client example (File > Examples > ESP8266HTTPClient > BasicHttpsClient) provides you with the extra lines to create an SSL connection to successfully run an HTTPS request.

Go ahead and Upload the design to your device. You can open up the Serial Monitor and observe the response every time you click on one of your buttons. You should now also see your IoT device(s), such as the Wyze smart bulb(s), turn on and off.

Conclusion

In this article we learned how to create an IoT connected smart button. Utilizing the ESP8266 module and IFTTT we were able to trigger a smart home event, such as turning on our smart bulbs, using push buttons. After learning how to create this simple embedded device you should be able to take these principles and build off of them to create more complex IoT devices such as sensors that trigger different smart home products.

Would you like to find out more about how Altium Designer® can help you with your next PCB design? Talk to an expert at Altium.

About Author

About Author

Ari is an engineer with broad experience in designing, manufacturing, testing, and integrating electrical, mechanical, and software systems. He is passionate about bringing design, verification, and test engineers together to work as a cohesive unit.

Recent Articles

Back to Home