Merge pull request #569 from waveform80/pin-factory-docs

Fix #568, fix #572, fix #565
This commit is contained in:
Dave Jones
2017-07-14 16:47:55 +01:00
committed by GitHub
25 changed files with 265 additions and 121 deletions

View File

@@ -127,44 +127,30 @@ Like the ``GPIOZERO_PIN_FACTORY`` value, these can be exported from your
.. warning::
The astute and mischievous reader may note that it is possible to mix
strictly local pin implementations, e.g. using ``RPiGPIOPin`` for one pin,
and ``NativePin`` for another. This is unsupported, and if it results in
your script crashing, your components failing, or your Raspberry Pi turning
into an actual raspberry pie, you have only yourself to blame.
factories, e.g. using ``RPiGPIOFactory`` for one pin, and ``NativeFactory``
for another. This is unsupported, and if it results in your script
crashing, your components failing, or your Raspberry Pi turning into an
actual raspberry pie, you have only yourself to blame.
Sensible uses of multiple pin factories are given in :doc:`remote_gpio`.
RPi.GPIO
========
Mock pins
=========
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory
There's also a :class:`gpiozero.pins.mock.MockFactory` which generates entirely
fake pins. This was originally intended for GPIO Zero developers who wish to
write tests for devices without having to have the physical device wired in to
their Pi. However, they have also proven relatively useful in developing GPIO
Zero scripts without having a Pi to hand. This pin factory will never be loaded
by default; it must be explicitly specified. For example:
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin
.. literalinclude:: examples/mock_demo.py
RPIO
====
.. autoclass:: gpiozero.pins.rpio.RPIOFactory
.. autoclass:: gpiozero.pins.rpio.RPIOPin
PiGPIO
======
.. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory
.. autoclass:: gpiozero.pins.pigpio.PiGPIOPin
Native
======
.. autoclass:: gpiozero.pins.native.NativeFactory
.. autoclass:: gpiozero.pins.native.NativePin
Several sub-classes of mock pins exist for emulating various other things
(pins that do/don't support PWM, pins that are connected together, pins that
drive high after a delay, etc). Interested users are invited to read the GPIO
Zero test suite for further examples of usage.
Base classes
@@ -196,22 +182,62 @@ Base classes
:members:
Utilities
=========
RPi.GPIO
========
The pins module also contains a database of information about the various
revisions of Raspberry Pi. This is used internally to raise warnings when
non-physical pins are used, or to raise exceptions when pull-downs are
requested on pins with physical pull-up resistors attached. The following
functions and classes can be used to query this database:
.. currentmodule:: gpiozero.pins.rpigpio
.. currentmodule:: gpiozero
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory
.. autofunction:: pi_info
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin
.. autoclass:: PiBoardInfo
.. autoclass:: HeaderInfo
RPIO
====
.. autoclass:: PinInfo
.. currentmodule:: gpiozero.pins.rpio
.. autoclass:: gpiozero.pins.rpio.RPIOFactory
.. autoclass:: gpiozero.pins.rpio.RPIOPin
PiGPIO
======
.. currentmodule:: gpiozero.pins.pigpio
.. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory
.. autoclass:: gpiozero.pins.pigpio.PiGPIOPin
Native
======
.. currentmodule:: gpiozero.pins.native
.. autoclass:: gpiozero.pins.native.NativeFactory
.. autoclass:: gpiozero.pins.native.NativePin
Mock
====
.. currentmodule:: gpiozero.pins.mock
.. autoclass:: gpiozero.pins.mock.MockFactory
:members:
.. autoclass:: gpiozero.pins.mock.MockPin
:members:
.. autoclass:: gpiozero.pins.mock.MockPWMPin
.. autoclass:: gpiozero.pins.mock.MockConnectedPin
.. autoclass:: gpiozero.pins.mock.MockChargingPin
.. autoclass:: gpiozero.pins.mock.MockTriggerPin

20
docs/api_utils.rst Normal file
View File

@@ -0,0 +1,20 @@
=========
Utilities
=========
.. currentmodule:: gpiozero
The GPIO Zero library also contains a database of information about the various
revisions of Raspberry Pi. This is used internally to raise warnings when
non-physical pins are used, or to raise exceptions when pull-downs are
requested on pins with physical pull-up resistors attached. The following
functions and classes can be used to query this database:
.. autofunction:: pi_info
.. autoclass:: PiBoardInfo
.. autoclass:: HeaderInfo
.. autoclass:: PinInfo

View File

@@ -1,9 +1,11 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from signal import pause
factory = PiGPIOFactory(host='192.168.1.3')
button = Button(2)
led = LED(PiGPIOPin(17, host='192.168.1.3'))
led = LED(17, pin_factory=factory)
led.source = button.values

View File

@@ -1,11 +1,14 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero.tools import all_values
from signal import pause
factory3 = PiGPIOFactory(host='192.168.1.3')
factory4 = PiGPIOFactory(host='192.168.1.4')
led = LED(17)
button_1 = Button(PiGPIOPin(17, host='192.168.1.3'))
button_2 = Button(PiGPIOPin(17, host='192.168.1.4'))
button_1 = Button(17, pin_factory=factory3)
button_2 = Button(17, pin_factory=factory4)
led.source = all_values(button_1.values, button_2.values)

View File

@@ -1,8 +1,9 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
led = LED(PiGPIOPin(17, host='192.168.1.3'))
factory = PiGPIOFactory(host='192.168.1.3')
led = LED(17, pin_factory=factory)
while True:
led.on()

View File

@@ -1,9 +1,11 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
led_1 = LED(PiGPIOPin(17, host='192.168.1.3'))
led_2 = LED(PiGPIOPin(17, host='192.168.1.4'))
factory3 = PiGPIOFactory(host='192.168.1.3')
factory4 = PiGPIOFactory(host='192.168.1.4')
led_1 = LED(17, pin_factory=factory3)
led_2 = LED(17, pin_factory=factory4)
while True:
led_1.on()

View File

@@ -1,9 +1,10 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
remote_factory = PiGPIOFactory(host='192.168.1.3')
led_1 = LED(17) # local pin
led_2 = LED(PiGPIOPin(17, host='192.168.1.3')) # remote pin
led_2 = LED(17, pin_factory=remote_factory) # remote pin
while True:
led_1.on()

View File

@@ -1,8 +1,9 @@
from gpiozero import LED
from gpiozero.pins.rpigpio import RPiGPIOPin
from gpiozero.pins.rpigpio import RPiGPIOFactory
from time import sleep
led_1 = LED(RPiGPIOPin(17)) # local pin
local_factory = RPiGPIOFactory()
led_1 = LED(17, pin_factory=local_factory) # local pin
led_2 = LED(17) # remote pin
while True:

View File

@@ -1,10 +1,13 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
factory3 = PiGPIOFactory(host='192.168.1.3')
factory4 = PiGPIOFactory(host='192.168.1.4')
led_1 = LED(17) # local pin
led_2 = LED(PiGPIOPin(17, host='192.168.1.3')) # remote pin on one pi
led_3 = LED(PiGPIOPin(17, host='192.168.1.4')) # remote pin on another pi
led_2 = LED(17, pin_factory=factory3) # remote pin on one pi
led_3 = LED(17, pin_factory=factory4) # remote pin on another pi
while True:
led_1.on()

View File

@@ -0,0 +1,28 @@
from gpiozero.pins.mock import MockFactory
from gpiozero import Device, Button, LED
from time import sleep
# Set the default pin factory to a mock factory
Device.pin_factory = MockFactory()
# Construct a couple of devices attached to mock pins 16 and 17, and link the
# devices
led = LED(17)
btn = Button(16)
led.source = btn.values
# Here the button isn't "pushed" so the LED's value should be False
print(led.value)
# Get a reference to mock pin 16 (used by the button)
btn_pin = Device.pin_factory.pin(16)
# Drive the pin low (this is what would happen eletrically when the button is
# pushed)
btn_pin.drive_low()
sleep(0.1) # give source some time to re-read the button state
print(led.value)
btn_pin.drive_high()
sleep(0.1)
print(led.value)

View File

@@ -1,8 +1,9 @@
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from signal import pause
led = LED(PiGPIOPin(17, host='raspberrypi.local'))
factory = PiGPIOFactory(host='raspberrypi.local')
led = LED(17, pin_factory=factory)
led.blink()

View File

@@ -1,8 +1,9 @@
from gpiozero import MotionSensor
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from sense_hat import SenseHat
pir = MotionSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor
remote_factory = PiGPIOFactory(host='192.198.1.4')
pir = MotionSensor(4, pin_factory=remote_factory) # remote motion sensor
sense = SenseHat() # local sense hat
while True:

View File

@@ -1,8 +1,9 @@
from gpiozero import LightSensor
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from sense_hat import SenseHat
light = LightSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor
remote_factory = PiGPIOFactory(host='192.168.1.4')
light = LightSensor(4, pin_factory=remote_factory) # remote motion sensor
sense = SenseHat() # local sense hat
blue = (0, 0, 255)

View File

@@ -3,5 +3,5 @@ from gpiozero import TrafficHat
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3'))
gpiozero.Device.pin_factory = PiGPIOFactory(host='192.168.1.3')
th = TrafficHat() # traffic hat on 192.168.1.3 using remote pins

View File

@@ -3,6 +3,7 @@ from gpiozero import TrafficHat
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
remote_factory = PiGPIOFactory(host='192.168.1.3')
th_1 = TrafficHat() # traffic hat using local pins
gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3'))
th_2 = TrafficHat() # traffic hat on 192.168.1.3 using remote pins
th_2 = TrafficHat(pin_factory=remote_factory) # traffic hat on 192.168.1.3 using remote pins

View File

@@ -17,6 +17,7 @@ Table of Contents
api_generic
api_tools
api_pins
api_utils
api_exc
cli_tools
source_values

View File

@@ -12,8 +12,8 @@ documentation page.
One of the pin libraries supported, `pigpio`_, provides the ability to control
GPIO pins remotely over the network, which means you can use GPIO Zero to
control devices connected to a Raspberry Pi on the network. You can do this from
another Raspberry Pi, or even from a PC.
control devices connected to a Raspberry Pi on the network. You can do this
from another Raspberry Pi, or even from a PC.
See the :doc:`recipes_remote_gpio` page for examples on how remote pins can be
used.
@@ -22,8 +22,8 @@ Preparing the Raspberry Pi
==========================
If you're using Raspbian Jessie (desktop - not Jessie Lite) then you have
everything you need to use the remote GPIO feature. If you're using Jessie Lite,
or another distribution, you'll need to install pigpio:
everything you need to use the remote GPIO feature. If you're using Jessie
Lite, or another distribution, you'll need to install pigpio:
.. code-block:: console
@@ -52,7 +52,9 @@ example:
$ sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only
You will need to launch the pigpio daemon every time you wish to use this
feature. To automate running the daemon at boot time::
feature. To automate running the daemon at boot time:
.. code-block:: console
$ sudo systemctl enable pigpiod
@@ -181,17 +183,18 @@ following:
If you are running this from a PC (not a Raspberry Pi) with gpiozero and the
pigpio Python library installed, this will work with no further configuration.
However, if you are running this from a Raspberry Pi, you will also need to
ensure the default pin factory is set to ``PiGPIOPin``. If ``RPi.GPIO`` is
installed, this will be selected as the default pin factory, so either uninstall
it, or use another environment variable to set it to ``PiGPIOPin``:
ensure the default pin factory is set to ``PiGPIOFactory``. If ``RPi.GPIO`` is
installed, this will be selected as the default pin factory, so either
uninstall it, or use another environment variable to set it to
``PiGPIOFactory``:
.. code-block:: console
$ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py
This usage will set the pin factory to :class:`PiGPIOPin` with a default host of
``192.168.1.3``. The pin factory can be changed inline in the code, as seen in
the following sections.
This usage will set the pin factory to :class:`PiGPIOFactory` with a default
host of ``192.168.1.3``. The pin factory can be changed inline in the code, as
seen in the following sections.
With this usage, you can write gpiozero code like you would on a Raspberry Pi,
with no modifications needed. For example:
@@ -218,9 +221,9 @@ Pin objects
===========
An alternative (or additional) method of configuring gpiozero objects to use
remote pins is to create instances of :class:PiGPIOPin objects, and
instantiating device objects with those pin objects, rather than just numbers.
For example, with no environment variables set:
remote pins is to create instances of :class:`PiGPIOFactory` objects, and use
them when instantiating device objects. For example, with no environment
variables set:
.. literalinclude:: examples/led_remote_1.py
@@ -230,8 +233,8 @@ This allows devices on multiple Raspberry Pis to be used in the same script:
You can, of course, continue to create gpiozero device objects as normal, and
create others using remote pins. For example, if run on a Raspberry Pi, the
following script will flash an LED on the host Pi, and also on another Pi on the
network:
following script will flash an LED on the host Pi, and also on another Pi on
the network:
.. literalinclude:: examples/led_remote_3.py
@@ -249,7 +252,8 @@ Note that these examples use the :class:`LED` class, which takes a ``pin``
argument to initialise. Some classes, particularly those representing HATs and
other add-on boards, do not require their pin numbers to be specified. However,
it is still possible to use remote pins with these devices, either using
environment variables, or by using :meth:`~Device._set_pin_factory`:
environment variables, :attr:`Device.pin_factory`, or the ``pin_factory``
keyword argument:
.. literalinclude:: examples/traffichat_remote_1.py
@@ -299,10 +303,10 @@ from the computer, referencing the host by its hostname, like so:
.. note::
When running code directly on a Raspberry Pi, any pin type can be used
When running code directly on a Raspberry Pi, any pin factory can be used
(assuming the relevant library is installed), but when a device is used
remotely, only :class:`PiGPIOPin` can be used, as pigpio is the only pin
library which supports remote GPIO.
remotely, only :class:`PiGPIOFactory` can be used, as pigpio is the only
pin library which supports remote GPIO.
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO

View File

@@ -448,7 +448,7 @@ def _default_pin_factory(name=os.getenv('GPIOZERO_PIN_FACTORY', None)):
except Exception as e:
warnings.warn(
PinFactoryFallback(
'Failed to load factory %s: %s' % (name, str(e))))
'Falling back from %s: %s' % (name, str(e))))
raise BadPinFactory('Unable to load any default pin factory!')
else:
for factory in pkg_resources.iter_entry_points(group, name.lower()):

View File

@@ -30,15 +30,9 @@ from ..exc import (
class Factory(object):
"""
Generates pins, SPI, and I2C interfaces for devices. This is an abstract
base class for pin factories. Descendents *must* override the following
methods:
* :meth:`_get_address`
* :meth:`pin_address`
Descendents *may* additionally override the following methods, if
applicable:
Generates pins and SPI interfaces for devices. This is an abstract
base class for pin factories. Descendents *may* override the following
methods, if applicable:
* :meth:`close`
* :meth:`reserve_pins`
@@ -129,9 +123,6 @@ class Factory(object):
"""
raise PinSPIUnsupported('SPI not supported by this pin factory')
def _get_address(self):
raise NotImplementedError
def _get_pi_info(self):
return None

View File

@@ -216,7 +216,7 @@ class MockChargingPin(MockPin):
class MockTriggerPin(MockPin):
"""
This derivative of :class:`MockPin` is intended to be used with another
:class:`MockPin` to emulate a distance sensor. Set :attr:`echo_pin` to the
:class:`MockPin` to emulate a distance sensor. Set *echo_pin* to the
corresponding pin instance. When this pin is driven high it will trigger
the echo pin to drive high for the echo time.
"""
@@ -410,6 +410,14 @@ class MockSPIDevice(object):
class MockFactory(LocalPiFactory):
"""
Factory for generating mock pins. The *revision* parameter specifies what
revision of Pi the mock factory pretends to be (this affects the result of
the :attr:`pi_info` attribute as well as where pull-ups are assumed to be).
The *pin_class* attribute specifies which mock pin class will be generated
by the :meth:`pin` method by default. This can be changed after
construction by modifying the :attr:`pin_class` attribute.
"""
def __init__(
self, revision=os.getenv('GPIOZERO_MOCK_REVISION', 'a02082'),
pin_class=os.getenv('GPIOZERO_MOCK_PIN_CLASS', MockPin)):
@@ -427,10 +435,22 @@ class MockFactory(LocalPiFactory):
return self._revision
def reset(self):
"""
Clears the pins and reservations sets. This is primarily useful in
test suites to ensure the pin factory is back in a "clean" state before
the next set of tests are run.
"""
self.pins.clear()
self._reservations.clear()
def pin(self, spec, pin_class=None, **kwargs):
"""
The pin method for :class:`MockFactory` additionally takes a *pin_class*
attribute which can be used to override the class' :attr:`pin_class`
attribute. Any additional keyword arguments will be passed along to the
pin constructor (useful with things like :class:`MockConnectedPin` which
expect to be constructed with another pin).
"""
if pin_class is None:
pin_class = self.pin_class
n = self._to_gpio(spec)

View File

@@ -161,10 +161,11 @@ class NativeFactory(LocalPiFactory):
You can construct native pin instances manually like so::
from gpiozero.pins.native import NativePin
from gpiozero.pins.native import NativeFactory
from gpiozero import LED
led = LED(NativePin(12))
factory = NativeFactory()
led = LED(12, pin_factory=factory)
"""
def __init__(self):
super(NativeFactory, self).__init__()
@@ -177,6 +178,9 @@ class NativeFactory(LocalPiFactory):
class NativePin(LocalPiPin):
"""
Native pin implementation. See :class:`NativeFactory` for more information.
"""
GPIO_FUNCTIONS = {
'input': 0b000,
'output': 0b001,

View File

@@ -238,11 +238,11 @@ class PiPin(Pin):
self._when_changed = None
self._number = number
try:
factory.pi_info.physical_pin('GPIO%d' % self.number)
factory.pi_info.physical_pin(repr(self))
except PinNoPins:
warnings.warn(
PinNonPhysical(
'no physical pins exist for GPIO%d' % self.number))
'no physical pins exist for %s' % repr(self)))
@property
def number(self):

View File

@@ -46,20 +46,21 @@ class PiGPIOFactory(PiFactory):
You can construct pigpio pins manually like so::
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero import LED
led = LED(PiGPIOPin(12))
factory = PiGPIOFactory()
led = LED(12, pin_factory=factory)
This is particularly useful for controlling pins on a remote machine. To
accomplish this simply specify the host (and optionally port) when
constructing the pin::
from gpiozero.pins.pigpio import PiGPIOPin
from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero import LED
from signal import pause
led = LED(PiGPIOPin(12, host='192.168.0.2'))
factory = PiGPIOFactory(host='192.168.0.2')
led = LED(12, pin_factory=factory)
.. note::
@@ -132,6 +133,12 @@ class PiGPIOFactory(PiFactory):
class PiGPIOPin(PiPin):
"""
Pin implementation for the `pigpio`_ library. See :class:`PiGPIOFactory`
for more information.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
_CONNECTIONS = {} # maps (host, port) to (connection, pi_info)
GPIO_FUNCTIONS = {
'input': pigpio.INPUT,
@@ -162,7 +169,7 @@ class PiGPIOPin(PiPin):
def __init__(self, factory, number):
super(PiGPIOPin, self).__init__(factory, number)
self._pull = 'up' if factory.pi_info.pulled_up(repr(self)) else 'floating'
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
self._pwm = False
self._bounce = None
self._callback = None
@@ -289,6 +296,12 @@ class PiGPIOPin(PiPin):
class PiGPIOHardwareSPI(SPI, Device):
"""
Hardware SPI implementation for the `pigpio`_ library. Uses the ``spi_*``
functions from the pigpio API.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
def __init__(self, factory, port, device):
self._port = port
self._device = device
@@ -385,6 +398,12 @@ class PiGPIOHardwareSPI(SPI, Device):
class PiGPIOSoftwareSPI(SPI, Device):
"""
Software SPI implementation for the `pigpio`_ library. Uses the ``bb_spi_*``
functions from the pigpio API.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
def __init__(self, factory, clock_pin, mosi_pin, miso_pin, select_pin):
self._closed = True
self._select_pin = select_pin

View File

@@ -40,7 +40,8 @@ class RPiGPIOFactory(LocalPiFactory):
from gpiozero.pins.rpigpio import RPiGPIOFactory
from gpiozero import LED
led = LED(RPiGPIOPin(12))
factory = RPiGPIOFactory()
led = LED(12, pin_factory=factory)
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
"""
@@ -57,6 +58,12 @@ class RPiGPIOFactory(LocalPiFactory):
class RPiGPIOPin(LocalPiPin):
"""
Pin implementation for the `RPi.GPIO`_ library. See :class:`RPiGPIOFactory`
for more information.
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
"""
GPIO_FUNCTIONS = {
'input': GPIO.IN,
'output': GPIO.OUT,
@@ -85,7 +92,7 @@ class RPiGPIOPin(LocalPiPin):
def __init__(self, factory, number):
super(RPiGPIOPin, self).__init__(factory, number)
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
self._pwm = None
self._frequency = None
self._duty_cycle = None
@@ -103,7 +110,7 @@ class RPiGPIOPin(LocalPiPin):
GPIO.setup(self.number, GPIO.OUT, initial=state)
def input_with_pull(self, pull):
if pull != 'up' and self.factory.pi_info.pulled_up(self.address[-1]):
if pull != 'up' and self.factory.pi_info.pulled_up(repr(self)):
raise PinFixedPull('%r has a physical pull-up resistor' % self)
try:
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[pull])
@@ -149,7 +156,7 @@ class RPiGPIOPin(LocalPiPin):
def _set_pull(self, value):
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]):
if value != 'up' and self.factory.pi_info.pulled_up(repr(self)):
raise PinFixedPull('%r has a physical pull-up resistor' % self)
try:
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[value])

View File

@@ -40,10 +40,11 @@ class RPIOFactory(LocalPiFactory):
You can construct RPIO pins manually like so::
from gpiozero.pins.rpio import RPIOPin
from gpiozero.pins.rpio import RPIOFactory
from gpiozero import LED
led = LED(RPIOPin(12))
factory = RPIOFactory()
led = LED(12, pin_factory=factory)
.. _RPIO: https://pythonhosted.org/RPIO/
"""
@@ -63,6 +64,12 @@ class RPIOFactory(LocalPiFactory):
class RPIOPin(LocalPiPin):
"""
Pin implementation for the `RPIO`_ library. See :class:`RPIOFactory` for
more information.
.. _RPIO: https://pythonhosted.org/RPIO/
"""
GPIO_FUNCTIONS = {
'input': RPIO.IN,
'output': RPIO.OUT,
@@ -80,7 +87,7 @@ class RPIOPin(LocalPiPin):
def __init__(self, factory, number):
super(RPIOPin, self).__init__(factory, number)
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
self._pwm = False
self._duty_cycle = None
self._bounce = None
@@ -138,7 +145,7 @@ class RPIOPin(LocalPiPin):
def _set_pull(self, value):
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]):
if value != 'up' and self.factory.pi_info.pulled_up(repr(self)):
raise PinFixedPull('%r has a physical pull-up resistor' % self)
try:
RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[value])