Introduction: WiFi Switch for Home Appliances With ESP8266
Learn how the build your own WiFi switch with the ESP module and how to control any appliance of your favorite place.
What are WiFi Switches?
Nowadays we are living in an Internet of Things age and WiFi Switches are basically the foundation of it. They are devices that can turn on, off or dim home appliances like lights, fans, etc remotely or autonomously, controlled by our cellphones, our voice, the room temperature or even weather reports.
How do they work?
They are based on wireless communication (commonly known as WiFi) that let them connect to the internet and process data, so they can take action due to certain conditions established by the user.
Supplies
Application requeriments:
- ESP8266 Module (ESP-01)
- PCB board
- Breadboard
- Wiring cables
- Ubidots account
- Arduino nano
Materials:
3x 1k ohm resistors 1/4w
2x 470 ohm resistors 1/2w
1x dual in line female connector (U3)
1x MOC3010 (Opto-triac)
1x Triac BTA24
1x 100nf 400v Capacitor
1x Hi-Link 3.3v Power Supply
1x Terminal Block 2p
1x Terminal Block 3p
Step 1: Schematic:
You can manufacture your PCB with PCBGoGo.
Step 2: Ubidots Device and Variable Creation.
a. Go to the Device section of your Ubidots account and create a new device called "wifiswitch".
b. Inside your "wifiswitch" device, create a variable called "light".
Step 3: Ubidots Dashboard and Widget Creation.
a. Once our device and variable are created, we can create a dashboard and widget to control the light from a web or mobile dashboard. To create a new dashboard, press the "Data > Dashboard". Then press the plus icon and complete the dashboard configuration as is desired.
b. Now, create a control widget to set the status of the light bulb associated with the variable "light". To create the control widget, select the plus icon located at the right upper side of the page. Then press "Switch" as widget type, select the variable desired to be controlled and complete the widget configuration as is desired.
c. Then you are ready to program and test your project.
Step 4: Programing With the Arduino IDE.
1. If not done yet, download the Arduino IDE.
1a. Open the Arduino IDE and select Files -> Preferences
1b. Add the url below into the Additional Board Manager URLs field. You can add multiple URLs by separating them with commas.
http://arduino.esp8266.com/stable/package_esp8266...
2. Open and Install the ESP8266 board in the Boards Manager: Tools -> Board -> Boards Manager
2a. You can easily find the board by typing “ESP8266” in the search bar.
3. Now, select the Generic ESP8266 board from Tools -> Board menu
4. Define or double check the Port of your PC which the device is communicating with. Go to Tools -> Port: -> Select the port.
4b. Ensure your IDE Upload Speed is 115200 by going to Tools -> Upload Speed -> 115200
5. Download the UbidotsESPMQTT library if you haven’t already. Now, click on Sketch –> Include Library –> Add .ZIP Library and choose the Ubidots ESP8266 MQTT library.
If properly uploaded, you get the response: "Library added to you libraries."
8. Close and open again the Arduino IDE.
Step 5: Programming the ESP8266:
Once your ESP8266 is set up, we can start publishing and subscribing data from/to Ubidots in order to control the Wifi Switch.
1. Copy and paste the following code in the Arduino IDE. Don’t forget to customize the Wi-Fi SSID and password and your Ubidots Token.
/****************************************
* Libraries
****************************************/
#include "UbidotsESPMQTT.h"
/****************************************
* Define constants ****************************************/
#define TOKEN "..........................." // Your Ubidots TOKEN
#define WIFINAME "........." //Your SSID
#define WIFIPASS "........." // Your Wifi Pass
#define DEVICE_LABEL "wifiswitch" // Name of the device
#define VARIABLE_LABEL1 "light" // Name of the Ubidots variable
const int ERROR_VALUE = 65535; // Error value
const uint8_t NUMBER_OF_VARIABLES = 2; // Cantidad de variables a las que el programa se va a suscribir char * variable_labels[NUMBER_OF_VARIABLES] = {"light"}; // Variables names
#define luz 0 #define boton 2
int seguro=0;
int ledState = LOW; // the current state of the output pin int buttonState; // the current reading from the input pin int lastButtonState = HIGH; // the previous reading from the input pin int reading; unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50;
float estadoluz; // Variable to be used in the code
float value; // Variable to store input data uint8_t variable; // To use with the switch case
Ubidots ubiClient(TOKEN);
WiFiClient client;
/****************************************
* Auxiliar functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length) { char* variable_label = (char *) malloc(sizeof(char) * 30); get_variable_label_topic(topic, variable_label); value = btof(payload, length); set_state(variable_label); execute_cases(); free(variable_label); /////////////////Light////////////////////
digitalWrite(luz, estadoluz); /////////////////Light//////////////////// }
// Parse topic to extract the variable label which changed value void get_variable_label_topic(char * topic, char * variable_label) { Serial.print("topic:"); Serial.println(topic); sprintf(variable_label, ""); for (int i = 0; i < NUMBER_OF_VARIABLES; i++) { char * result_lv = strstr(topic, variable_labels[i]); if (result_lv != NULL) { uint8_t len = strlen(result_lv); char result[100]; uint8_t i = 0; for (i = 0; i < len - 3; i++) { result[i] = result_lv[i]; } result[i] = '\0'; Serial.print("Label is: "); Serial.println(result); sprintf(variable_label, "%s", result); break; } } }
// cast from an array of chars to float value. float btof(byte * payload, unsigned int length) { char * demo = (char *) malloc(sizeof(char) * 10); for (int i = 0; i < length; i++) { demo[i] = payload[i]; } float value = atof(demo); free(demo); return value; }
// State machine to use switch case void set_state(char* variable_label) { variable = 0; for (uint8_t i = 0; i < NUMBER_OF_VARIABLES; i++) { if (strcmp(variable_label, variable_labels[i]) == 0) { break; } variable++; } if (variable >= NUMBER_OF_VARIABLES) variable = ERROR_VALUE; // Not valid }
// Function with switch case to determine which variable changed and assigned the value accordingly to the code variable void execute_cases() { switch (variable) { case 0: estadoluz = value; Serial.print("Luz: "); Serial.println(estadoluz); Serial.println(); break; case ERROR_VALUE: Serial.println("error"); Serial.println(); break; default: Serial.println("default"); Serial.println(); }
} /****************************************
* Funcion principal
****************************************/
void setup() {
// put your setup code here, to run once: pinMode(luz, OUTPUT); pinMode(boton, INPUT); ubiClient.ubidotsSetBroker("industrial.api.ubidots.com"); // Sets the broker properly for the business account ubiClient.setDebug(true); // Pass a true or false bool value to activate debug messages Serial.begin(115200); ubiClient.wifiConnection(WIFINAME, WIFIPASS); ubiClient.begin(callback); if(!ubiClient.connected()){ ubiClient.reconnect(); }
char* deviceStatus = getUbidotsDevice(DEVICE_LABEL);
if (strcmp(deviceStatus, "404") == 0) { ubiClient.add("light", 0); //Insert your variable Labels and the value to be sent ubiClient.ubidotsPublish(DEVICE_LABEL); ubiClient.loop(); }
ubiClient.ubidotsSubscribe(DEVICE_LABEL,VARIABLE_LABEL1); //Insert the Device and Variable's Labels Serial.println(variable_labels[1]);
}
void loop() { // put your main code here, to run repeatedly: if(!ubiClient.connected()){ ubiClient.reconnect(); ubiClient.ubidotsSubscribe(DEVICE_LABEL,VARIABLE_LABEL1); //Insert the Device and Variable's Labels } ubiClient.loop(); Read();
Debounce();
// save the reading. Next time through the loop, it'll be the lastButtonState: lastButtonState = reading; }
void Read(){ // read the state of the switch into a local variable: reading = digitalRead(boton); if (reading != lastButtonState) { // reset the debouncing timer lastDebounceTime = millis(); } }
void Debounce(){ if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state:
// if the button state has changed: if (reading != buttonState) { buttonState = reading; Toggle(); } } }
void Toggle(){ // only toggle the LED if the new button state is LOW if (buttonState == LOW) { ledState = !ledState; // set the LED: digitalWrite(luz, ledState); ubiClient.add("light", ledState); //Insert your variable Labels and the value to be sent ubiClient.ubidotsPublish(DEVICE_LABEL); } }
char* getUbidotsDevice(char* deviceLabel) { char* data = (char *) malloc(sizeof(char) * 700); char* response = (char *) malloc(sizeof(char) * 400); sprintf(data, "GET /api/v1.6/devices/%s/", deviceLabel); sprintf(data, "%s HTTP/1.1\r\n", data); sprintf(data, "%sHost: industrial.api.ubidots.com\r\nUser-Agent:wifiswitch/1.0\r\n", data); sprintf(data, "%sX-Auth-Token: %s\r\nConnection: close\r\n\r\n", data, TOKEN); char* data1 = data; free(data); if (client.connect("industrial.api.ubidots.com", 80)) { client.println(data1); } else { free(data); return "e"; } int timeout = 0; while(!client.available() && timeout < 5000) { timeout++; if (timeout >= 4999){ free(data); return "e"; } delay(1); }
int i = 0; while (client.available()) { response[i++] = (char)client.read(); if (i >= 399){ break; } } char * pch; char * statusCode; int j = 0; pch = strtok (response, " "); while (pch != NULL) { if (j == 1 ) { statusCode = pch; }
pch = strtok (NULL, " "); j++; } free(response); return statusCode;
}
Step 6: Configure Voice Commands Using Google Assistant:
To control your “WiFi Switch” with Google Home, first we need to configure an intermediary platform called IFTTT, this will let us to pair our Switch with the Google Assistant. To configure correctly, follow the steps shown below.
If you don't have an account, Sign up.
- Click on “My Applets”.
- Then, click on “New Applet”.
Click on “+ this” to configure the trigger of your condition.
Search for “Google assistant” service and click on it.
Click on “Say a simple phrase”.
Complete the trigger fields with the phrases you want to use to control the light, the response and the language, then click “Create trigger”.
Then, click on “+that” to configure the action.
Search for the “Webhooks” action service.
Click on “Make a web request”.
Complete action fields:
URL----> http://things.ubidots.com/api/v1.6/devices/wifisw... goes your Ubidots Token)
Method----> POST
Content Type----> application/json
Body----> To turn on {“light”:1}, to turn off {“light”:0}
11. Finally, click on Finish.
NOTE: Repeat everything to set the “Turn off the light” applet, with the correct Bodystatement.
Step 7: Testing Session:
Due to the diagram shown in the picture, connect correctly the module to your AC appliance.
Line---> L
Neutral---> N
Light Line'---> B
Add a momentary button of your preference in the terminal block called SW.
Identify the Line, Neutral and Light cables:
Make the connections and place the button, tight the screws and test.
In case you're a visual learner check out the following video tutorial. You can find all the steps I made to build this project carefully explained:
Step 8: Summary:
In this guide, we just learned how to build a WiFi switch that can be controlled over the internet by your voice, cellphone app, or your PC, that let you control a light bulb of a bedroom or any other place. This device works based on the ESP8266 WiFi module, that is a tiny module that let the project get online easily. And this device can be applied in the control of many different devices like fans, motors, curtains, lights, led strips, and much more.