Skip to content

improve read_pulses/blocking reliability #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 9, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 42 additions & 17 deletions adafruit_irremote.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
# pylint: disable=no-self-use

import array
import time

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_IRRemote.git"
Expand Down Expand Up @@ -192,30 +193,54 @@ def decode_bits(self, pulses, debug=False):
output[i // 8] |= 1
return output

def read_pulses(self, input_pulses, max_pulse=10000, blocking=True):
"""Read out a burst of pulses until a pulse is longer than ``max_pulse``.
def _read_pulses_non_blocking(self, input_pulses, max_pulse=10000, pulse_window=0.10):
"""Read out a burst of pulses without blocking until pulses stop for a specified
period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``.

:param ~pulseio.PulseIn input_pulses: Object to read pulses from
:param int max_pulse: Pulse duration to end a burst
:param bool blocking: If True, will block until pulses found.
If False, will return None if no pulses.
Defaults to True for backwards compatibility
:param ~pulseio.PulseIn input_pulses: Object to read pulses from
:param int max_pulse: Pulse duration to end a burst
:param float pulse_window: pulses are collected for this period of time
"""
if not input_pulses and not blocking:
return None
received = []
received = None
recent_count = 0
pruning = False
while True:
while not input_pulses:
pass
while input_pulses:
pulse = input_pulses.popleft()
recent_count += 1
if pulse > max_pulse:
if not received:
if received is None:
continue
else:
return received
received.append(pulse)
return received
pruning = True
if not pruning:
if received is None:
received = []
received.append(pulse)

if recent_count == 0:
return received
recent_count = 0
time.sleep(pulse_window)

def read_pulses(self, input_pulses, *, max_pulse=10000, blocking=True,
pulse_window=0.10, blocking_delay=0.10):
"""Read out a burst of pulses until pulses stop for a specified
period (pulse_window), pruning pulses after a pulse longer than ``max_pulse``.

:param ~pulseio.PulseIn input_pulses: Object to read pulses from
:param int max_pulse: Pulse duration to end a burst
:param bool blocking: If True, will block until pulses found.
If False, will return None if no pulses.
Defaults to True for backwards compatibility
:param float pulse_window: pulses are collected for this period of time
:param float blocking_delay: delay between pulse checks when blocking
"""
while True:
pulses = self._read_pulses_non_blocking(input_pulses, max_pulse, pulse_window)
if blocking and pulses is None:
time.sleep(blocking_delay)
continue
return pulses

class GenericTransmit:
"""Generic infrared transmit class that handles encoding."""
Expand Down