|
47 | 47 |
|
48 | 48 | import time
|
49 | 49 | import digitalio
|
50 |
| -import microcontroller |
| 50 | + |
| 51 | +_DEBOUNCED_STATE = 0x01 |
| 52 | +_UNSTABLE_STATE = 0x02 |
| 53 | +_CHANGED_STATE = 0x04 |
51 | 54 |
|
52 | 55 | class Debouncer(object):
|
53 | 56 | """Debounce an input pin or an arbitrary predicate"""
|
54 | 57 |
|
55 |
| - DEBOUNCED_STATE = 0x01 |
56 |
| - UNSTABLE_STATE = 0x02 |
57 |
| - CHANGED_STATE = 0x04 |
58 |
| - |
59 |
| - |
60 |
| - def __init__(self, pin_or_predicate, mode=None, interval=0.010): |
| 58 | + def __init__(self, io_or_predicate, interval=0.010): |
61 | 59 | """Make am instance.
|
62 |
| - :param int/function pin_or_predicate: the pin (from board) to debounce |
63 |
| - :param int mode: digitalio.Pull.UP or .DOWN (default is no pull up/down) |
| 60 | + :param DigitalInOut/function io_or_predicate: the pin (from board) to debounce |
64 | 61 | :param int interval: bounce threshold in seconds (default is 0.010, i.e. 10 milliseconds)
|
65 | 62 | """
|
66 | 63 | self.state = 0x00
|
67 |
| - if isinstance(pin_or_predicate, microcontroller.Pin): |
68 |
| - pin = digitalio.DigitalInOut(pin_or_predicate) |
69 |
| - pin.direction = digitalio.Direction.INPUT |
70 |
| - if mode is not None: |
71 |
| - pin.pull = mode |
72 |
| - self.function = lambda: pin.value |
| 64 | + if isinstance(io_or_predicate, digitalio.DigitalInOut): |
| 65 | + self.function = lambda: io_or_predicate.value |
73 | 66 | else:
|
74 |
| - self.function = pin_or_predicate |
| 67 | + self.function = io_or_predicate |
75 | 68 | if self.function():
|
76 |
| - self.__set_state(Debouncer.DEBOUNCED_STATE | Debouncer.UNSTABLE_STATE) |
| 69 | + self._set_state(_DEBOUNCED_STATE | _UNSTABLE_STATE) |
77 | 70 | self.previous_time = 0
|
78 | 71 | if interval is None:
|
79 | 72 | self.interval = 0.010
|
80 | 73 | else:
|
81 | 74 | self.interval = interval
|
82 | 75 |
|
83 | 76 |
|
84 |
| - def __set_state(self, bits): |
| 77 | + def _set_state(self, bits): |
85 | 78 | self.state |= bits
|
86 | 79 |
|
87 | 80 |
|
88 |
| - def __unset_state(self, bits): |
| 81 | + def _unset_state(self, bits): |
89 | 82 | self.state &= ~bits
|
90 | 83 |
|
91 | 84 |
|
92 |
| - def __toggle_state(self, bits): |
| 85 | + def _toggle_state(self, bits): |
93 | 86 | self.state ^= bits
|
94 | 87 |
|
95 | 88 |
|
96 |
| - def __get_state(self, bits): |
| 89 | + def _get_state(self, bits): |
97 | 90 | return (self.state & bits) != 0
|
98 | 91 |
|
99 | 92 |
|
100 | 93 | def update(self):
|
101 | 94 | """Update the debouncer state. MUST be called frequently"""
|
102 | 95 | now = time.monotonic()
|
103 |
| - self.__unset_state(Debouncer.CHANGED_STATE) |
| 96 | + self._unset_state(_CHANGED_STATE) |
104 | 97 | current_state = self.function()
|
105 |
| - if current_state != self.__get_state(Debouncer.UNSTABLE_STATE): |
| 98 | + if current_state != self._get_state(_UNSTABLE_STATE): |
106 | 99 | self.previous_time = now
|
107 |
| - self.__toggle_state(Debouncer.UNSTABLE_STATE) |
| 100 | + self._toggle_state(_UNSTABLE_STATE) |
108 | 101 | else:
|
109 | 102 | if now - self.previous_time >= self.interval:
|
110 |
| - if current_state != self.__get_state(Debouncer.DEBOUNCED_STATE): |
| 103 | + if current_state != self._get_state(_DEBOUNCED_STATE): |
111 | 104 | self.previous_time = now
|
112 |
| - self.__toggle_state(Debouncer.DEBOUNCED_STATE) |
113 |
| - self.__set_state(Debouncer.CHANGED_STATE) |
| 105 | + self._toggle_state(_DEBOUNCED_STATE) |
| 106 | + self._set_state(_CHANGED_STATE) |
114 | 107 |
|
115 | 108 |
|
116 | 109 | @property
|
117 | 110 | def value(self):
|
118 | 111 | """Return the current debounced value."""
|
119 |
| - return self.__get_state(Debouncer.DEBOUNCED_STATE) |
| 112 | + return self._get_state(_DEBOUNCED_STATE) |
120 | 113 |
|
121 | 114 |
|
122 | 115 | @property
|
123 | 116 | def rose(self):
|
124 | 117 | """Return whether the debounced value went from low to high at the most recent update."""
|
125 |
| - return self.__get_state(self.DEBOUNCED_STATE) and self.__get_state(self.CHANGED_STATE) |
| 118 | + return self._get_state(_DEBOUNCED_STATE) and self._get_state(_CHANGED_STATE) |
126 | 119 |
|
127 | 120 |
|
128 | 121 | @property
|
129 | 122 | def fell(self):
|
130 | 123 | """Return whether the debounced value went from high to low at the most recent update."""
|
131 |
| - return (not self.__get_state(self.DEBOUNCED_STATE)) and self.__get_state(self.CHANGED_STATE) |
| 124 | + return (not self._get_state(_DEBOUNCED_STATE)) and self._get_state(_CHANGED_STATE) |
0 commit comments