Skip to content

Scripts and a story for controlling a Hunter remote controlled ceiling fan with Alexa

Notifications You must be signed in to change notification settings

vesuvisian/fan-controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hunter Ceiling Fan Control with Arduino and Alexa

I have a remote-controlled ceiling fan in my bedroom that a previous owner installed. I'm also lazy. I didn't like the idea of having to find the remote in the middle of the night if I were hot or cold in order to turn the fan on or off. I also have an Echo Dot and a smart plug and (homemade) smart LED strip in the bedroom that I can control with my dear virtual assistant. So, looking at the remote one day, I realized that it should be possible to hook my fan up to my Alexa. The remote listed the fan as a Hunter brand with a frequency of 434 MHz. After some quick Googling to check the feasibility of this project, I ordered a cheap little transmitter and receiver from China for a dollar and change. Once they arrived (much sooner than expected), I began.

I soon learned that controlling a Hunter ceiling fan was not a solved probelm in the world of Arduino, but this blog post and repo were very helpful in getting me along the way. I tried looking at the pulses of ones and zeros coming of the receiver using Serial.println(), but this seemed to return somewhat random results every time I pressed a button on the remote. I eventually learned that the println function takes way too long and was missing a ton of data when we're dealing with pulses only a few hundred microseconds long.

I eventually figured out two improvements. First, rather than trying to interpret the pattern of ones and zeros, it's better to record the time between state changes. This made the printout a bit more consistent, and I could start to see a pattern emerge. In particular, I noticed a large spike of over 240,000 μs that occurred with every button press. Second, rather than printing every result immediately, I implemented a sort of circular buffer that stored the results in the Arduino's memory, and the program would only print them out at certain breakpoints. At first, this was just my sending a signal to the device, but I later changed this to be based on that spike I had seen. The final form of this script can be seen in record.ino.

Copy/pasting the results from pressing each button a few times into a spreadsheet, I confirmed that the outputs were consistent, and I could see that most of the timings were around 400 or 800 μs, so I rounded everything to the nearest multiple of 400. As best as I can tell, there are three parts to the codes: a bunch of 400 μs cycles to indicate "I'm about to send a signal", followed by a pause, followed by the actual signal with high 800/low 400 corresponding to a 1 and high 400/low 800 to a 0 (or maybe vice versa), followed by another pause and then more cycles to indicate that a message was just sent. This is just my guess, and maybe someone from Hunter can chime in with the truth, but it doesn't matter too much, as I just need to replay the signal, not decode it.

I copied these cleaned values into transmit.ino (and used a power rail of my breadboard as an antenna), and it actually freaking worked! Pressing the Arduino reset button turned the light on. Pressing it again turned the light back off. Likewise for running it with the fan code.

Next was to make it Alexa-enabled. One approach would have been to plug the Arduino into my Raspberry Pi Zero (which is mostly used as a Pi-hole and diyHue server). That would have tied up the Arduino, but since the Pi has GPIO pins, it seemed better to just connect the transmitter directly. I never soldered headers to my Pi, so jumpers secured by a rubber band will do for now. The Python script is very similar to the Arduino script in function, but it doesn't work every time. I think the OS gets distracted with other tasks, so the timing isn't as precise as it needs to be. The current approach seems better than using time.sleep(), but perhaps there's another method of improving the script timings to improve reliability. Importing GPIO Zero also takes a noticible amount of time, so I might try switching to C or C++ instead.

Finally, I started up a Fauxmo service with this configuration to make things visible to Alexa. I have three "devices" that she discovered: ceiling light on/off (really just a toggle, since there's no way for her to know the current state), fan on/off, and fan speed on (faster)/off (slower). In the app, I added ceiling light to my bedroom group, and now I can switch everything with a single voice command. I realize they make actual smart ceiling fans nowadays, but still, overall, I'm very happy with this cheap little project. Maybe it can help someone else out now too.

About

Scripts and a story for controlling a Hunter remote controlled ceiling fan with Alexa

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published