Skip to content

Commit

Permalink
Merge branch 'lurch-ramping-values'
Browse files Browse the repository at this point in the history
  • Loading branch information
waveform80 committed Feb 19, 2018
2 parents 882dc6b + ea77ec0 commit 7d5892e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 22 deletions.
2 changes: 2 additions & 0 deletions docs/api_tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Artificial sources

.. autofunction:: cos_values

.. autofunction:: ramping_values

.. autofunction:: random_values

.. autofunction:: sin_values
83 changes: 61 additions & 22 deletions gpiozero/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
from statistics import mean
except ImportError:
from .compat import mean
try:
from math import isclose
except ImportError:
from .compat import isclose


def negated(values):
Expand Down Expand Up @@ -108,9 +112,9 @@ def clamped(values, output_min=0, output_max=1):
led = PWMLED(4)
pot = MCP3008(channel=0)
led.source = clamped(pot.values, 0.5, 1.0)
pause()
"""
if output_min >= output_max:
Expand All @@ -131,10 +135,10 @@ def absoluted(values):
led = PWMLED(4)
motor = Motor(22, 27)
pot = MCP3008(channel=0)
motor.source = scaled(pot.values, -1, 1)
led.source = absoluted(motor.values)
pause()
"""
for v in values:
Expand Down Expand Up @@ -287,9 +291,9 @@ def averaged(*values):
pot2 = MCP3008(channel=1)
pot3 = MCP3008(channel=2)
led = PWMLED(4)
led.source = averaged(pot1.values, pot2.values, pot3.values)
pause()
"""
for v in zip(*values):
Expand All @@ -312,7 +316,7 @@ def summed(*values):
led = PWMLED(4)
led.source = scaled(summed(pot1.values, pot2.values, pot3.values), 0, 1, 0, 3)
pause()
"""
for v in zip(*values):
Expand All @@ -334,9 +338,9 @@ def multiplied(*values):
pot2 = MCP3008(channel=1)
pot3 = MCP3008(channel=2)
led = PWMLED(4)
led.source = multiplied(pot1.values, pot2.values, pot3.values)
pause()
"""
def _product(it):
Expand All @@ -360,13 +364,13 @@ def queued(values, qsize):
leds = LEDBoard(5, 6, 13, 19, 26)
btn = Button(17)
for i in range(4):
leds[i].source = queued(leds[i + 1].values, 5)
leds[i].source_delay = 0.01
leds[4].source = btn.values
pause()
"""
if qsize < 1:
Expand Down Expand Up @@ -395,7 +399,7 @@ def smoothed(values, qsize, average=mean):
from gpiozero.tools import smoothed
adc = MCP3008(channel=0)
for value in smoothed(adc.values, 5):
print(value)
"""
Expand Down Expand Up @@ -445,7 +449,7 @@ def pre_periodic_filtered(values, block, repeat_after):
from gpiozero.tools import pre_periodic_filtered
adc = MCP3008(channel=0)
for value in pre_periodic_filtered(adc.values, 50, 0):
print(value)
Expand All @@ -455,7 +459,7 @@ def pre_periodic_filtered(values, block, repeat_after):
from gpiozero.tools import pre_periodic_filtered
adc = MCP3008(channel=0)
for value in pre_periodic_filtered(adc.values, 1, 1):
print(value)
"""
Expand Down Expand Up @@ -487,7 +491,7 @@ def post_periodic_filtered(values, repeat_after, block):
from gpiozero.tools import post_periodic_filtered
adc = MCP3008(channel=0)
for value in post_periodic_filtered(adc.values, 9, 1):
print(value)
"""
Expand All @@ -513,9 +517,9 @@ def random_values():
from signal import pause
led = PWMLED(4)
led.source = random_values()
pause()
If you require a wider range than 0 to 1, see :func:`scaled`.
Expand All @@ -536,12 +540,12 @@ def sin_values(period=360):
red = PWMLED(2)
blue = PWMLED(3)
red.source_delay = 0.01
blue.source_delay = red.source_delay
red.source = scaled(sin_values(100), 0, 1, -1, 1)
blue.source = inverted(red.values)
pause()
If you require a different range than -1 to +1, see :func:`scaled`.
Expand All @@ -563,12 +567,12 @@ def cos_values(period=360):
red = PWMLED(2)
blue = PWMLED(3)
red.source_delay = 0.01
blue.source_delay = red.source_delay
red.source = scaled(cos_values(100), 0, 1, -1, 1)
blue.source = inverted(red.values)
pause()
If you require a different range than -1 to +1, see :func:`scaled`.
Expand Down Expand Up @@ -599,3 +603,38 @@ def alternating_values(initial_value=False):
while True:
yield value
value = not value


def ramping_values(period=360):
"""
Provides an infinite source of values representing a triangle wave (from 0
to 1 and back again) which repeats every *period* values. For example, to
pulse an LED once a second::
from gpiozero import PWMLED
from gpiozero.tools import ramping_values
from signal import pause
red = PWMLED(2)
red.source_delay = 0.01
red.source = ramping_values(100)
pause()
If you require a wider range than 0 to 1, see :func:`scaled`.
"""
step = 2 / period
value = 0
while True:
yield value
value += step
if isclose(value, 1, abs_tol=1e-9):
value = 1
step *= -1
elif isclose(value, 0, abs_tol=1e-9):
value = 0
step *= -1
elif value > 1 or value < 0:
step *= -1
value += step
40 changes: 40 additions & 0 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ def test_random_values():
assert 0 <= v <= 1

def test_sin_values():
for e, v in zip([0, 0], sin_values(2)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
for e, v in zip([0, 1, 0, -1], sin_values(4)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
for e, v in zip([0, 2**0.5/2, 1, 2**0.5/2, 0, -2**0.5/2, -1, -2**0.5/2], sin_values(8)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
firstval = None
for i, v in zip(range(1000), sin_values()):
assert -1 <= v <= 1
Expand All @@ -257,6 +266,15 @@ def test_sin_values():
assert v == firstval

def test_cos_values():
for e, v in zip([1, -1], cos_values(2)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
for e, v in zip([1, 0, -1, 0], cos_values(4)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
for e, v in zip([1, 2**0.5/2, 0, -2**0.5/2, -1, -2**0.5/2, 0, 2**0.5/2], cos_values(8)):
assert -1 <= v <= 1
assert isclose(e, v, abs_tol=1e-9)
firstval = None
for i, v in zip(range(1000), cos_values()):
assert -1 <= v <= 1
Expand All @@ -275,3 +293,25 @@ def test_cos_values():
else:
if i % period == 0:
assert v == firstval

def test_ramping_values():
assert list(islice(ramping_values(2), 2)) == [0, 1]
assert list(islice(ramping_values(4), 4)) == [0, 0.5, 1, 0.5]
assert list(islice(ramping_values(8), 8)) == [0, 0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25]
firstval = None
for i, v in zip(range(1000), ramping_values()):
assert 0 <= v <= 1
if i == 0:
firstval = v
else:
if i % 360 == 0:
v == firstval
for period in (360, 100):
firstval = None
for i, v in zip(range(1000), ramping_values(period)):
assert 0 <= v <= 1
if i == 0:
firstval = v
else:
if i % period == 0:
assert v == firstval

0 comments on commit 7d5892e

Please sign in to comment.