]> vault307.fbx.one Git - micorpython_ir.git/blob - ir_rx/__init__.py
525a859353b43488f062b275efcf96e156819c01
[micorpython_ir.git] / ir_rx / __init__.py
1 # ir_rx __init__.py Decoder for IR remote control using synchronous code
2 # IR_RX abstract base class for IR receivers.
3
4 # Author: Peter Hinch
5 # Copyright Peter Hinch 2020 Released under the MIT license
6
7 from machine import Timer, Pin
8 from array import array
9 from utime import ticks_us
10
11 # Save RAM
12 # from micropython import alloc_emergency_exception_buf
13 # alloc_emergency_exception_buf(100)
14
15
16 # On 1st edge start a block timer. While the timer is running, record the time
17 # of each edge. When the timer times out decode the data. Duration must exceed
18 # the worst case block transmission time, but be less than the interval between
19 # a block start and a repeat code start (~108ms depending on protocol)
20
21 class IR_RX():
22 # Result/error codes
23 # Repeat button code
24 REPEAT = -1
25 # Error codes
26 BADSTART = -2
27 BADBLOCK = -3
28 BADREP = -4
29 OVERRUN = -5
30 BADDATA = -6
31 BADADDR = -7
32
33 def __init__(self, pin, nedges, tblock, callback, *args): # Optional args for callback
34 self._pin = pin
35 self._nedges = nedges
36 self._tblock = tblock
37 self.callback = callback
38 self.args = args
39 self._errf = lambda _ : None
40 self.verbose = False
41
42 self._times = array('i', (0 for _ in range(nedges + 1))) # +1 for overrun
43 pin.irq(handler = self._cb_pin, trigger = (Pin.IRQ_FALLING | Pin.IRQ_RISING))
44 self.edge = 0
45 self.tim = Timer(-1) # Sofware timer
46 self.cb = self.decode
47
48 # Pin interrupt. Save time of each edge for later decode.
49 def _cb_pin(self, line):
50 t = ticks_us()
51 # On overrun ignore pulses until software timer times out
52 if self.edge <= self._nedges: # Allow 1 extra pulse to record overrun
53 if not self.edge: # First edge received
54 self.tim.init(period=self._tblock , mode=Timer.ONE_SHOT, callback=self.cb)
55 self._times[self.edge] = t
56 self.edge += 1
57
58 def do_callback(self, cmd, addr, ext, thresh=0):
59 self.edge = 0
60 if cmd >= thresh:
61 self.callback(cmd, addr, ext, *self.args)
62 else:
63 self._errf(cmd)
64
65 def error_function(self, func):
66 self._errf = func
67
68 def close(self):
69 self._pin.irq(handler = None)
70 self.tim.deinit()