Call or Text us: 1 (470) 231-7659
✈ Free Domestic Shipping on all Engineering Bundles!
Control a light switch with Arduino and WiFi ESP8266 tutorial

Make an IoT Switch to Control Any Device on WiFi

We sometimes use affiliate links in our content. This won't cost you anything, but it helps us to offset the costs of paying our writing team. You can support us directly on BuyMeACoffee. Thank you!

Free Robotics Course Robotics 101 by Learn Robotics
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn
Devices and homes are getting smarter these days. However, if you’re not the lucky owner of a brand-new house, you might be looking for ways to add home automation to your home without a big expense.

In this article, I’m going to share how you can make an IoT Switch that controls any device or appliance on WiFi. As a result, you’ll be able to control just about any device that’s hardwired into any light switch.

Additionally, I’ll show you how to add voice control to the Smart IoT Switch so that you can integrate this device with existing voice assistants and home automation systems.

Materials You’ll Need

Before you begin this project, you’ll need to buy and 3D print a few parts.

Here’s the list of materials you’ll need to create a Smart IoT Switch:

IZOKEE D1 Mini NodeMcu Lua 4M Bytes WLAN WiFi...
This D1 mini module is a mini WIFI board based on ESP-8266EX.
$15.99
Sale
4Pcs SG90 9g Micro Servos for RC Robot Helicopter...
High quality and high cost performance.; Operating speed: 0.1second/ 60degree ( 4.8V no load)
$11.99 −$2.01 $9.98
Gizmo Dorks 1.75mm PLA Filament 1kg / 2.2lb for 3D...
1.75mm diameter, 1kg net weight, PLA Filament; Filament Roundness: +/- 0.07mm; Filament Diameter: +/- 0.05mm
FlashForge Adventurer 3 Lite FDM 3D Printer
Build Volume: 150 x 150 x 150 mm; Layer Resolution: 0.1-0.4mm; Max. Print Bed Temperature: 100°C (212°F)
$369.00

If you don’t have a 3D printer, you can order the Smart Switch parts on our website, and we’ll print and ship them to you. You can also check out the list of 3D printers we recommend.

I recommend buying a 3D printer and learning how to manufacture parts if you plan on doing a lot of projects like this.

Download the 3D Printer Files

Download and print the Smart Switch Files from Thingiverse. I chose the Wemos D1 Mini Light switch with a Servo; however, there are many designs you can choose from.

Just make sure that the design fits a standard light switch, the Wemos D1 Mini, and a Micro 9g Servo.

After you have the files, print them out. I used Gizmo Dorks White PLA and printed at Draft Quality (Layer Height = 0.20mm) and about 20% Infill. The parts took me about 2 hours to print.

If you’re in the US, we can print these parts for you. Just submit your order, here.

Part 1. Assemble the Smart Switch

Now that you have the materials, it’s time to start the assembly process.

Step 1. Wiring Diagram

Before assembling the components, it’s a good idea to solder male header pins to the Wemos. I use a breadboard to hold the headers in place while I’m soldering.

Then, create a small wire harness to connect the servo motor to the Wemos. It’s a good idea to position the wires through the 3D printed case before soldering both ends of the harness.

Here’s a Wiring Diagram:

Control any light switch with a servo and Arduino Smart Switch
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn

Be sure the servo has a secure connection with the Wemos D1 Mini. Then move on Step 3 to finish the assembly.

Step 2. Attach Servo and Wemos D1 Mini

Once you have the 3D printed parts, mount the 9g Servo motor to the top of the mounting plate. Then, attach the servo horn. I used hot glue and the set screw included with the servo kit.

Next, press-fit the Wemos D1 Mini inside the controller compartment. The ESP8266 chip is facing up and the USB port is facing towards the right side.

Neatly tuck the wires aside. You can use a small zip tie to keep them together. Then, install the top plate cover. I used a bit of hot glue to keep the cover fully secure.

Smart Switch using Arduino and IoT
  • Facebook
  • Twitter
  • Pinterest
  • Buffer
  • reddit
  • LinkedIn

Now you should have a fully assembled IoT Switch that’s ready for programming!

Part 2. Programming the IoT Switch

There are four steps to write the code for our smart IoT switch.

Step 4. Calibrate Servo Positions

The first part includes calibrating the servo positions. This is important because we need to know which positions will turn the light switch on and off.

We also need to find a “home” position that will keep the servo horn in a neutral (center) position. That way if we want to move the switch manually, the horn won’t be blocking the switch.

You can use the test calibration code to figure out these positions.

Download the Smart Switch Position code, below.

Mount the IoT Switch to an outlet using the two existing screws on your light switch plate.

After the switch is mounted, plug the USB cord into the Wemos and your computer and give it a few seconds to initialize.

Upload the code to your Wemos. Then, open a Serial Monitor and type in an angle from 0-180. Figure out the position that moves the switch up, down, and center. Write these values down. We’ll use them in the next section.

Note: Servos are always active, which means, they’ll continuously receive a signal from the Wemos. Don’t try to manually move the servo horn or you risk sending feedback to the controller and frying it out.

Step 5. Create a method to control servo position

Use the readings from Step 4 to create a servo control method. I created three global variables (up, down, and center) to store the positions from the previous step. The setPos() method should look something like this:

/*
 * Control ON, OFF, NEUTRAL pos on servo for smart switch
 */
void setPos(int pos){
  if(pos == 1){
    smartSwitch.write(up); //switch is ON and up
  }
  else if(pos == 2){
    smartSwitch.write(down); //switch is OFF and down
  }
  else{
    smartSwitch.write(center); //servo horn is NEUTRAL
  }
  delay(50); //allow servo to move to pos
}

Once you have this method written, it’s time to receive and parse data from a Webhook service. For this tutorial, we’ll use Dweet.io, but you can also use IFTTT or service of your choice.

The Webhook service will store information from Siri or a Voice Assistant to control the state of the smart switch.

Note: If you use Dweet.io, know that your device will be “public” unless you buy a lock.

This means that technically anyone could set the status of your smartSwitch by setting the State variable to “on” or “off.”

For this tutorial, I’m not going to cover best practices for IoT security; however, if you’re concerned about this, you can use IFTTT and get a private webhook to use for this project.

Step 6. Receive Data from Webhook (Dweet.io)

To set the smart switch, we will use the ArduinoJSON library and Dweet.io to parse the data. Then, based on the status of our State variable, we’ll set the position of the Servo.

I created a getState() method to figure out this value. The first part is to create a client to connect to Dweet.io and get the latest “dweet,” or JSON file for the smartSwitch thing.

Code Block 1

/*
 * Pull data from dweet to set position
 */
void getState(){
  WiFiClient client;

  client.setTimeout(10000);
    if (!client.connect(host, 80)) {
      Serial.println(F("Connection failed"));
      return;
    }

    client.println("GET /get/latest/dweet/for/smartSwitch HTTP/1.0");
    client.println("Host: dweet.io");
    client.println("Connection: closed");
    if (client.println() == 0) {
      Serial.println("Failed to send request");
      return;
    }
  
      // Skip HTTP headers
    char endOfHeaders[] = "\r\n\r\n";
    if (!client.find(endOfHeaders)) {
      Serial.println("Invalid response");
      return;
    }

    //... continued in code block 2 ...
}

Once we have that JSON file, we can use the ArduinoJSON library to parse it. If you never worked with the ArduinoJSON library, it’s an easier way to access the key-value pairs using Arduino.

Use the ArduinoJSON v6 assistant tool to set up the parsing program:

Code Block 2

// ...continued from code block 1... 
// Allocate the JSON document 
// Use arduinojson.org/v6/assistant to compute the capacity. 
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + 120; 
DynamicJsonDocument doc(capacity); // Parse JSON object DeserializationError 
error = deserializeJson(doc, client); 
if (error) { 
     Serial.print(F("deserializeJson() failed: ")); 
     Serial.println(error.c_str()); return; 
} 
// Extract values 
JsonObject with_0 = doc["with"][0]; 
const char* with_0_thing = with_0["thing"]; // "smartSwitch" 
const char* with_0_created = with_0["created"]; // "2020-04-10T17:45:07.198Z" 
String switchState = with_0["content"]["State"]; //State value = "on" or "off" 
//...continued in code block 3...

I changed the name of the State key to “switchState,” just so that it’s easier to read. Then, I converted the string to lowercase so that I could run it through a set of conditional statements.

Code Block 3

//...continued from code block 2...	
    switchState.toLowerCase();

    Serial.print("Current State = ");
    Serial.println(currState);

    if(switchState != currState){
      if (switchState == "on"){
        Serial.println("smartSwitch ON"); //go to top position
        currState = "on";
        setPos(1);
        delay(100);      
      }
      if (switchState == "off"){ //go to bottom position
        Serial.println("smartSwitch OFF");
        currState = "off";
        setPos(2);
        delay(100);
      }
    }
    //goto NEUTRAL pos
    Serial.println("Set servo to NEUTRAL");
    Serial.println("");
    setPos(3);
    delay(50);

The conditional statements check to see the state value from Dweet and then moves the servo to the correct position. After the servo moves to the position, it’s commanded back to the neutral home position.

This code only runs if the new position from the Dweet website is different than the current position we’re at. There’s no point in moving the servo to the same position if we’re already there.

Note: You DO NOT want to “stall” the servo in any position. This could catch your switch in an “in-between” state, which can cause a short and/or pop breakers.

Make the moves as fast as you can. You’ll have to run some tests. But I’ve found that keeping the moves quick eliminates the risk of the servo horn getting “stuck” on the switch and causing problems.

Once you have the data from the JSON file, you can call the getState() in loop() and check every 2 seconds for a new reading.

You’ll have to play around by testing your code and tuning it for your particular scenario. However, this should give you a good starting point for setting up a versatile smart switch using Arduino.

Step 7. Download the Example Code

While it’s always more beneficial to try to learn the coding process yourself, you can unlock a copy of the full sample code on Buy Me a Coffee.

Unlock the Sample Code Here

This code has been tested on our Smart Switch device; however, it comes without support, without warranty, and you assume all liability by using it.

With that said, it is a good starting point if you’re new to IoT and need a little extra help in the right direction.

Setup Voice Control using Siri

After you set up the code to work with a webhook service, it’s time to use a voice assistant to set the state values at that service.

You can use Alexa, Google Assistant, or Siri to add voice activation to your project. for this project, I will show you how to set up Siri using the Shortcuts app.

  1. First, open up Shortcuts on your iPhone. Then add a URL block with the following URL: https://dweet.io:443/dweet/for/smartSwitch. Replace “smartSwitch” with your Dweet.io thing name.
  2. Next, add a Scripting block to Ask “Do you want the Switch on or off?” The Input Type is Text.
  3. Then, use a Network Block to Get contents of Name.
    • The method should be POST.
    • The Request Body is a JSON with the Key as “State” and the Text as Provided Input.
  4. Finally, add a Documents block to Speak “Setting Switch” Provided Input.

Name the Shortcut as “Set my SmartSwitch” and add an icon color and glyph as you like. Then hit Done. Now, you’re ready to test the voice control.

Make sure the Wemos is OFF during this test. Open up a browser window and navigate to https://dweet.io/follow/smartSwitch. Replace “smartSwitch” with the name of your Dweet thing.

Then, use your iPhone to give Siri the voice command: “Hey Siri, set my Smart Switch.” Siri will ask if you want the Switch On or Off. Test out the device in both positions by saying On or Off.

Check the Dweet.io page to see the State change “On” and “Off” respectively. If that works as expected, you’re ready to test the whole system in Part 3.

Part 3. Test and Install and Use the IoT Switch

Load the final code onto your Wemos D1 mini, power up the switch either using an AC adapter and a nearby wall outlet or using a shield and a battery pack. Then use Siri to command your switch.

If all goes well, the switch will turn on and off as desired. You may have to do some tweaking on the Servo positions and delays.

The cool thing about this design is that you don’t have to use the smart switch to control the device. Because the servo horn always moves to neutral, you can always move the switch manually, as desired.

MakerFocus 4pcs 3.7V Lithium Rechargable Battery...
[Charge current time]: Standard Charging: 0.2C (8 hours); Fast charging: 0.5C (2.5 hours).
$22.99
Onyehn 3pcs for Wemos D1 Mini Battery Shield Micro...
D1 mini Single Lithium Battery Charging Board; Lithium Battery voltage: 3.3-4.2V; Boost Power Supply: 5V(max: 1A)
$7.99
IZOKEE D1 Mini NodeMcu Lua 4M Bytes WLAN WiFi...
This D1 mini module is a mini WIFI board based on ESP-8266EX.
$15.99

Improvements and Recommendations

Lastly, I recommend adjusting the polling cycle. It’s not optimal to check the web service every 2 seconds.
A major improvement is to only adjust states when the new state is different than the current state.

If you get this feature working, we’d love to see it! Post your methodology in the comments below.

Once you have your Smart Switch working, you’ll be able to control any appliance or fixture that’s wired to a wall switch. I recommend making a bunch of these and adding them around the house.

And, as always, if you found value in this post, consider sending us a coffee. You can also support Learn Robotics by sharing this post on your favorite Social Media channel.

You May Also Like

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Free Learn Robotics Swag

Patch/Sticker with every LR Kit

Work with an Engineer

Live Chat with an Instructor

365 Day Course Access

1 year access to every course

100% Secure Checkout

PayPal / MasterCard / Visa

Become a Learn Robotics Insider

Sign up and receive product announcements and discounts!

 

Success! Check your email for a surprise!

Pin It on Pinterest