]> vault307.fbx.one Git - ir_remote.git/blob - primitives/aadc.py
infrared remote
[ir_remote.git] / primitives / aadc.py
1 # aadc.py AADC (asynchronous ADC) class
2
3 # Copyright (c) 2020 Peter Hinch
4 # Released under the MIT License (MIT) - see LICENSE file
5
6 import uasyncio as asyncio
7 import io
8
9 MP_STREAM_POLL_RD = const(1)
10 MP_STREAM_POLL = const(3)
11 MP_STREAM_ERROR = const(-1)
12
13 class AADC(io.IOBase):
14 def __init__(self, adc):
15 self._adc = adc
16 self._lower = 0
17 self._upper = 65535
18 self._pol = True
19 self._last = None
20 self._sreader = asyncio.StreamReader(self)
21
22 def __iter__(self):
23 b = yield from self._sreader.read(2)
24 return int.from_bytes(b, 'little')
25
26 def _adcread(self):
27 self._last = self._adc.read_u16()
28 return self._last
29
30 def read(self, n): # For use by StreamReader only
31 return int.to_bytes(self._last, 2, 'little')
32
33 def ioctl(self, req, arg):
34 ret = MP_STREAM_ERROR
35 if req == MP_STREAM_POLL:
36 ret = 0
37 if arg & MP_STREAM_POLL_RD:
38 if self._pol ^ (self._lower <= self._adcread() <= self._upper):
39 ret |= MP_STREAM_POLL_RD
40 return ret
41
42 # *** API ***
43
44 # If normal will pause until ADC value is in range
45 # Otherwise will pause until value is out of range
46 def sense(self, normal):
47 self._pol = normal
48
49 def read_u16(self, last=False):
50 if last:
51 return self._last
52 return self._adcread()
53
54 # Call syntax: set limits for trigger
55 # lower is None: leave limits unchanged.
56 # upper is None: treat lower as relative to current value.
57 # both have values: treat as absolute limits.
58 def __call__(self, lower=None, upper=None):
59 if lower is not None:
60 if upper is None: # Relative limit
61 r = self._adcread() if self._last is None else self._last
62 self._lower = r - lower
63 self._upper = r + lower
64 else: # Absolute limits
65 self._lower = lower
66 self._upper = upper
67 return self