Making a DIY Switchbot
Updated: Jan 23
I love the idea of home automation, but today, it's still impractical: there's little standardization (eg, a coffeemaker, blinds and a lamp each come with an app), it's still expensive and it's a time-suck (especially if you use open-source hubs like OpenHAB or Home Assistant, which are intended to solve the first two problems).
That's why I like the idea of the Switchbot. It's straightforward, simple to setup, and scoped to solve a very specific problem - pushing a button because you're lazy.
My son and I decided to build a DIY Switchbot as our "pandemic home project". He (being 7 yrs old) just wanted to build something "cool" (eg, turn off his bedroom lights by remote control). I wanted to tinker with the Attiny85, make something useful, while spending time with my kid. Here's how it looked in the end:
and here it is in action:
Read on for key details of the build:
Here were my main requirements. It had to:
Be simple in concept, design and execution - If you look at most DIY light switch bots, they are a mess of exposed boards and wires:
Be useful - Some DIY light switch bots only toggle the light one-way! We wanted to toggle a light ON and Off - and allow easy manual switching anytime
Use the Attiny85 - Everyone needs more 'Tiny85 in their lives
Have a small, "clean" footprint - No rat's nest of wires, especially in a kid's room. I am no Jony Ive nor did we plan to fab a PCB, so "clean" is relative
Use low-cost, common parts - No need to 3D print; wanted to use parts I had already or materials from around the home
Be safe, battery-powered and energy efficient - Don't want to constantly change batteries, maintain explodey LiPos, nor electrocute the kids if I tie to mains
Be portable - You can stick the real Switchbot anywhere as it comes with double-sided tape. I wanted ours portable too but without tape residue or drilling holes into a wall
1 x Attiny85-20PU
1 x SG90 micro servo
6 x AA alkaline batteries
1 x TSOP4838 IR Sensor
1 x IR remote (We used a spare toy remote)
1 x IRLZ44N mosfet
1 x plastic enclosure (I used an old Chick-fil-a toy box lying around)
2 x battery holders (4xAAAA, and a 2xAA)
1 x 100Ω resistor
1 x 10kΩ resistor
1 x 10 uF capacitor
I also used screws, nuts and bolts, wires, a small suction cup, orphan mounting pieces, and indiscriminate hot glue to complete the last mile of the project.
Note: You'll need a programmer for the Attiny. I used my Uno for that (plenty of tutorials out there like this one).
Getting IR, Servos and Attiny85 to work nicely together
I'd gotten an Attiny85 to control servos and respond to an IR Remote in the past, but never together. More details on what I learned here. TL;DR: I used the built-in Servo library of the attinycore and configured IRMP library to use Pin Change Interrupts to avoid Timer2 conflicts. I confirmed the IR remote used NEC protocol, and soon the Attiny85 was correctly moving the servo from On/Off commands sent from the remote.
Extending Battery Life
I was interested in the small footprint of Lipo, but have little experience with them (I also wanted to avoid an explosion of fire in my kid's room). With the SG90 requiring 4.8-6V and my expecting the 7 year old to mash buttons non-stop (this prediction came true), I went with 4 Alkaline AAs. Their heft was an OK tradeoff for simplicity, safety and capacity.
I powered the Tiny separately with 2 x AAs, so the servo could use a dedicated supply and to extend the time between any battery changes.
Before continuing, I confirmed the 4x and 2x battery holders could fit into my box.
We took some measurements with our cheap $20 digital multimeter:
SG90 servo: 2.47mA (idle), ~25-100mA (active load)
Attiny and IR Receiver circuit: ~4mA (Attiny@8MHz)
So back-of-envelope calculations gave us:
SG90 servo lifetime - 2500mAh/2.5mA / 24h = 41 days (just idling)
Attiny/IR receiver - 2500mAH/4mA/24h = 26 days
Not good enough.
I knew the Attiny could mostly sleep as it only needed to be awake to toggle the servo. I added sleep code for the Attiny (SLEEP_MODE_POWER_DOWN), after 3 seconds of inactivity (no commands), and waking on Pin Change Interrupt from the IR command.
For the servo, I used a low-side logic-level mosfet controlled by the Attiny to switch on the servo's circuit when receiving an IR command, then shut off as the Attiny went back to sleep. This blog helped me find a good 3v3 TTL through-hole mosfet (most are SMD).
SG90 servo: 95uA (Mosfet switched off)
Attiny and IR Receiver circuit: ~217uA (asleep; this wasn't as low as I expected; I suspect the IR Receiver was drawing most of this)
Which gave us (ballparking 1% of time the circuit is active, 99% of the time drawing negligible current)
SG90 servo lifetime - 2500mAh/(62mA*0.01)/ 24h = 168 days
Attiny/IR receiver - 2500mAH/(4mA*0.01)/24h = 7 years(!!)
Obviously this is a hypothetical and unrealistic with real-world usage (again, think 7 year old boy with a remote control) and battery discharge rates. But still - I felt reasonably confident I could go a couple months or more without a battery change, which was the aim.
Putting it all together
This was where I spent a surprising amount of my time. I soldered the project on perfboard so it could be semi-permanent:
After "playing Tetris" trying to fit the large battery packs and the circuit within the container, I finally found a working arrangement with the 4xAA holder on the bottom with circuit resting atop, and the 2xAA holder mounted on the opening cover. I also had to make room for the servo at the top of the container (to toggle the switch) and something to mount it atop of. I I I made some various holes and openings.
To keep it "clean", I decided to mount the whole thing on the existing light switch plate using its existing screw. I found a spare mounting bracket and used that as extra support of the container.
On toggling our rocker-style light switch, I wanted to follow the Switch bot model of being able to both push and pull. This was surprisingly hard to get right. I opted for a suction cup attachment and some wires linked to the servo horn for the pull motion, and played with multiple angles and servo speeds (and attachments) to get consistent switch toggling. After spending way too much time that I'll never get back on this part, I hotglued a bunch of glue at the tip of the servo horn, and was able to find consistent push and pull success.
We finally got it working and am proud to say that it is still in one piece on the wall in the kids' room, functions well, used daily and I haven't yet changed batteries.
What would I do differently or next time?
I would try a Li-ion battery pack to save space or at least a CR2032 for the Attiny
Try integrating an ESP8266 for wifi control (would be great to signal "flashing lights" in kids room at dinner time)
I wouldn't use Terminal blocks for my battery wires - very undependable
I would not underestimate the mechanical aspects of the design (eg, the servo horn pressing and pulling at just the right angle on the rocker)
Hope this writeup was useful for your projects!
Project code can be found here.