mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Fix real pin tests ... and some other bits
The real pin tests were broken by the new factory stuff. This commit fixes them up, and fixes up a few other bits besides (like why the pigpio PWM tests were failing, why RPi.GPIO sometimes segfaulted on PWM tests, etc.) It also causes the real pin tests to run against MockPin (thanks to @lurch for the suggestion!). This required some tweaks to MockPin to make it emulate physically pulled up pins itself (which in turn necessitated changing quite a few pin numbers in the main test suite because we were using 2 and 3 everywhere), and to allow one MockPin to drive another. Anyway, everything's working now including all the tests on a Pi (haven't tried RPIO yet, but only because I'm on a Pi3 - everything else works with overall coverage of 88% :).
This commit is contained in:
@@ -18,7 +18,13 @@ except ImportError:
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from ..exc import PinPWMUnsupported, PinSetInput, PinFixedPull
|
||||
from ..exc import (
|
||||
PinPWMUnsupported,
|
||||
PinSetInput,
|
||||
PinFixedPull,
|
||||
PinInvalidFunction,
|
||||
PinInvalidPull,
|
||||
)
|
||||
from ..devices import Device
|
||||
from .pi import PiPin
|
||||
from .local import LocalPiFactory
|
||||
@@ -34,8 +40,8 @@ class MockPin(PiPin):
|
||||
def __init__(self, factory, number):
|
||||
super(MockPin, self).__init__(factory, number)
|
||||
self._function = 'input'
|
||||
self._state = False
|
||||
self._pull = 'floating'
|
||||
self._pull = 'up' if factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
||||
self._state = self._pull == 'up'
|
||||
self._bounce = None
|
||||
self._edges = 'both'
|
||||
self._when_changed = None
|
||||
@@ -49,7 +55,8 @@ class MockPin(PiPin):
|
||||
return self._function
|
||||
|
||||
def _set_function(self, value):
|
||||
assert value in ('input', 'output')
|
||||
if value not in ('input', 'output'):
|
||||
raise PinInvalidFunction('function must be input or output')
|
||||
self._function = value
|
||||
if value == 'input':
|
||||
# Drive the input to the pull
|
||||
@@ -85,8 +92,12 @@ class MockPin(PiPin):
|
||||
return self._pull
|
||||
|
||||
def _set_pull(self, value):
|
||||
assert self._function == 'input'
|
||||
assert value in ('floating', 'up', 'down')
|
||||
if self.function != 'input':
|
||||
raise PinFixedPull('cannot set pull on non-input pin %r' % self)
|
||||
if value != 'up' and self.factory.pi_info.pulled_up(self.address[-1]):
|
||||
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
||||
if value not in ('floating', 'up', 'down'):
|
||||
raise PinInvalidPull('pull must be floating, up, or down')
|
||||
self._pull = value
|
||||
if value == 'up':
|
||||
self.drive_high()
|
||||
@@ -132,7 +143,12 @@ class MockPin(PiPin):
|
||||
def assert_states(self, expected_states):
|
||||
# Tests that the pin went through the expected states (a list of values)
|
||||
for actual, expected in zip(self.states, expected_states):
|
||||
assert actual.state == expected
|
||||
try:
|
||||
assert actual.state == expected
|
||||
except AssertionError:
|
||||
print('Actual states', self.states)
|
||||
print('Expected states', expected_states)
|
||||
raise
|
||||
|
||||
def assert_states_and_times(self, expected_states):
|
||||
# Tests that the pin went through the expected states at the expected
|
||||
@@ -140,8 +156,32 @@ class MockPin(PiPin):
|
||||
# that's about all we can reasonably expect in a non-realtime
|
||||
# environment on a Pi 1)
|
||||
for actual, expected in zip(self.states, expected_states):
|
||||
assert isclose(actual.timestamp, expected[0], rel_tol=0.05, abs_tol=0.05)
|
||||
assert isclose(actual.state, expected[1])
|
||||
try:
|
||||
assert isclose(actual.timestamp, expected[0], rel_tol=0.05, abs_tol=0.05)
|
||||
assert isclose(actual.state, expected[1])
|
||||
except AssertionError:
|
||||
print('Actual states', self.states)
|
||||
print('Expected states', expected_states)
|
||||
raise
|
||||
|
||||
|
||||
class MockConnectedPin(MockPin):
|
||||
"""
|
||||
This derivative of :class:`MockPin` emulates a pin connected to another
|
||||
mock pin. This is used in the "real pins" portion of the test suite to
|
||||
check that one pin can influence another.
|
||||
"""
|
||||
def __init__(self, factory, number):
|
||||
super(MockConnectedPin, self).__init__(factory, number)
|
||||
self.input_pin = None
|
||||
|
||||
def _change_state(self, value):
|
||||
if self.input_pin:
|
||||
if value:
|
||||
self.input_pin.drive_high()
|
||||
else:
|
||||
self.input_pin.drive_low()
|
||||
return super(MockConnectedPin, self)._change_state(value)
|
||||
|
||||
|
||||
class MockPulledUpPin(MockPin):
|
||||
|
||||
@@ -236,6 +236,12 @@ class PiGPIOPin(PiPin):
|
||||
|
||||
def _set_frequency(self, value):
|
||||
if not self._pwm and value is not None:
|
||||
if self.function != 'output':
|
||||
raise PinPWMFixedValue('cannot start PWM on pin %r' % self)
|
||||
# NOTE: the pin's state *must* be set to zero; if it's currently
|
||||
# high, starting PWM and setting a 0 duty-cycle *doesn't* bring
|
||||
# the pin low; it stays high!
|
||||
self.factory.connection.write(self.number, 0)
|
||||
self.factory.connection.set_PWM_frequency(self.number, value)
|
||||
self.factory.connection.set_PWM_range(self.number, 10000)
|
||||
self.factory.connection.set_PWM_dutycycle(self.number, 0)
|
||||
|
||||
1
setup.py
1
setup.py
@@ -77,7 +77,6 @@ __entry_points__ = {
|
||||
'gpiozero_mock_pin_classes': [
|
||||
'mockpin = gpiozero.pins.mock:MockPin',
|
||||
'mockpwmpin = gpiozero.pins.mock:MockPWMPin',
|
||||
'mockpulleduppin = gpiozero.pins.mock:MockPulledUpPin',
|
||||
'mockchargingpin = gpiozero.pins.mock:MockChargingPin',
|
||||
'mocktriggerpin = gpiozero.pins.mock:MockTriggerPin',
|
||||
],
|
||||
|
||||
@@ -246,10 +246,15 @@ def test_led_board_bad_blink():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_blink_background():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
# Instantiation takes a long enough time that it throws off our timing
|
||||
# here!
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0.1, 0.1, n=2)
|
||||
board._blink_thread.join() # naughty, but ensures no arbitrary waits in the test
|
||||
test = [
|
||||
@@ -266,10 +271,13 @@ def test_led_board_blink_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_blink_foreground():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0.1, 0.1, n=2, background=False)
|
||||
test = [
|
||||
(0.0, False),
|
||||
@@ -285,10 +293,13 @@ def test_led_board_blink_foreground():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_blink_control():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0.1, 0.1, n=2)
|
||||
# make sure the blink thread's started
|
||||
while not board._blink_leds:
|
||||
@@ -310,10 +321,13 @@ def test_led_board_blink_control():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_blink_take_over():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board[1].blink(0.1, 0.1, n=2)
|
||||
board.blink(0.1, 0.1, n=2) # immediately take over blinking
|
||||
board[1]._blink_thread.join()
|
||||
@@ -332,10 +346,13 @@ def test_led_board_blink_take_over():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_blink_control_all():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0.1, 0.1, n=2)
|
||||
# make sure the blink thread's started
|
||||
while not board._blink_leds:
|
||||
@@ -354,9 +371,9 @@ def test_led_board_blink_control_all():
|
||||
pin3.assert_states_and_times(test)
|
||||
|
||||
def test_led_board_blink_interrupt_on():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
board.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
@@ -366,10 +383,13 @@ def test_led_board_blink_interrupt_on():
|
||||
pin3.assert_states([False, True, False])
|
||||
|
||||
def test_led_board_blink_interrupt_off():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0.1, 1)
|
||||
sleep(0.2)
|
||||
board.off() # should interrupt while off
|
||||
@@ -380,10 +400,13 @@ def test_led_board_blink_interrupt_off():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_led_board_fade_background():
|
||||
pin1 = Device._pin_factory.pin(2)
|
||||
pin2 = Device._pin_factory.pin(3)
|
||||
pin3 = Device._pin_factory.pin(4)
|
||||
pin1 = Device._pin_factory.pin(4)
|
||||
pin2 = Device._pin_factory.pin(5)
|
||||
pin3 = Device._pin_factory.pin(6)
|
||||
with LEDBoard(pin1, LEDBoard(pin2, pin3, pwm=True), pwm=True) as board:
|
||||
pin1.clear_states()
|
||||
pin2.clear_states()
|
||||
pin3.clear_states()
|
||||
board.blink(0, 0, 0.2, 0.2, n=2)
|
||||
board._blink_thread.join()
|
||||
test = [
|
||||
|
||||
@@ -65,7 +65,7 @@ def test_device_reopen_same_pin():
|
||||
assert device.pin is None
|
||||
|
||||
def test_device_repr():
|
||||
with GPIODevice(2) as device:
|
||||
with GPIODevice(4) as device:
|
||||
assert repr(device) == '<gpiozero.GPIODevice object on pin %s, is_active=False>' % device.pin
|
||||
|
||||
def test_device_repr_after_close():
|
||||
@@ -85,18 +85,18 @@ def test_device_context_manager():
|
||||
|
||||
def test_composite_device_sequence():
|
||||
with CompositeDevice(
|
||||
InputDevice(2),
|
||||
InputDevice(3)
|
||||
InputDevice(4),
|
||||
InputDevice(5)
|
||||
) as device:
|
||||
assert len(device) == 2
|
||||
assert device[0].pin.number == 2
|
||||
assert device[1].pin.number == 3
|
||||
assert device[0].pin.number == 4
|
||||
assert device[1].pin.number == 5
|
||||
assert device.namedtuple._fields == ('_0', '_1')
|
||||
|
||||
def test_composite_device_values():
|
||||
with CompositeDevice(
|
||||
InputDevice(2),
|
||||
InputDevice(3)
|
||||
InputDevice(4),
|
||||
InputDevice(5)
|
||||
) as device:
|
||||
assert device.value == (0, 0)
|
||||
assert not device.is_active
|
||||
@@ -106,8 +106,8 @@ def test_composite_device_values():
|
||||
|
||||
def test_composite_device_named():
|
||||
with CompositeDevice(
|
||||
foo=InputDevice(2),
|
||||
bar=InputDevice(3),
|
||||
foo=InputDevice(4),
|
||||
bar=InputDevice(5),
|
||||
_order=('foo', 'bar')
|
||||
) as device:
|
||||
assert device.namedtuple._fields == ('foo', 'bar')
|
||||
@@ -126,8 +126,8 @@ def test_composite_device_bad_init():
|
||||
|
||||
def test_composite_device_read_only():
|
||||
with CompositeDevice(
|
||||
foo=InputDevice(2),
|
||||
bar=InputDevice(3)
|
||||
foo=InputDevice(4),
|
||||
bar=InputDevice(5)
|
||||
) as device:
|
||||
with pytest.raises(AttributeError):
|
||||
device.foo = 1
|
||||
|
||||
@@ -12,7 +12,7 @@ import pytest
|
||||
from threading import Event
|
||||
from functools import partial
|
||||
|
||||
from gpiozero.pins.mock import MockPulledUpPin, MockChargingPin, MockTriggerPin
|
||||
from gpiozero.pins.mock import MockChargingPin, MockTriggerPin
|
||||
from gpiozero import *
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ def teardown_function(function):
|
||||
|
||||
|
||||
def test_input_initial_values():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with InputDevice(pin, pull_up=True) as device:
|
||||
assert pin.function == 'input'
|
||||
assert pin.pull == 'up'
|
||||
@@ -42,23 +42,23 @@ def test_input_is_active_low():
|
||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=True, is_active=True>'
|
||||
|
||||
def test_input_is_active_high():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with InputDevice(pin, pull_up=False) as device:
|
||||
pin.drive_high()
|
||||
assert device.is_active
|
||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=False, is_active=True>'
|
||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO4, pull_up=False, is_active=True>'
|
||||
pin.drive_low()
|
||||
assert not device.is_active
|
||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=False, is_active=False>'
|
||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO4, pull_up=False, is_active=False>'
|
||||
|
||||
def test_input_pulled_up():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPulledUpPin)
|
||||
pin = Device._pin_factory.pin(2)
|
||||
with pytest.raises(PinFixedPull):
|
||||
InputDevice(pin, pull_up=False)
|
||||
|
||||
def test_input_event_activated():
|
||||
event = Event()
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalInputDevice(pin) as device:
|
||||
device.when_activated = lambda: event.set()
|
||||
assert not event.is_set()
|
||||
@@ -67,7 +67,7 @@ def test_input_event_activated():
|
||||
|
||||
def test_input_event_deactivated():
|
||||
event = Event()
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalInputDevice(pin) as device:
|
||||
device.when_deactivated = lambda: event.set()
|
||||
assert not event.is_set()
|
||||
@@ -78,7 +78,7 @@ def test_input_event_deactivated():
|
||||
|
||||
def test_input_partial_callback():
|
||||
event = Event()
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
def foo(a, b):
|
||||
event.set()
|
||||
return a + b
|
||||
@@ -91,22 +91,22 @@ def test_input_partial_callback():
|
||||
assert event.is_set()
|
||||
|
||||
def test_input_wait_active():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalInputDevice(pin) as device:
|
||||
pin.drive_high()
|
||||
assert device.wait_for_active(1)
|
||||
assert not device.wait_for_inactive(0)
|
||||
|
||||
def test_input_wait_inactive():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalInputDevice(pin) as device:
|
||||
assert device.wait_for_inactive(1)
|
||||
assert not device.wait_for_active(0)
|
||||
|
||||
def test_input_smoothed_attrib():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with SmoothedInputDevice(pin, threshold=0.5, queue_len=5, partial=False) as device:
|
||||
assert repr(device) == '<gpiozero.SmoothedInputDevice object on pin GPIO2, pull_up=False>'
|
||||
assert repr(device) == '<gpiozero.SmoothedInputDevice object on pin GPIO4, pull_up=False>'
|
||||
assert device.threshold == 0.5
|
||||
assert device.queue_len == 5
|
||||
assert not device.partial
|
||||
@@ -116,7 +116,7 @@ def test_input_smoothed_attrib():
|
||||
device.threshold = 1
|
||||
|
||||
def test_input_smoothed_values():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with SmoothedInputDevice(pin) as device:
|
||||
device._queue.start()
|
||||
assert not device.is_active
|
||||
@@ -138,7 +138,7 @@ def test_input_button():
|
||||
assert button.wait_for_release(1)
|
||||
|
||||
def test_input_line_sensor():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with LineSensor(pin) as sensor:
|
||||
pin.drive_low() # logic is inverted for line sensor
|
||||
assert sensor.wait_for_line(1)
|
||||
@@ -148,7 +148,7 @@ def test_input_line_sensor():
|
||||
assert not sensor.line_detected
|
||||
|
||||
def test_input_motion_sensor():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with MotionSensor(pin) as sensor:
|
||||
pin.drive_high()
|
||||
assert sensor.wait_for_motion(1)
|
||||
@@ -160,7 +160,7 @@ def test_input_motion_sensor():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_input_light_sensor():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockChargingPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockChargingPin)
|
||||
with LightSensor(pin) as sensor:
|
||||
pin.charge_time = 0.1
|
||||
assert sensor.wait_for_dark(1)
|
||||
@@ -170,8 +170,8 @@ def test_input_light_sensor():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_input_distance_sensor():
|
||||
echo_pin = Device._pin_factory.pin(2)
|
||||
trig_pin = Device._pin_factory.pin(3, pin_class=MockTriggerPin)
|
||||
echo_pin = Device._pin_factory.pin(4)
|
||||
trig_pin = Device._pin_factory.pin(5, pin_class=MockTriggerPin)
|
||||
trig_pin.echo_pin = echo_pin
|
||||
trig_pin.echo_time = 0.02
|
||||
with pytest.raises(ValueError):
|
||||
|
||||
@@ -28,7 +28,7 @@ def test_mock_pin_init():
|
||||
assert Device._pin_factory.pin(2).number == 2
|
||||
|
||||
def test_mock_pin_defaults():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
assert pin.bounce == None
|
||||
assert pin.edges == 'both'
|
||||
assert pin.frequency == None
|
||||
@@ -36,6 +36,9 @@ def test_mock_pin_defaults():
|
||||
assert pin.pull == 'floating'
|
||||
assert pin.state == 0
|
||||
assert pin.when_changed == None
|
||||
pin.close()
|
||||
pin = Device._pin_factory.pin(2)
|
||||
assert pin.pull == 'up'
|
||||
|
||||
def test_mock_pin_open_close():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
@@ -54,7 +57,7 @@ def test_mock_pin_init_twice_different_pin():
|
||||
assert pin2.number == pin1.number+1
|
||||
|
||||
def test_mock_pwm_pin_defaults():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
assert pin.bounce == None
|
||||
assert pin.edges == 'both'
|
||||
assert pin.frequency == None
|
||||
@@ -62,6 +65,9 @@ def test_mock_pwm_pin_defaults():
|
||||
assert pin.pull == 'floating'
|
||||
assert pin.state == 0
|
||||
assert pin.when_changed == None
|
||||
pin.close()
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
assert pin.pull == 'up'
|
||||
|
||||
def test_mock_pwm_pin_open_close():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
@@ -104,20 +110,25 @@ def test_mock_pin_frequency_supported():
|
||||
assert not pin.state
|
||||
|
||||
def test_mock_pin_pull():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
pin.function = 'input'
|
||||
assert pin.pull == 'floating'
|
||||
pin.pull = 'up'
|
||||
assert pin.state
|
||||
pin.pull = 'down'
|
||||
assert not pin.state
|
||||
pin.close()
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin.function = 'input'
|
||||
assert pin.pull == 'up'
|
||||
with pytest.raises(PinFixedPull):
|
||||
pin.pull = 'floating'
|
||||
|
||||
def test_mock_pin_state():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
with pytest.raises(PinSetInput):
|
||||
pin.state = 1
|
||||
pin.function = 'output'
|
||||
assert pin.state == 0
|
||||
pin.state = 1
|
||||
assert pin.state == 1
|
||||
pin.state = 0
|
||||
@@ -130,7 +141,6 @@ def test_mock_pwm_pin_state():
|
||||
with pytest.raises(PinSetInput):
|
||||
pin.state = 1
|
||||
pin.function = 'output'
|
||||
assert pin.state == 0
|
||||
pin.state = 1
|
||||
assert pin.state == 1
|
||||
pin.state = 0
|
||||
|
||||
@@ -95,7 +95,7 @@ def test_output_digital_toggle():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_blink_background():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2)
|
||||
@@ -113,7 +113,7 @@ def test_output_blink_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_blink_foreground():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2, background=False)
|
||||
@@ -127,7 +127,7 @@ def test_output_blink_foreground():
|
||||
])
|
||||
|
||||
def test_output_blink_interrupt_on():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalOutputDevice(pin) as device:
|
||||
device.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
@@ -135,7 +135,7 @@ def test_output_blink_interrupt_on():
|
||||
pin.assert_states([False, True, False])
|
||||
|
||||
def test_output_blink_interrupt_off():
|
||||
pin = Device._pin_factory.pin(2)
|
||||
pin = Device._pin_factory.pin(4)
|
||||
with DigitalOutputDevice(pin) as device:
|
||||
device.blink(0.1, 1)
|
||||
sleep(0.2)
|
||||
@@ -151,7 +151,7 @@ def test_output_pwm_not_supported():
|
||||
PWMOutputDevice(Device._pin_factory.pin(2))
|
||||
|
||||
def test_output_pwm_states():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.value = 0.1
|
||||
device.value = 0.2
|
||||
@@ -172,14 +172,14 @@ def test_output_pwm_read():
|
||||
assert device.frequency is None
|
||||
|
||||
def test_output_pwm_write():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.on()
|
||||
device.off()
|
||||
pin.assert_states([False, True, False])
|
||||
|
||||
def test_output_pwm_toggle():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.toggle()
|
||||
device.value = 0.5
|
||||
@@ -218,7 +218,7 @@ def test_output_pwm_write_silly():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_blink_background():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2)
|
||||
@@ -236,7 +236,7 @@ def test_output_pwm_blink_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_blink_foreground():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2, background=False)
|
||||
@@ -252,7 +252,7 @@ def test_output_pwm_blink_foreground():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_fade_background():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||
@@ -286,7 +286,7 @@ def test_output_pwm_fade_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_fade_foreground():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||
@@ -318,7 +318,7 @@ def test_output_pwm_fade_foreground():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_pulse_background():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.pulse(0.2, 0.2, n=2)
|
||||
@@ -352,7 +352,7 @@ def test_output_pwm_pulse_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_pulse_foreground():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
start = time()
|
||||
device.pulse(0.2, 0.2, n=2, background=False)
|
||||
@@ -382,7 +382,7 @@ def test_output_pwm_pulse_foreground():
|
||||
])
|
||||
|
||||
def test_output_pwm_blink_interrupt():
|
||||
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
|
||||
pin = Device._pin_factory.pin(4, pin_class=MockPWMPin)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
@@ -515,7 +515,7 @@ def test_rgbled_blink_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_background():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2)
|
||||
@@ -536,7 +536,7 @@ def test_rgbled_blink_background():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_background_nonpwm():
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2)
|
||||
@@ -557,7 +557,7 @@ def test_rgbled_blink_background_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_foreground():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2, background=False)
|
||||
@@ -576,7 +576,7 @@ def test_rgbled_blink_foreground():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_foreground_nonpwm():
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2, background=False)
|
||||
@@ -595,7 +595,7 @@ def test_rgbled_blink_foreground_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_fade_background():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||
@@ -638,7 +638,7 @@ def test_rgbled_fade_background_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_fade_foreground():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||
@@ -679,7 +679,7 @@ def test_rgbled_fade_foreground_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_pulse_background():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.pulse(0.2, 0.2, n=2)
|
||||
@@ -722,7 +722,7 @@ def test_rgbled_pulse_background_nonpwm():
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_pulse_foreground():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
start = time()
|
||||
device.pulse(0.2, 0.2, n=2, background=False)
|
||||
@@ -761,7 +761,7 @@ def test_rgbled_pulse_foreground_nonpwm():
|
||||
device.pulse(0.2, 0.2, n=2, background=False)
|
||||
|
||||
def test_rgbled_blink_interrupt():
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b) as device:
|
||||
device.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
@@ -771,7 +771,7 @@ def test_rgbled_blink_interrupt():
|
||||
b.assert_states([0, 1, 0])
|
||||
|
||||
def test_rgbled_blink_interrupt_nonpwm():
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (1, 2, 3))
|
||||
r, g, b = (Device._pin_factory.pin(i) for i in (4, 5, 6))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
device.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
|
||||
@@ -11,20 +11,33 @@ except NameError:
|
||||
pass
|
||||
|
||||
import io
|
||||
import os
|
||||
import subprocess
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
import pkg_resources
|
||||
|
||||
from gpiozero import PinFixedPull, PinInvalidPull, PinInvalidFunction
|
||||
from gpiozero import (
|
||||
PinFixedPull,
|
||||
PinInvalidPull,
|
||||
PinInvalidFunction,
|
||||
PinPWMUnsupported,
|
||||
Device,
|
||||
)
|
||||
from gpiozero.pins.mock import MockConnectedPin, MockFactory
|
||||
try:
|
||||
from math import isclose
|
||||
except ImportError:
|
||||
from gpiozero.compat import isclose
|
||||
|
||||
|
||||
# This module assumes you've wired the following GPIO pins together
|
||||
TEST_PIN = 22
|
||||
INPUT_PIN = 27
|
||||
# This module assumes you've wired the following GPIO pins together. The pins
|
||||
# can be re-configured via the listed environment variables (useful for when
|
||||
# your testing rig requires different pins because the defaults interfere with
|
||||
# attached hardware).
|
||||
TEST_PIN = int(os.getenv('GPIOZERO_TEST_PIN', '22'))
|
||||
INPUT_PIN = int(os.getenv('GPIOZERO_INPUT_PIN', '27'))
|
||||
|
||||
|
||||
# Skip the entire module if we're not on a Pi
|
||||
@@ -40,51 +53,48 @@ pytestmark = pytest.mark.skipif(not is_a_pi(), reason='tests cannot run on non-P
|
||||
del is_a_pi
|
||||
|
||||
|
||||
# Try and import as many pin libraries as possible
|
||||
PIN_CLASSES = []
|
||||
try:
|
||||
from gpiozero.pins.rpigpio import RPiGPIOPin
|
||||
PIN_CLASSES.append(RPiGPIOPin)
|
||||
except ImportError:
|
||||
RPiGPIOPin = None
|
||||
try:
|
||||
from gpiozero.pins.rpio import RPIOPin
|
||||
PIN_CLASSES.append(RPIOPin)
|
||||
except ImportError:
|
||||
RPIOPin = None
|
||||
try:
|
||||
from gpiozero.pins.pigpiod import PiGPIOPin
|
||||
PIN_CLASSES.append(PiGPIOPin)
|
||||
except ImportError:
|
||||
PiGPIOPin = None
|
||||
try:
|
||||
from gpiozero.pins.native import NativePin
|
||||
PIN_CLASSES.append(NativePin)
|
||||
except ImportError:
|
||||
NativePin = None
|
||||
@pytest.fixture(
|
||||
scope='module',
|
||||
params=('rpigpio',))
|
||||
#params=pkg_resources.get_distribution('gpiozero').get_entry_map('gpiozero_pin_factories').keys())
|
||||
def pin_factory(request):
|
||||
# Constructs each pin factory in turn with some extra logic to ensure
|
||||
# the pigpiod daemon gets started and stopped around the pigpio factory
|
||||
if request.param == 'pigpio':
|
||||
try:
|
||||
subprocess.check_call(['sudo', 'systemctl', 'start', 'pigpiod'])
|
||||
except subprocess.CalledProcessError:
|
||||
pytest.skip("skipped factory pigpio: failed to start pigpiod")
|
||||
try:
|
||||
factory = pkg_resources.load_entry_point('gpiozero', 'gpiozero_pin_factories', request.param)()
|
||||
except Exception as e:
|
||||
if request.param == 'pigpio':
|
||||
subprocess.check_call(['sudo', 'systemctl', 'stop', 'pigpiod'])
|
||||
pytest.skip("skipped factory %s: %s" % (request.param, str(e)))
|
||||
else:
|
||||
Device._set_pin_factory(factory)
|
||||
def fin():
|
||||
Device._set_pin_factory(MockFactory())
|
||||
if request.param == 'pigpio':
|
||||
subprocess.check_call(['sudo', 'systemctl', 'stop', 'pigpiod'])
|
||||
request.addfinalizer(fin)
|
||||
return factory
|
||||
|
||||
@pytest.fixture(scope='module', params=PIN_CLASSES)
|
||||
def pin_class(request):
|
||||
# pigpiod needs to be running for PiGPIOPin
|
||||
if request.param.__name__ == 'PiGPIOPin':
|
||||
subprocess.check_call(['sudo', 'pigpiod'])
|
||||
# Unfortunately, pigpiod provides no option for running in the
|
||||
# foreground, so we have to use the sledgehammer of killall to get shot
|
||||
# of it
|
||||
def kill_pigpiod():
|
||||
subprocess.check_call(['sudo', 'killall', 'pigpiod'])
|
||||
request.addfinalizer(kill_pigpiod)
|
||||
return request.param
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pins(request, pin_class):
|
||||
def pins(request, pin_factory):
|
||||
# Why return both pins in a single fixture? If we defined one fixture for
|
||||
# each pin then pytest will (correctly) test RPiGPIOPin(22) against
|
||||
# NativePin(27) and so on. This isn't supported, so we don't test it
|
||||
test_pin = pin_class(TEST_PIN)
|
||||
input_pin = pin_class(INPUT_PIN)
|
||||
if pin_factory.__class__.__name__ == 'MockFactory':
|
||||
test_pin = pin_factory.pin(TEST_PIN, pin_class=MockConnectedPin)
|
||||
else:
|
||||
test_pin = pin_factory.pin(TEST_PIN)
|
||||
input_pin = pin_factory.pin(INPUT_PIN)
|
||||
input_pin.function = 'input'
|
||||
input_pin.pull = 'down'
|
||||
if pin_factory.__class__.__name__ == 'MockFactory':
|
||||
test_pin.input_pin = input_pin
|
||||
def fin():
|
||||
test_pin.close()
|
||||
input_pin.close()
|
||||
@@ -134,17 +144,18 @@ def test_pull_bad(pins):
|
||||
with pytest.raises(PinInvalidPull):
|
||||
test_pin.input_with_pull('foo')
|
||||
|
||||
def test_pull_down_warning(pin_class):
|
||||
# XXX This assumes we're on a vaguely modern Pi and not a compute module
|
||||
# Might want to refine this with the pi-info database
|
||||
pin = pin_class(2)
|
||||
try:
|
||||
with pytest.raises(PinFixedPull):
|
||||
pin.pull = 'down'
|
||||
with pytest.raises(PinFixedPull):
|
||||
pin.input_with_pull('down')
|
||||
finally:
|
||||
pin.close()
|
||||
def test_pull_down_warning(pin_factory):
|
||||
if pin_factory.pi_info.pulled_up('GPIO2'):
|
||||
pin = pin_factory.pin(2)
|
||||
try:
|
||||
with pytest.raises(PinFixedPull):
|
||||
pin.pull = 'down'
|
||||
with pytest.raises(PinFixedPull):
|
||||
pin.input_with_pull('down')
|
||||
finally:
|
||||
pin.close()
|
||||
else:
|
||||
pytest.skip("GPIO2 isn't pulled up on this pi")
|
||||
|
||||
def test_input_with_pull(pins):
|
||||
test_pin, input_pin = pins
|
||||
@@ -153,25 +164,42 @@ def test_input_with_pull(pins):
|
||||
test_pin.input_with_pull('down')
|
||||
assert input_pin.state == 0
|
||||
|
||||
@pytest.mark.skipif(True, reason='causes segfaults')
|
||||
def test_bad_duty_cycle(pins):
|
||||
test_pin, input_pin = pins
|
||||
if test_pin.__class__.__name__ == 'NativePin':
|
||||
pytest.skip("native pin doesn't support PWM")
|
||||
test_pin.function = 'output'
|
||||
test_pin.frequency = 100
|
||||
with pytest.raises(ValueError):
|
||||
test_pin.state = 1.1
|
||||
try:
|
||||
# NOTE: There's some race in RPi.GPIO that causes a segfault if we
|
||||
# don't pause before starting PWM; only seems to happen when stopping
|
||||
# and restarting PWM very rapidly (i.e. between test cases).
|
||||
if Device._pin_factory.__class__.__name__ == 'RPiGPIOFactory':
|
||||
sleep(0.1)
|
||||
test_pin.frequency = 100
|
||||
except PinPWMUnsupported:
|
||||
pytest.skip("%r doesn't support PWM" % test_pin.factory)
|
||||
else:
|
||||
try:
|
||||
with pytest.raises(ValueError):
|
||||
test_pin.state = 1.1
|
||||
finally:
|
||||
test_pin.frequency = None
|
||||
|
||||
def test_duty_cycles(pins):
|
||||
test_pin, input_pin = pins
|
||||
if test_pin.__class__.__name__ == 'NativePin':
|
||||
pytest.skip("native pin doesn't support PWM")
|
||||
test_pin.function = 'output'
|
||||
test_pin.frequency = 100
|
||||
for duty_cycle in (0.0, 0.1, 0.5, 1.0):
|
||||
test_pin.state = duty_cycle
|
||||
assert test_pin.state == duty_cycle
|
||||
total = sum(input_pin.state for i in range(20000))
|
||||
assert isclose(total / 20000, duty_cycle, rel_tol=0.1, abs_tol=0.1)
|
||||
try:
|
||||
# NOTE: see above
|
||||
if Device._pin_factory.__class__.__name__ == 'RPiGPIOFactory':
|
||||
sleep(0.1)
|
||||
test_pin.frequency = 100
|
||||
except PinPWMUnsupported:
|
||||
pytest.skip("%r doesn't support PWM" % test_pin.factory)
|
||||
else:
|
||||
try:
|
||||
for duty_cycle in (0.0, 0.1, 0.5, 1.0):
|
||||
test_pin.state = duty_cycle
|
||||
assert test_pin.state == duty_cycle
|
||||
total = sum(input_pin.state for i in range(20000))
|
||||
assert isclose(total / 20000, duty_cycle, rel_tol=0.1, abs_tol=0.1)
|
||||
finally:
|
||||
test_pin.frequency = None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user