Skip to content

Instantly share code, notes, and snippets.

@csmatt
Last active November 25, 2017 07:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csmatt/7286fdb06f6dd3767a6664418ed44eeb to your computer and use it in GitHub Desktop.
Save csmatt/7286fdb06f6dd3767a6664418ed44eeb to your computer and use it in GitHub Desktop.
Code for controlling my Hunter fan with a Raspberry Pi
#!/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