The Ultimate Light Switch




Introduction: The Ultimate Light Switch

About: Hi, I'm a hobbyist in the Chicago area, I like to do some woodworking, and automation with Arduino / Raspberry Pi.

The goal of this instructable is to explain how I made a wifi-connected light switch (also called remotes further). The goal of these remotes is to turn on and off several wifi-connected relays. The relays are not explained in this instructable. They are explained in a separate instructable that I made in the past: ESP8266 Wifi Switch.

These remotes will contain up to 3 small buttons. Each button turns on/off one or more relays. An LED next to each button serves as feedback. A larger button is used for a special purpose: it turns off all of the relays. Not only the ones controlled by the remote, but all relays controlled by all remotes of the house. This is used to turn everything off when leaving to work, or going to bed.

The link between the devices is managed by Blynk. The remote microcontroller is a Huzzah Feather with ESP8266. The power to the remotes is coming from a USB wall plug (no batteries).

If you follow my instructables, you will notice that this device has a similar purpose as the one explained in a previous instructable: ESP32 Thing Wifi Remote, and you are correct. I made the following improvements from the previous model:

  • The ESP32 Thing was replaced by a Huzzah Feather with ESP8266 (I had connectivity issues with the ESP32 Thing).
  • The metallic buttons were replaced by plastic buttons (static electricity was sometimes transmitted to the board through the metallic buttons, requiring a reboot).
  • These remotes now only control a few lights, usually the lights in one room, instead of controlling all the lights of the house with each remote (so you don't accidentally turn on the lights in the other bedrooms for example).
  • I had a battery in the older model, to be able to remove the remote from the USB plug, and still use it for a few hours. It turns out I never used this functionality, so I removed the battery to make the remote slimmer.
  • I added the "turn everything off" button.
  • I added the feedback LEDs.

Difficulty level: Medium

Material needed:

    Tools needed:

    • Soldering iron Amazon
    • Dremel (if you don't have one, a utility knife would suffice) Lowes
    • Drill press (if you don't have one, a hand drill would suffice) Lowes

    Step 1: Design


    As microcontroller, I used the feather Huzzah with ESP8266, made by Adafruit, for the following reasons:

    • It has wifi capabilities
    • It is cheap ($18.95 for the assembled version)
    • It is relatively small (23mm x 51mm x 8mm / 0.9" x 2" x 0.28")
    • It has 9 GPIOs pins (I needed 7)

    The microcontroller will be powered by the 5V of a USB outlet.

    4 GPIOs will be used as inputs from buttons, and 3 will be used as output to light leds. One of the buttons (the one that turns off every light) has an LED included, so it did not make sense to me to have a feedback led for this button.


    The design for the buttons is very simple: for the 3 small buttons, I picked tactile switches, also called SPST switches. I picked the tall ones, so that they will stand out of the enclosure. For the bigger button, I also picked an SPST switch, but a shorter one, so that it will be recessed in the enclosure, the goal being that it won't be pushed by accident. It also has an led inside, and has an I/O symbol.

    As shown in the diagram above, the switches supply ground to the GPIO through a 3.3k pull-down resistor, and supply 3.3V to the GPIO when pressed.


    I used 5mm yellow LEDs. They are simply connected to a GPIO on one end, and to ground through a 3.3k resistor on the other end.


    For the enclosure, I needed a plastic box with internal dimensions of at least 51mm x 97mm x 11mm / 2.0" x 3.8" x 0.4" . The box I picked has internal dimensions of 52mm x 100mm x 19mm / 2.0" x 3.9" x 0.7" . This means that I will have to stack a few cardboard or paper behind the breadboard, to make sure that the system is pushed flush with the enclosure lid, and the buttons will stick out of the lid.

    All components are soldered on a solderable breadboard. This makes it more permanent and secured than a conventional breadboard, and does not require to design a custom-made PCB. I found that the half-sized permaboard from Adafruit worked perfectly.

    Step 2: Making the Board

    Soldering the board is the fun part! Simply follow the wiring diagram, and everything should work according to plan. Pay special attention to the following points:

    • Pay attention to the LED polarity (short lead-cathode-ground / long lead-anode-positive voltage).
    • The LEDs should be as low as possible to the breadboard. Otherwise, the top of the led will be too high and stick out of the enclosure too much.
    • Before soldering the Feather Huzzah, I removed the battery connector from it. We will not need it, and it is very tall, so it would not allow us to place the enclosure lid properly.
    • I placed a 90-degree male - female pin connector on the "batt" pin of the Feather Huzzah, and on the ground rail. These will then be connected to the 5V and ground of the USB.
    Use a third hand, or make one yourself with a piece of wood, 4 Loc-line hoses, and 4 alligator clips

    Step 3: Making the Enclosure

    USB plug:

    Use the dremel or utility knife to make cut an opening for the USB plug in one of the upper corner of the enclosure on the rear side. Place the USB plug through it.

    Make sure the USB plug is protruding 11.5 mm / 0.45" from the back of the enclosure, and glue the USB plug in the enclosure using polyurethane glue.

    Solder a wire from the +5V of the USB plug, and a wire from the ground of the USB plug. When you place your board in the enclosure, these wires will be connected to the "batt" and ground of the 90-degree male - female pin connector, respectively.

    Buttons and LEDs openings:

    Drill holes in the enclosure lid where the buttons and LEDs will protrude. A drill bit of diameter 4mm / 5/32" is perfect for the small button, and 8mm / 5/16" is perfect for the larger one. Use a countersink drill bit to make a tapered hole so it looks nice. For the LEDs, I drilled a much smaller diameter than the LED itself (1mm / 1/32"). Otherwise, I found that the LEDs I chose produce too much light. If the light switch is in a bedroom, it can be disturbing to have too much light coming from the switch.

    Place an empty solderable breadboard on the enclosure lid and use a thin-tipped pen to draw on the enclosure where the holes should be drilled.

    Step 4: Programming

    I used the Arduino IDE for the programming of my Feather Huzzah. If you have not done it yet, download and install Arduio IDE.

    To be able to use Blynk, I had to use the Blynk library for Arduino IDE. The Blynk library can be downloaded here. Follow these steps to install the library (quoted from the Blynk website):

    1. Download the latest release .zip file.
    2. Copy all these libraries to your_sketchbook_folder of Arduino IDE. To find the location of your_sketchbook_folder, go to top menu in Arduino IDE: File -> Preferences (if you are using Mac OS - go to Arduino → Preferences)
    3. Unzip it. You will notice that archive contains several folders and several libraries.

    The structure of your your_sketchbook_folder should now look like this, along with your other sketches (if you have them):



    Note that libraries should go to libraries and tools to tools. If you don't have tools folder you can create it by yourself.

    The code can be found in the following Github repository:

    It should be fairly well documented, but don't hesitate to post a comment if you have any question.

    In summary, this is how the code works:

    A timer runs the function checkInputs every 200 ms. This function checks if a button has been pressed or released.


    If the button is released, it does not do anything.

    If the button is pressed, it toggles the state of the switch (switchState), and calls function sendState.


    If one of the small buttons is pressed, function sendState will send the new state of the switch to the appropriate relays, through the built-in function bridge.virtualWrite.

    If the bigger button is pressed, function sendState will send an "off" state to all relays through the built-in function bridge.virtualWrite.

    The rest of the code is the setup, creating variables, connecting to a known wifi, etc...

    Step 5: Setup the Blynk App

    Blynk is a great app, that does the link between your phone, your devices, and the Blynk server. They have a great community, lots of examples, and the app interface is user-friendly, while still customizable. The app is free, but it comes with a limited number of widget that you can add. If you add all the widget I have, you will probably need to buy 5$ of credit. But a lot of the widgets proposed are optional, and you could do this project for free, especially if you want to control less than 15 relays.

    If you have never used Blynk before, follow these steps to set it up:

    1. Install the Blynk app on your smartphone from the Google Play store or the App store.
    2. In the Blynk app:
      Login or create an account
      Create a new project
      Add a device for each remote and relay (select ESP8266, with wifi connectivity)
      Build the dashboard as described below in this step
    3. Connect the feather Huzzah to your computer using a usb cable.
    4. Make sure that you downloaded and installed the Blynk library in the previous step.
    5. In the program, enter the authentication token that you received by email from Blynk.
    6. In the Tools -> Port, select the COM port your Arduino is connected to.

    I created 5 tabs on the dashboard:


    The Lights tab is used to turn on/off individual lights (or anything that is connected the relays). I used the button widget, with a switch as target, V0 being the output between 0 and 1, in switch mode. I did that for every switch.


    The Groups tab is used to turn on/off groups of lights (or anything that is connected to the relays). I simply created tags for each room, and then repeated the same step as for the Lights tab, with one button widget for every group.


    I added a couple timers, that can be used to turn the front porch lights on in the evening, or simulate a presence when you are on vacation, or turn your nightstand light on to wake you up, etc... I picked the following widgets:

    • The time input widget, in which I selected the relayI want to control, output V3, allowing Start/Stop input, and allowing timezone selection.
    • A button widget, in which I selected the same relay, with output V4 between 0 and 1, in mode "switch". This is to tell the relay if it should follow the schedule or not.
    • Another button widget, in which I selected the same relay, with output V0 between 0 and 1, in mode "switch". This is to manually turn the relay on or off.


    The Monitor tab contains a terminal widget. This is only used for debuging purposes. In "source", I select the device I want to debug. Input is V16. I also have a notification widget, to notify me when a hardware goes offline (optional), and a Real-time clock widget, for the devices to be able to now the current time (only necessary if you use timers).


    The LEDs tab contains a bunch of LEDs that serve as feedback. This is optional too. I picked the LED widget, selected a relay, with input V1. I did that for each relay.

    Step 6: Use and Potential Improvements

    I have now installed 6 remotes in my house, and used them for several months. I believe that they work well, and I would not have much to improve. The "turn off all lights" feature is a great improvement. The appearance is quite simple and sober, which I like. Having small holes for the LEDs feedback don't produce too much light, so they don't disturb me at night, yet they are still visible, even in daylight. The response time is very fast.

    Here are a few things that could be improved:

    • If a relay is turned on / off with another device than its linked remote (for example with the app), the remote does not know that the relay state has changed, so it's not going to update its feedback light. Also, when I want to turn off a light with a remote, after I turned it on with my app, I will have to push the button twice: the first time, the remote is turning on the light, even though it's already on, and the second time it turns it off.
      It's not a big deal, but I tried to implement this fix and could not find a Blynk function that periodically checks the state of other devices. Let me know in the comment if you have an idea how to do that.
    • I chose the smallest possible enclosure that I found, but it's still quite thick. They could be much slimmer, but I did not find such a plastic enclosure.

    This is my most complete and detailed instructable. If you liked it, please vote for me in the Epilog X contest! If you have suggestions, questions, or did this project, please let me know in the comments! I spent quite some time on these devices, and I'd love to see your take it.

    Thanks for reading!

    Epilog X Contest

    Participated in the
    Epilog X Contest

    Be the First to Share


      • For the Home Contest

        For the Home Contest
      • Big and Small Contest

        Big and Small Contest
      • Game Design: Student Design Challenge

        Game Design: Student Design Challenge



      4 years ago on Introduction

      That is indeed a great ultimatum which is remarkable just to look at. I believe I must totally be in greater awe if I ever get the chance to operate it.


      Tip 4 years ago

      You could improve the Relay state issue by using virtual buttons instead of normal buttons in Blynk and then use the hardware side coding to handle all the requests and give the right response in both LEDs and Blynk-button-state-indicators.