Last active
November 25, 2017 07:41
-
-
Save csmatt/7286fdb06f6dd3767a6664418ed44eeb to your computer and use it in GitHub Desktop.
Code for controlling my Hunter fan with a Raspberry Pi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Code for controlling a Hunter fan with a Raspberry Pi rather than the remote with FCC ID: IN2TX31 | |
# Use: python fan.py COMMAND where COMMAND is light, fan_off, fan1, fan2, fan3 | |
# Truth be told, I'm new at this radio stuff. The code below works, but the method might be a misunderstanding of the protocol/signal. I'd love to understand it better if anyone can help. | |
# Visit http://csmatt.com/notes/?p=189 for more information | |
# That said, here's my understanding: | |
# | |
# Sending a command consists of a 'part' of a command (a sequence of bits) that is made up of a preamble followed by the part's specific binary sequence | |
# The preamble is transmitted as 12 high pulses each separated by a low, both for a PULSE_LENGTH | |
# I believe the preamble sets up a clock rate. The DELAY_* constants below may be better defined as a multiple of that clock rate | |
# There is then a delay (DELAY_AFTER_PREAMBLE) | |
# The first part of the command is then sent | |
# (a zero is two high pulses of PULSE_LENGTH and a one is a single high pulse followed by a low pulse, both of PULSE_LENGTH. each bit is separated by low pulse.) | |
# (fan speed 1,2,3 have one part commands whereas fan off and light on/off consist of two parts) | |
# The first part of the command is then sent again | |
# If there are more parts, those are sent just like the first part (prefaced with the preamble and repeated) after a delay of DELAY_BETWEEN_DOUBLE_COMMAND | |
import RPi.GPIO as GPIO | |
import time | |
import sys | |
# RPi pin connected to the data pin of the 433MHz transmitter | |
TX_PIN = 18 | |
# Length in seconds of a clock pulse | |
PULSE_LENGTH = 0.0004*0.85 | |
# Delay in seconds after the preamble before sending the command | |
DELAY_AFTER_PREAMBLE = 0.005 | |
# Delay in seconds after the command has been sent | |
DELAY_AFTER_COMMAND = 0.025 | |
# Delay in seconds between the first and second repeats of a double command | |
DELAY_BETWEEN_DOUBLE_COMMAND = 0.285 | |
PREAMBLE = "101010101010101010101010" | |
# All commands begin with this prefix. It's prepended to the command before sending | |
COMMAND_PREFIX = "01000101111001100110101111010000111110010111" | |
# Map of actions to their bit sequences (commands) excluding the prefix | |
COMMANDS = { | |
"light": [ | |
"0111111110001000000001", | |
"1110110010000001001101" | |
], | |
"fan_off": [ | |
"1111111100000000000010", | |
"1110111010000001000100" | |
], | |
"fan1": ["1111111010000000000100"], | |
"fan2": ["1110111110000001000001"], | |
"fan3": ["1101111110000010000001"] | |
} | |
def send_value(value): | |
GPIO.output(TX_PIN, value) | |
time.sleep(PULSE_LENGTH) | |
def send_0(): | |
send_value(GPIO.HIGH) | |
send_value(GPIO.HIGH) | |
def send_1(): | |
send_value(GPIO.HIGH) | |
send_value(GPIO.LOW) | |
def send_separator(): | |
send_value(GPIO.LOW) | |
def send_command_part(part): | |
for bit in PREAMBLE: | |
if bit == "1": | |
GPIO.output(TX_PIN, GPIO.HIGH) | |
time.sleep(PULSE_LENGTH) | |
elif bit == "0": | |
GPIO.output(TX_PIN, GPIO.LOW) | |
time.sleep(PULSE_LENGTH) | |
GPIO.output(TX_PIN, GPIO.LOW) | |
time.sleep(DELAY_AFTER_PREAMBLE) | |
prefixed_part = COMMAND_PREFIX + part | |
for bit in prefixed_part: | |
if bit == "0": | |
send_0() | |
elif bit == "1": | |
send_1() | |
send_separator() | |
time.sleep(DELAY_AFTER_COMMAND) | |
if __name__ == "__main__": | |
# Pin Setup: | |
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme | |
GPIO.setup(TX_PIN, GPIO.OUT) | |
try: | |
choice = sys.argv[1] | |
for part in COMMANDS[choice]: | |
# send each command part twice | |
send_command_part(part) | |
send_command_part(part) | |
finally: | |
GPIO.cleanup() # cleanup all GPIO |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment