diff --git a/remote_input.py b/remote_input.py new file mode 100644 index 0000000..d0bac84 --- /dev/null +++ b/remote_input.py @@ -0,0 +1,91 @@ +import RPi.GPIO as GPIO +from subprocess import call +from time import time + +IR_PIN_INPUT = 15 + +def setup(): + GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location + GPIO.setup(IR_PIN_INPUT, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + + +def binary_aquire(pin, duration): + # aquires data as quickly as possible + t0 = time() + results = [] + while (time() - t0) < duration: + results.append(GPIO.input(pin)) + return results + + +def on_ir_receive(pinNo, bouncetime=150): + # when edge detect is called (which requires less CPU than constant + # data acquisition), we acquire data as quickly as possible + data = binary_aquire(pinNo, bouncetime/1000.0) + if len(data) < bouncetime: + return + rate = len(data) / (bouncetime / 1000.0) + pulses = [] + i_break = 0 + # detect run lengths using the acquisition rate to turn the times in to microseconds + for i in range(1, len(data)): + if (data[i] != data[i-1]) or (i == len(data)-1): + pulses.append((data[i-1], int((i-i_break)/rate*1e6))) + i_break = i + # decode ( < 1 ms "1" pulse is a 1, > 1 ms "1" pulse is a 1, longer than 2 ms pulse is something else) + # does not decode channel, which may be a piece of the information after the long 1 pulse in the middle + outbin = "" + for val, us in pulses: + if val != 1: + continue + if outbin and us > 2000: + break + elif us < 1000: + outbin += "0" + elif 1000 < us < 2000: + outbin += "1" + try: + return int(outbin, 2) + except ValueError: + # probably an empty code + return None + +def run_command(mpc_command): + call(["mpc", mpc_command]) + +def destroy(): + GPIO.cleanup() + +codes = { + "0x5ea110ef": "play", + "0x5ea1906f": "stop", + "0x2f50c837": "toggle", + "0x5ea150af": "next", + "0x5ea1d02f": "prev", + } + +if __name__ == "__main__": + setup() + try: + print("Starting IR Listener") + while True: + print("Waiting for signal") + GPIO.wait_for_edge(IR_PIN_INPUT, GPIO.FALLING) + code = on_ir_receive(IR_PIN_INPUT) + if code and str(hex(code)) in codes: + hex_code = str(hex(code)) + print(f"{hex_code} -> {codes[hex_code]}") + run_command(codes[hex_code]) + else: + pass + print("Invalid code") + except KeyboardInterrupt: + print("interupt") + pass + except RuntimeError as e: + # this gets thrown when control C gets pressed + # because wait_for_edge doesn't properly pass this on + print(f"runtime: {e}") + pass + print("Quitting") + destroy() \ No newline at end of file