Skip to content

Commit b78e317

Browse files
committed
improve read_pulses/blocking reliability
1 parent ec11164 commit b78e317

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

adafruit_irremote.py

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
# pylint: disable=no-self-use
7474

7575
import array
76+
import time
7677

7778
__version__ = "0.0.0-auto.0"
7879
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_IRRemote.git"
@@ -192,30 +193,56 @@ def decode_bits(self, pulses, debug=False):
192193
output[i // 8] |= 1
193194
return output
194195

195-
def read_pulses(self, input_pulses, max_pulse=10000, blocking=True):
196-
"""Read out a burst of pulses until a pulse is longer than ``max_pulse``.
196+
def read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window=0.10):
197+
"""Read out a burst of pulses without blocking until pulses stop for a specified
198+
period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``.
197199
198-
:param ~pulseio.PulseIn input_pulses: Object to read pulses from
199-
:param int max_pulse: Pulse duration to end a burst
200-
:param bool blocking: If True, will block until pulses found.
201-
If False, will return None if no pulses.
202-
Defaults to True for backwards compatibility
200+
:param ~pulseio.PulseIn input_pulses: Object to read pulses from
201+
:param int max_pulse: Pulse duration to end a burst
202+
:param float pulse_window: pulses are collected for this period of time
203203
"""
204-
if not input_pulses and not blocking:
205-
return None
206-
received = []
204+
received = None
205+
recent_count = 0
206+
pruning = False
207207
while True:
208-
while not input_pulses:
209-
pass
210-
while input_pulses:
208+
try:
211209
pulse = input_pulses.popleft()
210+
recent_count += 1
212211
if pulse > max_pulse:
213-
if not received:
212+
if received is None:
214213
continue
215-
else:
216-
return received
217-
received.append(pulse)
218-
return received
214+
pruning = True
215+
if not pruning:
216+
if received is None:
217+
received = []
218+
received.append(pulse)
219+
except IndexError:
220+
if recent_count == 0:
221+
return received
222+
recent_count = 0
223+
time.sleep(pulse_window)
224+
225+
# pylint: disable-msg=too-many-arguments
226+
def read_pulses(self, input_pulses, max_pulse=10000, blocking=True,
227+
pulse_window=0.10, blocking_delay=0.10):
228+
"""Read out a burst of pulses until pulses stop for a specified
229+
period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``.
230+
231+
:param ~pulseio.PulseIn input_pulses: Object to read pulses from
232+
:param int max_pulse: Pulse duration to end a burst
233+
:param bool blocking: If True, will block until pulses found.
234+
If False, will return None if no pulses.
235+
Defaults to True for backwards compatibility
236+
:param float pulse_window: pulses are collected for this period of time
237+
:param float blocking_delay: delay between pulse checks when blocking
238+
"""
239+
while True:
240+
pulses = self.read_pulses_non_blocking(input_pulses, max_pulse, pulse_window)
241+
if blocking and pulses is None:
242+
time.sleep(blocking_delay)
243+
continue
244+
return pulses
245+
# pylint: enable-msg=too-many-arguments
219246

220247
class GenericTransmit:
221248
"""Generic infrared transmit class that handles encoding."""

0 commit comments

Comments
 (0)