mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Merge pull request #312 from lurch/rgbled_pulse
Add RGBLED.pulse method
This commit is contained in:
@@ -23,13 +23,13 @@ PWMLED
|
|||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: PWMLED(pin, active_high=True, initial_value=0, frequency=100)
|
.. autoclass:: PWMLED(pin, active_high=True, initial_value=0, frequency=100)
|
||||||
:members: on, off, toggle, blink, pin, is_lit, value
|
:members: on, off, toggle, blink, pulse, pin, is_lit, value
|
||||||
|
|
||||||
RGBLED
|
RGBLED
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: RGBLED(red, green, blue, active_high=True, initial_value=(0, 0, 0))
|
.. autoclass:: RGBLED(red, green, blue, active_high=True, initial_value=(0, 0, 0))
|
||||||
:members: on, off, toggle, blink, red, green, blue, is_lit, color
|
:members: on, off, toggle, blink, pulse, red, green, blue, is_lit, color
|
||||||
|
|
||||||
Buzzer
|
Buzzer
|
||||||
======
|
======
|
||||||
|
|||||||
@@ -435,12 +435,12 @@ class PWMOutputDevice(OutputDevice):
|
|||||||
Number of seconds to spend fading out. Defaults to 1.
|
Number of seconds to spend fading out. Defaults to 1.
|
||||||
|
|
||||||
:param int n:
|
:param int n:
|
||||||
Number of times to blink; ``None`` (the default) means forever.
|
Number of times to pulse; ``None`` (the default) means forever.
|
||||||
|
|
||||||
:param bool background:
|
:param bool background:
|
||||||
If ``True`` (the default), start a background thread to continue
|
If ``True`` (the default), start a background thread to continue
|
||||||
blinking and return immediately. If ``False``, only return when the
|
pulsing and return immediately. If ``False``, only return when the
|
||||||
blink is finished (warning: the default value of *n* will result in
|
pulse is finished (warning: the default value of *n* will result in
|
||||||
this method never returning).
|
this method never returning).
|
||||||
"""
|
"""
|
||||||
on_time = off_time = 0
|
on_time = off_time = 0
|
||||||
@@ -670,13 +670,49 @@ class RGBLED(SourceMixin, Device):
|
|||||||
self._stop_blink()
|
self._stop_blink()
|
||||||
self._blink_thread = GPIOThread(
|
self._blink_thread = GPIOThread(
|
||||||
target=self._blink_device,
|
target=self._blink_device,
|
||||||
args=(on_time, off_time, fade_in_time, fade_out_time, on_color, off_color, n)
|
args=(
|
||||||
|
on_time, off_time, fade_in_time, fade_out_time,
|
||||||
|
on_color, off_color, n
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self._blink_thread.start()
|
self._blink_thread.start()
|
||||||
if not background:
|
if not background:
|
||||||
self._blink_thread.join()
|
self._blink_thread.join()
|
||||||
self._blink_thread = None
|
self._blink_thread = None
|
||||||
|
|
||||||
|
def pulse(
|
||||||
|
self, fade_in_time=1, fade_out_time=1,
|
||||||
|
on_color=(1, 1, 1), off_color=(0, 0, 0), n=None, background=True):
|
||||||
|
"""
|
||||||
|
Make the device fade in and out repeatedly.
|
||||||
|
|
||||||
|
:param float fade_in_time:
|
||||||
|
Number of seconds to spend fading in. Defaults to 1.
|
||||||
|
|
||||||
|
:param float fade_out_time:
|
||||||
|
Number of seconds to spend fading out. Defaults to 1.
|
||||||
|
|
||||||
|
:param tuple on_color:
|
||||||
|
The color to use when the LED is "on". Defaults to white.
|
||||||
|
|
||||||
|
:param tuple off_color:
|
||||||
|
The color to use when the LED is "off". Defaults to black.
|
||||||
|
|
||||||
|
:param int n:
|
||||||
|
Number of times to pulse; ``None`` (the default) means forever.
|
||||||
|
|
||||||
|
:param bool background:
|
||||||
|
If ``True`` (the default), start a background thread to continue
|
||||||
|
pulsing and return immediately. If ``False``, only return when the
|
||||||
|
pulse is finished (warning: the default value of *n* will result in
|
||||||
|
this method never returning).
|
||||||
|
"""
|
||||||
|
on_time = off_time = 0
|
||||||
|
self.blink(
|
||||||
|
on_time, off_time, fade_in_time, fade_out_time,
|
||||||
|
on_color, off_color, n, background
|
||||||
|
)
|
||||||
|
|
||||||
def _stop_blink(self, led=None):
|
def _stop_blink(self, led=None):
|
||||||
# If this is called with a single led, we stop all blinking anyway
|
# If this is called with a single led, we stop all blinking anyway
|
||||||
if self._blink_thread:
|
if self._blink_thread:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ str = type('')
|
|||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from time import sleep
|
from time import sleep, time
|
||||||
try:
|
try:
|
||||||
from math import isclose
|
from math import isclose
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -95,8 +95,11 @@ def test_output_digital_toggle():
|
|||||||
def test_output_blink_background():
|
def test_output_blink_background():
|
||||||
pin = MockPin(2)
|
pin = MockPin(2)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
device._blink_thread.join() # naughty, but ensures no arbitrary waits in the test
|
device._blink_thread.join() # naughty, but ensures no arbitrary waits in the test
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, False),
|
(0.0, False),
|
||||||
(0.0, True),
|
(0.0, True),
|
||||||
@@ -110,7 +113,9 @@ def test_output_blink_background():
|
|||||||
def test_output_blink_foreground():
|
def test_output_blink_foreground():
|
||||||
pin = MockPin(2)
|
pin = MockPin(2)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, False),
|
(0.0, False),
|
||||||
(0.0, True),
|
(0.0, True),
|
||||||
@@ -212,8 +217,11 @@ def test_output_pwm_write_silly():
|
|||||||
def test_output_pwm_blink_background():
|
def test_output_pwm_blink_background():
|
||||||
pin = MockPWMPin(2)
|
pin = MockPWMPin(2)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
device._blink_thread.join()
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.0, 1),
|
(0.0, 1),
|
||||||
@@ -227,7 +235,9 @@ def test_output_pwm_blink_background():
|
|||||||
def test_output_pwm_blink_foreground():
|
def test_output_pwm_blink_foreground():
|
||||||
pin = MockPWMPin(2)
|
pin = MockPWMPin(2)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.0, 1),
|
(0.0, 1),
|
||||||
@@ -241,8 +251,11 @@ def test_output_pwm_blink_foreground():
|
|||||||
def test_output_pwm_fade_background():
|
def test_output_pwm_fade_background():
|
||||||
pin = MockPWMPin(2)
|
pin = MockPWMPin(2)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
device._blink_thread.join()
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.04, 0.2),
|
(0.04, 0.2),
|
||||||
@@ -272,7 +285,75 @@ def test_output_pwm_fade_background():
|
|||||||
def test_output_pwm_fade_foreground():
|
def test_output_pwm_fade_foreground():
|
||||||
pin = MockPWMPin(2)
|
pin = MockPWMPin(2)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
|
pin.assert_states_and_times([
|
||||||
|
(0.0, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
])
|
||||||
|
|
||||||
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
|
reason='timing is too random on pypy')
|
||||||
|
def test_output_pwm_pulse_background():
|
||||||
|
pin = MockPWMPin(2)
|
||||||
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
|
device.pulse(0.2, 0.2, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
|
pin.assert_states_and_times([
|
||||||
|
(0.0, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
])
|
||||||
|
|
||||||
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
|
reason='timing is too random on pypy')
|
||||||
|
def test_output_pwm_pulse_foreground():
|
||||||
|
pin = MockPWMPin(2)
|
||||||
|
with PWMOutputDevice(pin) as device:
|
||||||
|
start = time()
|
||||||
|
device.pulse(0.2, 0.2, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
pin.assert_states_and_times([
|
pin.assert_states_and_times([
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.04, 0.2),
|
(0.04, 0.2),
|
||||||
@@ -409,8 +490,11 @@ def test_rgbled_toggle():
|
|||||||
def test_rgbled_blink_background():
|
def test_rgbled_blink_background():
|
||||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
device._blink_thread.join()
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
expected = [
|
expected = [
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.0, 1),
|
(0.0, 1),
|
||||||
@@ -427,7 +511,9 @@ def test_rgbled_blink_background():
|
|||||||
def test_rgbled_blink_foreground():
|
def test_rgbled_blink_foreground():
|
||||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
expected = [
|
expected = [
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.0, 1),
|
(0.0, 1),
|
||||||
@@ -444,8 +530,118 @@ def test_rgbled_blink_foreground():
|
|||||||
def test_rgbled_fade_background():
|
def test_rgbled_fade_background():
|
||||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
device._blink_thread.join()
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
|
expected = [
|
||||||
|
(0.0, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
]
|
||||||
|
r.assert_states_and_times(expected)
|
||||||
|
g.assert_states_and_times(expected)
|
||||||
|
b.assert_states_and_times(expected)
|
||||||
|
|
||||||
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
|
reason='timing is too random on pypy')
|
||||||
|
def test_rgbled_fade_foreground():
|
||||||
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
|
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
|
expected = [
|
||||||
|
(0.0, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
]
|
||||||
|
r.assert_states_and_times(expected)
|
||||||
|
g.assert_states_and_times(expected)
|
||||||
|
b.assert_states_and_times(expected)
|
||||||
|
|
||||||
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
|
reason='timing is too random on pypy')
|
||||||
|
def test_rgbled_pulse_background():
|
||||||
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
|
device.pulse(0.2, 0.2, n=2)
|
||||||
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
|
device._blink_thread.join()
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
|
expected = [
|
||||||
|
(0.0, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 1),
|
||||||
|
(0.04, 0.8),
|
||||||
|
(0.04, 0.6),
|
||||||
|
(0.04, 0.4),
|
||||||
|
(0.04, 0.2),
|
||||||
|
(0.04, 0),
|
||||||
|
]
|
||||||
|
r.assert_states_and_times(expected)
|
||||||
|
g.assert_states_and_times(expected)
|
||||||
|
b.assert_states_and_times(expected)
|
||||||
|
|
||||||
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
|
reason='timing is too random on pypy')
|
||||||
|
def test_rgbled_pulse_foreground():
|
||||||
|
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||||
|
with RGBLED(r, g, b) as device:
|
||||||
|
start = time()
|
||||||
|
device.pulse(0.2, 0.2, n=2, background=False)
|
||||||
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
expected = [
|
expected = [
|
||||||
(0.0, 0),
|
(0.0, 0),
|
||||||
(0.04, 0.2),
|
(0.04, 0.2),
|
||||||
|
|||||||
Reference in New Issue
Block a user