Last active
March 17, 2017 05:36
-
-
Save aplocher/e83fdc72e705c099936cc187cee74768 to your computer and use it in GitHub Desktop.
Python script to detect signal from MAX4466 Mic Amp and send an RF signal to power on/off a plug when it detects two clap sounds (aka "DIY The Clapper"). Implemented on Raspberry Pi Zero
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 | |
# | |
# usage: clapper.py [-h] [--on | --off] | |
# | |
# With no arguments, this will run continuously and listen for clap noises to | |
# trigger an RF power plug to turn on or off (aka The Clapper). Can | |
# alternatively be used to manually control a power plug with arguments | |
# | |
# optional arguments: | |
# -h, --help show this help message and exit | |
# --on Send an ON signal to the power plug and exit | |
# --off Send an OFF signal to the power plug and exit | |
import spidev | |
import os | |
import time | |
import argparse | |
# <config stuff> | |
# Determine what frequency you should send by using the RFSniffer utility | |
rf_power_off = "4216268 -l 183" | |
rf_power_on = "4216259 -l 183" | |
# Higher number means the sound needs to be louder to trigger a "clap" | |
minimum_sound_level = 640 | |
# Time in seconds between claps. Must detect 2 claps between min/max seconds apart to trigger power on/off | |
min_time_between_claps = 0.2 | |
max_time_between_claps = 2.0 | |
# Path to codesend bin | |
code_send_path = "/var/www/rfoutlet/codesend" | |
# ADC channel | |
channel = 0 | |
# </config stuff> | |
# SPI device - bus 0, device 0 | |
spi = spidev.SpiDev() | |
spi.open(0, 0) | |
def enum(**enums): | |
return type('Enum', (), enums) | |
def change_power_status(rf): | |
os.system("{} {} -p 0".format(code_send_path, rf)) | |
arg_parser = argparse.ArgumentParser(description='With no arguments, this will run continuously and listen for clap noises to trigger an RF power plug to turn on or off (aka The Clapper). Can alternatively be used to manually control a power plug with arguments') | |
arg_group = arg_parser.add_mutually_exclusive_group() | |
arg_group.add_argument('--on', help='Send an ON signal to the power plug and exit',action='store_true') | |
arg_group.add_argument('--off', help='Send an OFF signal to the power plug and exit',action='store_true') | |
args = arg_parser.parse_args() | |
if (args.on): | |
change_power_status(rf_power_on) | |
exit() | |
if (args.off): | |
change_power_status(rf_power_off) | |
exit() | |
PowerStates = enum(ON=1, OFF=0) | |
last_triggered_time = 0 | |
current_power_state = PowerStates.OFF | |
print("LISTENING") | |
while True: | |
if ( (channel > 7) or (channel < 0) ): | |
raise ValueError('Invalid channel {}'.format(channel)) | |
spi_result = spi.xfer( [1, (8 + channel) << 4, 0] ) | |
adc_out = ( (spi_result[1] & 3) << 8 ) + spi_result[2] | |
if (adc_out > minimum_sound_level): | |
# Detected sound was loud enough to trigger a "clap" | |
print(adc_out) | |
triggered_time = time.time() | |
last_triggered = triggered_time - last_triggered_time | |
if (last_triggered > max_time_between_claps): | |
# Second clap occured too long after the first clap - count as a new FIRST clap | |
clap_count = 1 | |
elif(last_triggered > min_time_between_claps and last_triggered < max_time_between_claps): | |
if (clap_count == 0): | |
# First clap | |
clap_count = 1 | |
elif (clap_count > 0): | |
# Second clap (within allotted time range) | |
if (current_power_state == PowerStates.ON): | |
current_power_state = PowerStates.OFF | |
print("SENDING ON") | |
change_power_status(rf_power_on) | |
else: | |
current_power_state = PowerStates.ON | |
print("SENDING OFF") | |
change_power_status(rf_power_off) | |
clap_count = 0 | |
last_triggered_time = triggered_time |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment