diff --git a/IRModule.py b/IRModule.py index e22f6e8..79ce2c7 100644 --- a/IRModule.py +++ b/IRModule.py @@ -23,157 +23,91 @@ """ import RPi.GPIO as GPIO -import time, threading +import time, threading +from datetime import datetime class IRRemote: def __init__(self, callback = None): self.decoding = False - self.pList = [] - self.timer = time.time() if callback == 'DECODE': self.callback = self.print_ir_code else: self.callback = callback - self.checkTime = 150 # time in milliseconds self.verbose = False - self.repeatCodeOn = True - self.lastIRCode = 0 - self.maxPulseListLength = 70 + #self.lastRecievedTime = None def pWidth(self, pin): """pWidth, function to record the width of the highs and lows of the IR remote signal and start the function to look for the end of the IR remote signal""" - - self.pList.append(time.time()-self.timer) - self.timer = time.time() - if self.decoding == False: self.decoding = True - check_loop = threading.Thread(name='self.pulse_checker',target=self.pulse_checker) + check_loop = threading.Thread(name='self.pulse_checker',target=self.getData) check_loop.start() return - def pulse_checker(self): - """pulse_checker, function to look for the end of the IR remote - signal and activate the signal decode function followed by - the callback function. - - End of signal is determined by 1 of 2 ways - 1 - if the length of the pulse list is larger than self.maxPulseListLength - - used for initial button press codes - 2 - if the length of time receiving the pulse is great than self.checkTime - - used for repeat codes""" - - timer = time.time() - - while True: - check = (time.time()-timer)*1000 - if check > self.checkTime: - print(check, len(self.pList)) - break - if len(self.pList) > self.maxPulseListLength: - print(check, len(self.pList)) - break - time.sleep(0.001) - - if len(self.pList) > self.maxPulseListLength: - decode = self.decode_pulse(self.pList) - self.lastIRCode = decode - - # if the length of self.pList is less than 10 - # assume repeat code found - elif len(self.pList) < 10: - if self.repeatCodeOn == True: - decode = self.lastIRCode - else: - decode = 0 - self.lastIRCode = decode - else: - decode = 0 - self.lastIRCode = decode - - self.pList = [] - self.decoding = False - - if self.callback != None: - self.callback(decode) - - return - - def decode_pulse(self,pList): - """decode_pulse, function to decode the high and low - timespans captured by the pWidth function into a binary - number""" - - bitList = [] - sIndex = -1 - - # convert the timespans in seconds to milli-seconds - # look for the start of the IR remote signal + def ConvertHex(self, BinVal): #Converts binary data to hexidecimal + tmpB2 = int(str(BinVal), 2) + return hex(tmpB2) + + def getData(self): #Pulls data from sensor + PinIn = 17 + num1s = 0 #Number of consecutive 1s + command = [] #Pulses and their timings + binary = 1 #Decoded binary command + previousValue = 0 #The previous pin state + value = GPIO.input(PinIn) #Current pin state - for p in range(0,len(pList)): - try: - pList[p]=float(pList[p])*1000 - if self.verbose == True: - print(pList[p]) - if pList[p]<11: - if sIndex == -1: - sIndex = p - except: - pass - - # if no acceptable start is found return -1 - - if sIndex == -1: - return -1 - - if sIndex+1 >= len(pList): - return -1 + while value: #Waits until pin is pulled low + value = GPIO.input(PinIn) - #print(sIndex, pList[sIndex], pList[sIndex+1]) - - if (pList[sIndex]<4 or pList[sIndex]>11): - return -1 + startTime = datetime.now() #Sets start time - if (pList[sIndex+1]<2 or pList[sIndex+1]>6): - return -1 + while True: + if value != previousValue: #Waits until change in state occurs + now = datetime.now() #Records the current time + pulseLength = now - startTime #Calculate time in between pulses + startTime = now #Resets the start time + command.append((previousValue, pulseLength.microseconds)) #Adds pulse time to array (previous val acts as an alternating 1 / 0 to show whether time is the on time or off time) + + #Interrupts code if an extended high period is detected (End Of Command) + if value: + num1s += 1 + else: + num1s = 0 - """ pulses are made up of 2 parts, a fixed length low (approx 0.5-0.6ms) - and a variable length high. The length of the high determines whether or - not a 0,1 or control pulse/bit is being sent. Highes of length approx 0.5-0.6ms - indicate a 0, and length of approx 1.6-1.7 ms indicate a 1""" - - - for i in range(sIndex+2,len(pList),2): - if i+1 < len(pList): - if pList[i+1]< 0.9: - bitList.append(0) - elif pList[i+1]< 2.5: - bitList.append(1) - elif (pList[i+1]> 2.5 and pList[i+1]< 45): - #print('end of data found') - break + if num1s > 10000: + break + + #Reads values again + previousValue = value + value = GPIO.input(PinIn) + + #Covers data to binary + for (typ, tme) in command: + if typ == 1: + if tme > 1000: #According to NEC protocol a gap of 1687.5 microseconds repesents a logical 1 so over 1000 should make a big enough distinction + binary = binary * 10 + 1 else: - break - - if self.verbose == True: - print(bitList) - - # convert the list of 1s and 0s into a - # binary number - - pulse = 0 - bitShift = 0 - - for b in bitList: - pulse = (pulse< 34: #Sometimes the binary has two rouge charactes on the end + binary = int(str(binary)[:34]) + #print("binary") + #print(binary) + command = self.ConvertHex(binary) + #print("hex") + #print(command) + if self.callback != None: + self.callback(command) + #self.getData() + time.sleep(0.01) + check_loop = threading.Thread(name='self.pulse_checker',target=self.getData) + check_loop.start() + return command def set_callback(self, callback = None): """set_callback, function to allow the user to set @@ -194,7 +128,8 @@ def remove_callback(self): def print_ir_code(self, code): """print_ir_code, function to display IR code received""" - print(hex(code)) + #print(hex(code)) + print(code) return @@ -212,10 +147,8 @@ def set_repeat(self, repeat = True): the IR repeat code functionality""" self.repeatCodeOn = repeat - return - if __name__ == "__main__": def remote_callback(code):