Tuesday, June 26, 2018

[v2.0] Ok Google, Open my curtains!

This post is a follow-up to my previous post http://vignesh.foamsnet.com/2018/06/ok-google-open-my-curtains.html.

Note: I've created a github repository which contains the code and some more details. I intend to keep that up to date with newer ideas, etc. https://github.com/vickyg3/curtain-automation

When i posted the previous set-up on reddit, one of them suggested a better way to do this that will overcome the cons of the previous method (noise and lack of manual control).

In a nutshell, these are the replacements i made:
  • Use a stepper motor instead of a servo.
  • Use a timing belt pulley and timing belts instead of a pulley and rope.

Here are the updated list of parts (with links to the cheapest ones i could find online to keep the cost minimum - although i didn't necessarily buy it from these links):

* Mounting bracket for the pulley on the non-motor end - I used a servo mounting bracket with a long screw. I am sure there are better alternatives for this one - $12.99
* Super glue - $4
* Vibration dampener for stepper motor (optional but highly recommended to keep the noise down) - $2.98
* 12V DC adapter - $8.99

Total Cost - $67.69 (some of it can probably be gotten for a cheaper price on ebay/gearbest/aliexpress).

Step 1 - Screw in the mounting bracket

This is quite straightforward. I drilled in a couple of drywall anchors and screwed in the mounting bracket to the wall.

Step 2 - Install the motor and the vibration dampener

Place the vibration dampener on the motor. Make sure that the non-threaded holes on the dampener are touching the motor and use two M3 screws to attach the motor and the dampener. Attach the pulley wheel to the motor's shaft using the screws on the side of the pulley.

Now the motor can be mounted on to the mounting bracket using 2 M3 screws which connect to the dampener's threaded holes.
Motor attached to the mounting bracket (shown without the vibration dampener).

Step 3 - Install the pulley mounting bracket on the other end

I drilled a drywall anchor on the other end and screwed the pulley mounting bracket in. I then used a long screw with a couple of plastic fillers to hold the other pulley roughly in the center.

Step 4 - Loop the timing belt around the pulleys

I had bought an open ended timing belt. I looped it around either pulleys and tightened them as much as i could by hand and cut off the rest of the belt leaving about an inch of overlap. I then used super glue on the extra inch of belt to stick to them together with as much tension as possible. You could also use a clamp like this with a screw to close the loop on the belt.

At this point, you should be able to move the belt manually by hand by pulling it gently in either direction. If so, there is enough tension on the belt to move the curtains.

Step 5 - Attach the curtains to the timing belt

Just as before, i placed the curtains in the completely closed state and attached each curtain to either side of the timing belt using a safety pin.

Here's a sketch from before about how the pulleys and the curtains move:

Step 6 - Program the microcontroller

I used the same NodeMCU ESP8266 controller as before. Here's the gist that contains the Arduino sketch: https://gist.github.com/vickyg3/623ca535b565ed43c8b617a6f7c7c06f (it is a crude version and has a lot of room for improvement, but i left it for another day).

Step 7 - Microcontroller and Motor Driver setup

Here's the wiring:
* DIR+ to D2
* PUL+ to D5
* ENA+ to D8
* DIR-, PUL- and ENA- to GND (can either be bundled together or connected separately to individual GND pins on the NodeMCU)
* A+, A-, B+ and B- need to be connected to the motor (refer to the motor's spec for the wiring colors for your motor).
* The switches on the driver need to be set to ON, ON, OFF, ON, ON, OFF (S3 and S6 should be off).

Connect the DC power supply to the driver. I cut the ends of an old DC adapter and identified the positive and negative wires using a multimeter.

I then glued the driver and the NodeMCU board to the wall behind the curtain using small command strips. Any double sided tape should work as they aren't that heavy.

Step 8 - Home Assistant Configuration

That is pretty much it. For more details on how you can control it from Google Home/Alexa, please see my previous post.

The noise level of the old servo based system was around 60 decibels (as measured by an app on my phone). The new system with vibration dampeners works at 30-35 decibels and is barely audible. Most of the noise is from the curtains actually moving on the rod.

Here's how it works (The video is noisy because the roomba was running when i recorded the clip):

Here's a video without much of external noise:

Saturday, June 16, 2018

Ok Google, Open my curtains!

Finally I've found a worthy enough reason to write a blog post.

I've been wanting to make the curtains in my home "smart" for a while now. I have what is called "grommet curtains"  and there are apparently no off the shelf solutions to automate this. There is this kickstarter project called Slide which retrofits to any curtain type, but that is still in its early stages and a bit pricey (~$150).

I ran into a tutorial which spoke about automating grommet curtains. But they used a 3d-printer to print custom designed components which wasn't an option for me (I don't have a 3d printer and i don't have any knowledge of how to design components for a 3d printer).

I borrowed the basic idea from that video. Two pulleys at either end with a rope running around them. One of the pulleys is attached to a servo which is controlled by a microcontroller. Here's an awful sketch of the idea:

Here are some of the challenges faced/things i did:
  • There is no cheap off the shelf servo that has a pulley attached to it. So i had to tweak around to figure out a way to mount a pulley to the servo.
  • The load on the servo to pull the rope along with the curtains is pretty high. So the servo has to be mounted securely to the wall. I first tried a heavy duty double sided tape, but that wasn't enough to withstand the tension of the rope. I then tried out various things and found a mount that could be screwed into the wall.
  • The wall mount for the servo held it too close to the wall and there was no room for the pulley (whose diameter is larger than the breadth of the servo) to fit in and rotate smoothly. So i used a couple of washers behind each mounting screw to give enough room for the pulley.
  • To tie the other pulley (which has no motor), i simply used a rope to tie the pulley on to the curtain rod's mounting bracket.
  • The servo had to have metal gears in order to have enough torque to pull the curtains. But such servos need a minimum of 4.8 volts of power. I found a NodeMCU board which had a 5V pin to supply enough power to the servo.

Here are the list of parts with links to where i bought them:

* NodeMCU (ESP8266) microcontroller (model with 5V pin) - Amazon - $5.98
* Jumper wire (to connect to the 5V pin) - Amazon - $5.24
* MG995 Servo (360 degree, metal gear, digital model) - Amazon - $10.99
* Servo wall mount - Amazon - $12.99
* Washers - I just used a couple of old washers lying around. Equivalent link: Home Depot - $2
* Pulley (for attaching with servo) - Servocity - $3.49
* Pulley (for the other end) - Home Depot -  $2.47
* Rope - Home Depot - $3.98
* Safety pins - Amazon - $3.15

Total Cost - $50.33 (some of it can probably be gotten for a cheaper price on ebay/gearbest/aliexpress).

Ok, with all that out of the way, let me explain how exactly i built and programmed this.

Step 1 - Attach pulley to the servo

Attaching the winch pulley to the servo is quite straight-forward. I screwed in the 4 pieces of the pulley with 2 bolts (on diagonally opposite ends) and small hex nuts. I then attached one of the servo horns to the other two holes of the pulley with two small screws (that came with the servo).

Now, the servo horn can merely be screwed into the servo until it's fairly tight.

Step 2 - Install the mounting bracket

After marking two spots with the mounting bracket's holes, i drilled in two drywall anchors on those spots. Then use two screws to screw the mounting bracket into the wall placing two washers in between the mounting bracket and the wall. This makes sure there is enough room to mount the servo along with the pulley.
This is the bracket i used to mount the servo to the wall
Step 3 - Attach servo to the mounting bracket

This is very straight-forward. The only catch is i used two nuts instead of 4 to attach the servo on to the mounting bracket.
Servo mount with washer behind. Pulley attached to the servo.
Step 4 - Mount the pulley on the other end

I used a small rope to tie the pulley on to the curtain rod's mounting bracket on the other end. A nut and bolt can also be used but since the rope worked for me i didn't look further.

Step 5 - Tie the rope on to the pulleys

Loop the rope around the pulley without the servo once. In the servo end, loop the rope around the pulley at least twice and then tie a really stiff knot. Make sure that the rope is really tight. Cut off any extra rope since it could cause friction when the rope is moving.
Rope tied to the pulleys and attached to the curtains.
Step 6 - Attach the curtains to the rope

I used a couple of safety pins to attach the curtains to the rope. I set the curtains in fully closed positions and then attached each half to one of the ropes. When the pulley spins, both the ropes will move in opposite directions thereby opening each curtain outward. The same process is reversed to close it.
Curtains attached to the rope with safety pins.
Step 7 - Program the microcontroller

This is my first foray into programming a microcontroller and surprisingly enough it was really simple. The NodeMCU ESP8266 board is a $5 wifi enabled board. Wifi means that you can send commands to it through simple HTTP requests.

Here's the arduino sketch i used to make a simple HTTP server that supports 3 commands: left, right and off (which spins the servo left, right and turns off respectively): https://gist.github.com/vickyg3/94b80435fa10a58691f563f643aaf807

Once this is flashed into the board, controlling the servo is simply a matter of "curl http://<ip>/left".

Step 8 - Mount the microcontroller

I mounted the microcontroller near the servo (using a small double side tape on the wifi chip) and just attached the servo wires to the appropriate pins (i used a jumper wire to connect the power wire to the 5 volt pin). I then ran a long micro-usb cable that i had lying around to power the microcontroller.

Step 9 - Home Assistant configuration

I added this to home assistant as a command line cover that used curl. Here's a sample configuration:

Where curtains.sh contains the following:

I determined the time to sleep between rotating the pulley and turning it off by trial and error. It usually took more time to close than to open because the set up struggled a bit to pull the curtains in that direction. It now shows up in home assistant, like so:

That's it. You can now include this in your automations, etc. I have set up automations like close the curtains after sunset, when we are away and so on.

If you have your home assistant tied to google assistant, you can control the curtain by saying "Ok Google, Turn the <curtain name> on/off". If you want custom commands, you can also try ifttt with google assistant to have commands like "Ok Google, open my curtains!".

Here's the Eureka moment

Some cons of this system:
  • The servo is a bit noisy. This is probably ok given that curtain control is not too frequent. It is probably bearable for 10 seconds or so once in a while.
  • Hooking up the curtains this way makes it impossible to control the curtains manually (since the curtains are tied to the rope). I've worked around this by sticking a button next to the curtain by the wall for those scenarios where we don't want to use voice control. Pressing the button will open/close the curtain.
    Button to control the curtains in lieu of voice/phone control.

Comments and suggestions about improving this in any way are welcome!