mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 09:40:36 +00:00
Add pin_factory param to all devices
And some docs ...
This commit is contained in:
@@ -16,35 +16,35 @@ everyday components. Components must be wired up correctly before use in code.
|
||||
Button
|
||||
======
|
||||
|
||||
.. autoclass:: Button(pin, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False)
|
||||
.. autoclass:: Button(pin, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None)
|
||||
:members: wait_for_press, wait_for_release, pin, is_pressed, is_held, hold_time, held_time, hold_repeat, pull_up, when_pressed, when_released, when_held
|
||||
|
||||
|
||||
Line Sensor (TRCT5000)
|
||||
======================
|
||||
|
||||
.. autoclass:: LineSensor(pin, queue_len=5, sample_rate=100, threshold=0.5, partial=False)
|
||||
.. autoclass:: LineSensor(pin, queue_len=5, sample_rate=100, threshold=0.5, partial=False, pin_factory=None)
|
||||
:members: wait_for_line, wait_for_no_line, pin, line_detected, when_line, when_no_line
|
||||
|
||||
|
||||
Motion Sensor (D-SUN PIR)
|
||||
=========================
|
||||
|
||||
.. autoclass:: MotionSensor(pin, queue_len=1, sample_rate=10, threshold=0.5, partial=False)
|
||||
.. autoclass:: MotionSensor(pin, queue_len=1, sample_rate=10, threshold=0.5, partial=False, pin_factory=None)
|
||||
:members: wait_for_motion, wait_for_no_motion, pin, motion_detected, when_motion, when_no_motion
|
||||
|
||||
|
||||
Light Sensor (LDR)
|
||||
==================
|
||||
|
||||
.. autoclass:: LightSensor(pin, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False)
|
||||
.. autoclass:: LightSensor(pin, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False, pin_factory=None)
|
||||
:members: wait_for_light, wait_for_dark, pin, light_detected, when_light, when_dark
|
||||
|
||||
|
||||
Distance Sensor (HC-SR04)
|
||||
=========================
|
||||
|
||||
.. autoclass:: DistanceSensor(echo, trigger, queue_len=30, max_distance=1, threshold_distance=0.3, partial=False)
|
||||
.. autoclass:: DistanceSensor(echo, trigger, queue_len=30, max_distance=1, threshold_distance=0.3, partial=False, pin_factory=None)
|
||||
:members: wait_for_in_range, wait_for_out_of_range, trigger, echo, when_in_range, when_out_of_range, max_distance, distance, threshold_distance
|
||||
|
||||
Base Classes
|
||||
@@ -63,7 +63,7 @@ to construct classes for their own devices.
|
||||
DigitalInputDevice
|
||||
==================
|
||||
|
||||
.. autoclass:: DigitalInputDevice(pin, pull_up=False, bounce_time=None)
|
||||
.. autoclass:: DigitalInputDevice(pin, pull_up=False, bounce_time=None, pin_factory=None)
|
||||
:members:
|
||||
|
||||
SmoothedInputDevice
|
||||
@@ -75,12 +75,12 @@ SmoothedInputDevice
|
||||
InputDevice
|
||||
===========
|
||||
|
||||
.. autoclass:: InputDevice(pin, pull_up=False)
|
||||
.. autoclass:: InputDevice(pin, pull_up=False, pin_factory=None)
|
||||
:members:
|
||||
|
||||
GPIODevice
|
||||
==========
|
||||
|
||||
.. autoclass:: GPIODevice(pin)
|
||||
.. autoclass:: GPIODevice(pin, pin_factory=None)
|
||||
:members:
|
||||
|
||||
|
||||
@@ -11,10 +11,23 @@ are concerned with. However, some users may wish to take advantage of the
|
||||
capabilities of alternative GPIO implementations or (in future) use GPIO
|
||||
extender chips. This is the purpose of the pins portion of the library.
|
||||
|
||||
When you construct a device, you pass in a pin specification. However, what the
|
||||
library actually expects is a :class:`Pin` implementation. If it finds anything
|
||||
else, it uses the existing ``Device.pin_factory`` to construct a :class:`Pin`
|
||||
implementation based on the specification.
|
||||
When you construct a device, you pass in a pin specification. This is passed to
|
||||
a pin :class:`Factory` which turns it into a :class:`Pin` implementation. The
|
||||
default factory can be queried (and changed) with ``Device.pin_factory``, i.e.
|
||||
the ``pin_factory`` attribute of the :class:`Device` class. However, all
|
||||
classes accept a ``pin_factory`` keyword argument to their constructors
|
||||
permitting the factory to be overridden on a per-device basis (the reason for
|
||||
allowing per-device factories is made apparent later in the :doc:`remote_gpio`
|
||||
chapter).
|
||||
|
||||
This is illustrated in the following flow-chart:
|
||||
|
||||
.. image:: images/device_pin_flowchart.*
|
||||
|
||||
The default factory is constructed when GPIO Zero is first imported; if no
|
||||
default factory can be constructed (e.g. because no GPIO implementations are
|
||||
installed, or all of them fail to load for whatever reason), an
|
||||
:exc:`ImportError` will be raised.
|
||||
|
||||
Changing the pin factory
|
||||
========================
|
||||
@@ -24,7 +37,7 @@ The default pin factory can be replaced by specifying a value for the
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
pi@raspberrypi $ GPIOZERO_PIN_FACTORY=native python
|
||||
$ GPIOZERO_PIN_FACTORY=native python
|
||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||
[GCC 4.9.1] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
@@ -37,8 +50,8 @@ export this value:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
pi@raspberrypi $ export GPIOZERO_PIN_FACTORY=native
|
||||
pi@raspberrypi $ python
|
||||
$ export GPIOZERO_PIN_FACTORY=native
|
||||
$ python
|
||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||
[GCC 4.9.1] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
@@ -46,7 +59,7 @@ export this value:
|
||||
>>> gpiozero.Device.pin_factory
|
||||
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
|
||||
>>> quit()
|
||||
pi@raspberrypi $ python
|
||||
$ python
|
||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||
[GCC 4.9.1] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
@@ -73,17 +86,30 @@ they are tried by default.
|
||||
| native | :class:`gpiozero.pins.native.NativeFactory` | :class:`gpiozero.pins.native.NativePin` |
|
||||
+---------+-----------------------------------------------+-------------------------------------------+
|
||||
|
||||
If you need to change the default pin factory from within a script, set
|
||||
If you need to change the default pin factory from within a script, either set
|
||||
``Device.pin_factory`` to the new factory instance to use::
|
||||
|
||||
from gpiozero.pins.native import NativeFactory
|
||||
from gpiozero import *
|
||||
from gpiozero import Device, LED
|
||||
|
||||
Device.pin_factory = NativeFactory()
|
||||
|
||||
# These will now implicitly use NativePin instead of
|
||||
# RPiGPIOPin
|
||||
led1 = LED(16)
|
||||
led2 = LED(17)
|
||||
|
||||
Or use the ``pin_factory`` keyword parameter mentioned above::
|
||||
|
||||
from gpiozero.pins.native import NativeFactory
|
||||
from gpiozero import LED
|
||||
|
||||
# This will now use NativePin instead of RPiGPIOPin
|
||||
led = LED(16)
|
||||
my_factory = NativeFactory()
|
||||
|
||||
# This will use NativePin instead of RPiGPIOPin for led1
|
||||
# but led2 will continue to use RPiGPIOPin
|
||||
led1 = LED(16, pin_factory=my_factory)
|
||||
led2 = LED(17)
|
||||
|
||||
Certain factories may take default information from additional sources.
|
||||
For example, to default to creating pins with
|
||||
@@ -100,11 +126,13 @@ 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 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.
|
||||
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.
|
||||
|
||||
Sensible uses of multiple pin factories are given in :doc:`remote_gpio`.
|
||||
|
||||
|
||||
RPi.GPIO
|
||||
|
||||
19
docs/images/device_pin_flowchart.dot
Normal file
19
docs/images/device_pin_flowchart.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
/* vim: set et sw=4 sts=4: */
|
||||
|
||||
digraph device_pins {
|
||||
graph [rankdir=TB];
|
||||
node [shape=rect, shape=filled, fontname=Sans, fontsize=10];
|
||||
edge [fontname=Sans, fontsize=10];
|
||||
|
||||
constructor [label="LED(pin_spec, ...,\npin_factory=None)"];
|
||||
pin_factory_kwarg [shape=diamond,label="pin_factory == None?"];
|
||||
default_factory [label="self.pin_factory = Device.pin_factory"];
|
||||
override_factory [label="self.pin_factory = pin_factory"];
|
||||
factory_pin [label="self.pin = self.pin_factory.pin(pin_spec)"];
|
||||
|
||||
constructor->pin_factory_kwarg;
|
||||
pin_factory_kwarg->default_factory [label="yes"];
|
||||
pin_factory_kwarg->override_factory [label="no"];
|
||||
default_factory->factory_pin;
|
||||
override_factory->factory_pin;
|
||||
}
|
||||
BIN
docs/images/device_pin_flowchart.pdf
Normal file
BIN
docs/images/device_pin_flowchart.pdf
Normal file
Binary file not shown.
BIN
docs/images/device_pin_flowchart.png
Normal file
BIN
docs/images/device_pin_flowchart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
66
docs/images/device_pin_flowchart.svg
Normal file
66
docs/images/device_pin_flowchart.svg
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
||||
-->
|
||||
<!-- Title: device_pins Pages: 1 -->
|
||||
<svg width="372pt" height="273pt"
|
||||
viewBox="0.00 0.00 371.50 273.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 269)">
|
||||
<title>device_pins</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-269 367.5,-269 367.5,4 -4,4"/>
|
||||
<!-- constructor -->
|
||||
<g id="node1" class="node"><title>constructor</title>
|
||||
<polygon fill="none" stroke="black" points="243.5,-265 136.5,-265 136.5,-229 243.5,-229 243.5,-265"/>
|
||||
<text text-anchor="middle" x="190" y="-250" font-family="Sans" font-size="10.00">LED(pin_spec, ...,</text>
|
||||
<text text-anchor="middle" x="190" y="-239" font-family="Sans" font-size="10.00">pin_factory=None)</text>
|
||||
</g>
|
||||
<!-- pin_factory_kwarg -->
|
||||
<g id="node2" class="node"><title>pin_factory_kwarg</title>
|
||||
<polygon fill="none" stroke="black" points="190,-192 88.3711,-174 190,-156 291.629,-174 190,-192"/>
|
||||
<text text-anchor="middle" x="190" y="-171.5" font-family="Sans" font-size="10.00">pin_factory == None?</text>
|
||||
</g>
|
||||
<!-- constructor->pin_factory_kwarg -->
|
||||
<g id="edge1" class="edge"><title>constructor->pin_factory_kwarg</title>
|
||||
<path fill="none" stroke="black" d="M190,-228.813C190,-220.789 190,-211.047 190,-202.069"/>
|
||||
<polygon fill="black" stroke="black" points="193.5,-202.029 190,-192.029 186.5,-202.029 193.5,-202.029"/>
|
||||
</g>
|
||||
<!-- default_factory -->
|
||||
<g id="node3" class="node"><title>default_factory</title>
|
||||
<polygon fill="none" stroke="black" points="190,-109 0,-109 0,-73 190,-73 190,-109"/>
|
||||
<text text-anchor="middle" x="95" y="-88.5" font-family="Sans" font-size="10.00">self.pin_factory = Device.pin_factory</text>
|
||||
</g>
|
||||
<!-- pin_factory_kwarg->default_factory -->
|
||||
<g id="edge2" class="edge"><title>pin_factory_kwarg->default_factory</title>
|
||||
<path fill="none" stroke="black" d="M173.452,-158.891C159.473,-146.971 139.158,-129.65 122.703,-115.621"/>
|
||||
<polygon fill="black" stroke="black" points="124.861,-112.861 114.98,-109.036 120.319,-118.187 124.861,-112.861"/>
|
||||
<text text-anchor="middle" x="157.5" y="-130" font-family="Sans" font-size="10.00">yes</text>
|
||||
</g>
|
||||
<!-- override_factory -->
|
||||
<g id="node4" class="node"><title>override_factory</title>
|
||||
<polygon fill="none" stroke="black" points="363.5,-109 208.5,-109 208.5,-73 363.5,-73 363.5,-109"/>
|
||||
<text text-anchor="middle" x="286" y="-88.5" font-family="Sans" font-size="10.00">self.pin_factory = pin_factory</text>
|
||||
</g>
|
||||
<!-- pin_factory_kwarg->override_factory -->
|
||||
<g id="edge3" class="edge"><title>pin_factory_kwarg->override_factory</title>
|
||||
<path fill="none" stroke="black" d="M206.722,-158.891C220.849,-146.971 241.377,-129.65 258.005,-115.621"/>
|
||||
<polygon fill="black" stroke="black" points="260.424,-118.16 265.809,-109.036 255.909,-112.81 260.424,-118.16"/>
|
||||
<text text-anchor="middle" x="250.5" y="-130" font-family="Sans" font-size="10.00">no</text>
|
||||
</g>
|
||||
<!-- factory_pin -->
|
||||
<g id="node5" class="node"><title>factory_pin</title>
|
||||
<polygon fill="none" stroke="black" points="311,-36 111,-36 111,-0 311,-0 311,-36"/>
|
||||
<text text-anchor="middle" x="211" y="-15.5" font-family="Sans" font-size="10.00">self.pin = self.pin_factory.pin(pin_spec)</text>
|
||||
</g>
|
||||
<!-- default_factory->factory_pin -->
|
||||
<g id="edge4" class="edge"><title>default_factory->factory_pin</title>
|
||||
<path fill="none" stroke="black" d="M122.785,-72.9937C138.167,-63.5785 157.484,-51.7554 174.117,-41.5748"/>
|
||||
<polygon fill="black" stroke="black" points="176.338,-44.3193 183.04,-36.1136 172.683,-38.3489 176.338,-44.3193"/>
|
||||
</g>
|
||||
<!-- override_factory->factory_pin -->
|
||||
<g id="edge5" class="edge"><title>override_factory->factory_pin</title>
|
||||
<path fill="none" stroke="black" d="M267.845,-72.8129C258.448,-63.9174 246.82,-52.9094 236.533,-43.1717"/>
|
||||
<polygon fill="black" stroke="black" points="238.656,-40.3619 228.988,-36.0288 233.844,-45.4454 238.656,-40.3619"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 36 KiB |
@@ -9,42 +9,58 @@ operating systems, including for PCs using the :doc:`remote_gpio` feature.
|
||||
Raspberry Pi
|
||||
============
|
||||
|
||||
First, update your repositories list::
|
||||
First, update your repositories list:
|
||||
|
||||
sudo apt update
|
||||
.. code-block:: console
|
||||
|
||||
Then install the package for Python 3::
|
||||
pi@raspberrypi:~$ sudo apt update
|
||||
|
||||
sudo apt install python3-gpiozero
|
||||
Then install the package for Python 3:
|
||||
|
||||
or Python 2::
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt install python-gpiozero
|
||||
pi@raspberrypi:~$ sudo apt install python3-gpiozero
|
||||
|
||||
or Python 2:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
pi@raspberrypi:~$ sudo apt install python-gpiozero
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
First, update your distribution's repositories list. For example::
|
||||
First, update your distribution's repositories list. For example:
|
||||
|
||||
sudo apt update
|
||||
.. code-block:: console
|
||||
|
||||
Then install pip for Python 3::
|
||||
$ sudo apt update
|
||||
|
||||
sudo apt install python3-pip
|
||||
Then install pip for Python 3:
|
||||
|
||||
or Python 3::
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt install python-pip
|
||||
$ sudo apt install python3-pip
|
||||
|
||||
or Python 3:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo apt install python-pip
|
||||
|
||||
(Alternatively, install pip with `get-pip`_.)
|
||||
|
||||
Next, install gpiozero for Python 3::
|
||||
Next, install gpiozero for Python 3:
|
||||
|
||||
sudo pip3 install gpiozero
|
||||
.. code-block:: console
|
||||
|
||||
or Python 2::
|
||||
$ sudo pip3 install gpiozero
|
||||
|
||||
sudo pip install gpiozero
|
||||
or Python 2:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pip install gpiozero
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -55,24 +71,32 @@ or Python 2::
|
||||
Mac OS
|
||||
======
|
||||
|
||||
First, install pip::
|
||||
First, install pip:
|
||||
|
||||
???
|
||||
.. code-block:: console
|
||||
|
||||
Next, install gpiozero with pip::
|
||||
$ ???
|
||||
|
||||
pip install gpiozero
|
||||
Next, install gpiozero with pip:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install gpiozero
|
||||
|
||||
Windows
|
||||
=======
|
||||
|
||||
First, install pip::
|
||||
First, install pip:
|
||||
|
||||
???
|
||||
.. code-block:: doscon
|
||||
|
||||
Next, install gpiozero with pip::
|
||||
C:\Users\user1> ???
|
||||
|
||||
pip install gpiozero
|
||||
Next, install gpiozero with pip:
|
||||
|
||||
.. code-block:: doscon
|
||||
|
||||
C:\Users\user1> pip install gpiozero
|
||||
|
||||
|
||||
.. _Raspbian Jessie: https://www.raspberrypi.org/downloads/raspbian/
|
||||
|
||||
@@ -102,4 +102,4 @@ the ``pip`` utility. This can be done with the following command in Raspbian:
|
||||
Alternatively, install pip with `get-pip`_.
|
||||
|
||||
|
||||
.. _get_pip: https://pip.pypa.io/en/stable/installing/
|
||||
.. _get-pip: https://pip.pypa.io/en/stable/installing/
|
||||
|
||||
@@ -36,7 +36,9 @@ functionality without the need to wire up your own LEDs (also useful because
|
||||
the power and activity LEDs are "known good").
|
||||
|
||||
Firstly you need to disable the usual triggers for the built-in LEDs. This can
|
||||
be done from the terminal with the following commands::
|
||||
be done from the terminal with the following commands:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo none | sudo tee /sys/class/leds/led0/trigger
|
||||
$ echo gpio | sudo tee /sys/class/leds/led1/trigger
|
||||
@@ -46,7 +48,9 @@ Now you can control the LEDs with gpiozero like so:
|
||||
.. literalinclude:: examples/led_builtin.py
|
||||
|
||||
To revert the LEDs to their usual purpose you can either reboot your Pi or
|
||||
run the following commands::
|
||||
run the following commands:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo mmc0 | sudo tee /sys/class/leds/led0/trigger
|
||||
$ echo input | sudo tee /sys/class/leds/led1/trigger
|
||||
|
||||
@@ -7,7 +7,7 @@ Remote GPIO
|
||||
GPIO Zero supports a number of different pin implementations (low-level pin
|
||||
libraries which deal with the GPIO pins directly). By default, the `RPi.GPIO`_
|
||||
library is used (assuming it is installed on your system), but you can
|
||||
optionally specify one to use. For more information, see the :doc:`pins`
|
||||
optionally specify one to use. For more information, see the :doc:`api_pins`
|
||||
documentation page.
|
||||
|
||||
One of the pin libraries supported, `pigpio`_, provides the ability to control
|
||||
@@ -23,9 +23,11 @@ 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::
|
||||
or another distribution, you'll need to install pigpio:
|
||||
|
||||
sudo apt install pigpio
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo apt install pigpio
|
||||
|
||||
Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration
|
||||
tool:
|
||||
@@ -34,21 +36,25 @@ tool:
|
||||
|
||||
(Alternatively, use ``sudo raspi-config`` on the command line)
|
||||
|
||||
Then launch the pigpio daemon::
|
||||
Then launch the pigpio daemon:
|
||||
|
||||
sudo pigpiod
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pigpiod
|
||||
|
||||
To only allow connections from a specific IP address, use the ``-n`` flag. For
|
||||
example::
|
||||
example:
|
||||
|
||||
sudo pigpiod -n localhost # allow localhost only
|
||||
sudo pigpiod -n 192.168.1.65 # allow 192.168.1.65 only
|
||||
sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pigpiod -n localhost # allow localhost only
|
||||
$ sudo pigpiod -n 192.168.1.65 # allow 192.168.1.65 only
|
||||
$ 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::
|
||||
|
||||
sudo systemctl enable pigpiod
|
||||
$ sudo systemctl enable pigpiod
|
||||
|
||||
Preparing the host computer
|
||||
===========================
|
||||
@@ -61,72 +67,100 @@ Python library on the PC.
|
||||
Raspberry Pi
|
||||
------------
|
||||
|
||||
First, update your repositories list::
|
||||
First, update your repositories list:
|
||||
|
||||
sudo apt update
|
||||
.. code-block:: console
|
||||
|
||||
Then install the pigpio library for Python 3::
|
||||
$ sudo apt update
|
||||
|
||||
sudo apt install python3-pigpio
|
||||
Then install the pigpio library for Python 3:
|
||||
|
||||
or Python 2::
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt install python-pigpio
|
||||
$ sudo apt install python3-pigpio
|
||||
|
||||
Alternatively, install with pip::
|
||||
or Python 2:
|
||||
|
||||
sudo pip3 install pigpio
|
||||
.. code-block:: console
|
||||
|
||||
or::
|
||||
$ sudo apt install python-pigpio
|
||||
|
||||
sudo pip install pigpio
|
||||
Alternatively, install with pip:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pip3 install pigpio
|
||||
|
||||
or:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pip install pigpio
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
First, update your distribution's repositories list. For example::
|
||||
First, update your distribution's repositories list. For example:
|
||||
|
||||
sudo apt update
|
||||
.. code-block:: console
|
||||
|
||||
Then install pip for Python 3::
|
||||
$ sudo apt update
|
||||
|
||||
sudo apt install python3-pip
|
||||
Then install pip for Python 3:
|
||||
|
||||
or Python 2::
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt install python-pip
|
||||
$ sudo apt install python3-pip
|
||||
|
||||
or Python 2:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo apt install python-pip
|
||||
|
||||
(Alternatively, install pip with `get-pip`_.)
|
||||
|
||||
Next, install pigpio for Python 3::
|
||||
Next, install pigpio for Python 3:
|
||||
|
||||
sudo pip3 install pigpio
|
||||
.. code-block:: console
|
||||
|
||||
or Python 2::
|
||||
$ sudo pip3 install pigpio
|
||||
|
||||
sudo pip install pigpio
|
||||
or Python 2:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo pip install pigpio
|
||||
|
||||
Mac OS
|
||||
------
|
||||
|
||||
First, install pip::
|
||||
First, install pip:
|
||||
|
||||
???
|
||||
.. code-block:: console
|
||||
|
||||
Next, install pigpio with pip::
|
||||
$ ???
|
||||
|
||||
pip install pigpio
|
||||
Next, install pigpio with pip:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install pigpio
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
First install pip::
|
||||
First install pip:
|
||||
|
||||
???
|
||||
.. code-block:: doscon
|
||||
|
||||
Next, install pigpio with pip::
|
||||
C:\Users\user1> ???
|
||||
|
||||
pip install pigpio
|
||||
Next, install pigpio with pip:
|
||||
|
||||
.. code-block:: doscon
|
||||
|
||||
C:\Users\user1> pip install pigpio
|
||||
|
||||
Environment variables
|
||||
=====================
|
||||
@@ -135,7 +169,9 @@ The simplest way to use devices with remote pins is to set the ``PIGPIO_ADDR``
|
||||
environment variable to the IP address of the desired Raspberry Pi. You must
|
||||
run your Python script or launch your development environment with the
|
||||
environment variable set using the command line. For example, one of the
|
||||
following::
|
||||
following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
||||
$ PIGPIO_ADDR=192.168.1.3 python3
|
||||
@@ -147,7 +183,9 @@ 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``::
|
||||
it, or use another environment variable to set it to ``PiGPIOPin``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
||||
|
||||
@@ -160,12 +198,16 @@ with no modifications needed. For example:
|
||||
|
||||
.. literalinclude:: examples/led_1.py
|
||||
|
||||
When run with::
|
||||
When run with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ PIGPIO_ADDR=192.168.1.3 python3 led.py
|
||||
|
||||
will flash the LED connected to pin 17 of the Raspberry Pi with the IP address
|
||||
``192.168.1.3``. And::
|
||||
``192.168.1.3``. And:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ PIGPIO_ADDR=192.168.1.4 python3 led.py
|
||||
|
||||
@@ -236,11 +278,13 @@ computer using remote pins.
|
||||
First, configure the boot partition of the SD card:
|
||||
|
||||
1. Edit ``config.txt`` and add ``dtoverlay=dwc2`` on a new line, then save the
|
||||
file.
|
||||
file.
|
||||
|
||||
2. Create an empty file called ``ssh`` (no file extension) and save it in the
|
||||
boot partition.
|
||||
boot partition.
|
||||
|
||||
3. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after
|
||||
``rootwait``.
|
||||
``rootwait``.
|
||||
|
||||
(See `blog.gbaman.info`_ for more information)
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@ class CompositeOutputDevice(SourceMixin, CompositeDevice):
|
||||
specific order). All keyword arguments *must* be included in the
|
||||
collection. If omitted, an alphabetically sorted order will be selected
|
||||
for keyword arguments.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
|
||||
def on(self):
|
||||
@@ -124,6 +128,10 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
||||
executed once per hold. This parameter can only be specified as a
|
||||
keyword parameter.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
:param \*\*named_pins:
|
||||
Specify GPIO pins that buttons of the board are attached to,
|
||||
associating each button with a property name. You can designate as
|
||||
@@ -135,6 +143,7 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
||||
bounce_time = kwargs.pop('bounce_time', None)
|
||||
hold_time = kwargs.pop('hold_time', 1)
|
||||
hold_repeat = kwargs.pop('hold_repeat', False)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
order = kwargs.pop('_order', None)
|
||||
super(ButtonBoard, self).__init__(
|
||||
*(
|
||||
@@ -142,6 +151,7 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
||||
for pin in args
|
||||
),
|
||||
_order=order,
|
||||
pin_factory=pin_factory,
|
||||
**{
|
||||
name: Button(pin, pull_up, bounce_time, hold_time, hold_repeat)
|
||||
for name, pin in kwargs.items()
|
||||
@@ -209,20 +219,28 @@ class LEDCollection(CompositeOutputDevice):
|
||||
pwm = kwargs.pop('pwm', False)
|
||||
active_high = kwargs.pop('active_high', True)
|
||||
initial_value = kwargs.pop('initial_value', False)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
order = kwargs.pop('_order', None)
|
||||
LEDClass = PWMLED if pwm else LED
|
||||
super(LEDCollection, self).__init__(
|
||||
*(
|
||||
pin_or_collection
|
||||
if isinstance(pin_or_collection, LEDCollection) else
|
||||
LEDClass(pin_or_collection, active_high, initial_value)
|
||||
LEDClass(
|
||||
pin_or_collection, active_high, initial_value,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
for pin_or_collection in args
|
||||
),
|
||||
_order=order,
|
||||
pin_factory=pin_factory,
|
||||
**{
|
||||
name: pin_or_collection
|
||||
if isinstance(pin_or_collection, LEDCollection) else
|
||||
LEDClass(pin_or_collection, active_high, initial_value)
|
||||
LEDClass(
|
||||
pin_or_collection, active_high, initial_value,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
for name, pin_or_collection in kwargs.items()
|
||||
})
|
||||
leds = []
|
||||
@@ -283,6 +301,10 @@ class LEDBoard(LEDCollection):
|
||||
the device will be switched on initially. This parameter can only be
|
||||
specified as a keyword parameter.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
:param \*\*named_pins:
|
||||
Specify GPIO pins that LEDs of the board are attached to, associating
|
||||
each LED with a property name. You can designate as many pins as
|
||||
@@ -486,6 +508,10 @@ class LEDBarGraph(LEDCollection):
|
||||
The initial :attr:`value` of the graph given as a float between -1 and
|
||||
+1. Defaults to ``0.0``. This parameter can only be specified as a
|
||||
keyword parameter.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
|
||||
def __init__(self, *pins, **kwargs):
|
||||
@@ -495,9 +521,12 @@ class LEDBarGraph(LEDCollection):
|
||||
pwm = kwargs.pop('pwm', False)
|
||||
active_high = kwargs.pop('active_high', True)
|
||||
initial_value = kwargs.pop('initial_value', 0.0)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
if kwargs:
|
||||
raise TypeError('unexpected keyword argument: %s' % kwargs.popitem()[0])
|
||||
super(LEDBarGraph, self).__init__(*pins, pwm=pwm, active_high=active_high)
|
||||
super(LEDBarGraph, self).__init__(
|
||||
*pins, pwm=pwm, active_high=active_high, pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self.value = initial_value
|
||||
except:
|
||||
@@ -572,12 +601,17 @@ class LedBorg(RGBLED):
|
||||
each component of the LedBorg. If ``False``, construct regular
|
||||
:class:`LED` instances, which prevents smooth color graduations.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _PiBorg LedBorg: https://www.piborg.org/ledborg
|
||||
"""
|
||||
|
||||
def __init__(self, initial_value=(0, 0, 0), pwm=True):
|
||||
def __init__(self, initial_value=(0, 0, 0), pwm=True, pin_factory=None):
|
||||
super(LedBorg, self).__init__(red=17, green=27, blue=22,
|
||||
pwm=pwm, initial_value=initial_value)
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
pin_factory=pin_factory)
|
||||
|
||||
|
||||
class PiLiter(LEDBoard):
|
||||
@@ -604,12 +638,17 @@ class PiLiter(LEDBoard):
|
||||
in when configured for output (warning: this can be on). If ``True``,
|
||||
the device will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
||||
"""
|
||||
|
||||
def __init__(self, pwm=False, initial_value=False):
|
||||
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||
super(PiLiter, self).__init__(4, 17, 27, 18, 22, 23, 24, 25,
|
||||
pwm=pwm, initial_value=initial_value)
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
pin_factory=pin_factory)
|
||||
|
||||
|
||||
class PiLiterBarGraph(LEDBarGraph):
|
||||
@@ -634,13 +673,18 @@ class PiLiterBarGraph(LEDBarGraph):
|
||||
The initial :attr:`value` of the graph given as a float between -1 and
|
||||
+1. Defaults to ``0.0``.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
||||
"""
|
||||
|
||||
def __init__(self, pwm=False, initial_value=0.0):
|
||||
def __init__(self, pwm=False, initial_value=0.0, pin_factory=None):
|
||||
pins = (4, 17, 27, 18, 22, 23, 24, 25)
|
||||
super(PiLiterBarGraph, self).__init__(*pins,
|
||||
pwm=pwm, initial_value=initial_value)
|
||||
super(PiLiterBarGraph, self).__init__(
|
||||
*pins, pwm=pwm, initial_value=initial_value, pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class TrafficLights(LEDBoard):
|
||||
@@ -680,9 +724,14 @@ class TrafficLights(LEDBoard):
|
||||
The GPIO pin that the yellow LED is attached to. This is merely an
|
||||
alias for the ``amber`` parameter - you can't specify both ``amber``
|
||||
and ``yellow``.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, red=None, amber=None, green=None,
|
||||
pwm=False, initial_value=False, yellow=None):
|
||||
pwm=False, initial_value=False, yellow=None,
|
||||
pin_factory=None):
|
||||
if amber is not None and yellow is not None:
|
||||
raise OutputDeviceBadValue(
|
||||
'Only one of amber or yellow can be specified'
|
||||
@@ -700,7 +749,7 @@ class TrafficLights(LEDBoard):
|
||||
)
|
||||
super(TrafficLights, self).__init__(
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
_order=devices.keys(),
|
||||
_order=devices.keys(), pin_factory=pin_factory,
|
||||
**devices)
|
||||
|
||||
def __getattr__(self, name):
|
||||
@@ -739,11 +788,16 @@ class PiTraffic(TrafficLights):
|
||||
in when configured for output (warning: this can be on). If ``True``,
|
||||
the device will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Low Voltage Labs PI-TRAFFIC: http://lowvoltagelabs.com/products/pi-traffic/
|
||||
"""
|
||||
def __init__(self, pwm=False, initial_value=False):
|
||||
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||
super(PiTraffic, self).__init__(9, 10, 11,
|
||||
pwm=pwm, initial_value=initial_value)
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
pin_factory=pin_factory)
|
||||
|
||||
|
||||
class PiStop(TrafficLights):
|
||||
@@ -774,6 +828,10 @@ class PiStop(TrafficLights):
|
||||
in when configured for output (warning: this can be on). If ``True``,
|
||||
the device will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _PiHardware Pi-Stop: https://pihw.wordpress.com/meltwaters-pi-hardware-kits/pi-stop/
|
||||
.. _location: https://github.com/PiHw/Pi-Stop/blob/master/markdown_source/markdown/Discover-PiStop.md
|
||||
"""
|
||||
@@ -786,13 +844,17 @@ class PiStop(TrafficLights):
|
||||
'D': (2, 3, 4),
|
||||
}
|
||||
|
||||
def __init__(self, location=None, pwm=False, initial_value=False):
|
||||
def __init__(
|
||||
self, location=None, pwm=False, initial_value=False,
|
||||
pin_factory=None):
|
||||
gpios = self.LOCATIONS.get(location, None)
|
||||
if gpios is None:
|
||||
raise ValueError('location must be one of: %s' %
|
||||
', '.join(sorted(self.LOCATIONS.keys())))
|
||||
super(PiStop, self).__init__(*gpios,
|
||||
pwm=pwm, initial_value=initial_value)
|
||||
super(PiStop, self).__init__(
|
||||
*gpios, pwm=pwm, initial_value=initial_value,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class StatusZero(LEDBoard):
|
||||
@@ -817,6 +879,10 @@ class StatusZero(LEDBoard):
|
||||
not all strips are given labels, any remaining strips will not be
|
||||
initialised.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _STATUS Zero: https://thepihut.com/statuszero
|
||||
"""
|
||||
default_labels = ('one', 'two', 'three')
|
||||
@@ -827,6 +893,7 @@ class StatusZero(LEDBoard):
|
||||
(22, 27),
|
||||
(9, 10),
|
||||
)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
if len(labels) == 0:
|
||||
labels = self.default_labels
|
||||
elif len(labels) > len(pins):
|
||||
@@ -834,10 +901,15 @@ class StatusZero(LEDBoard):
|
||||
dup, count = Counter(labels).most_common(1)[0]
|
||||
if count > 1:
|
||||
raise ValueError("Duplicate label %s" % dup)
|
||||
super(StatusZero, self).__init__(_order=labels, **{
|
||||
label: LEDBoard(red=red, green=green, _order=('red', 'green'), **kwargs)
|
||||
for (green, red), label in zip(pins, labels)
|
||||
})
|
||||
super(StatusZero, self).__init__(
|
||||
_order=labels, pin_factory=pin_factory, **{
|
||||
label: LEDBoard(
|
||||
red=red, green=green, _order=('red', 'green'),
|
||||
pin_factory=pin_factory, **kwargs
|
||||
)
|
||||
for (green, red), label in zip(pins, labels)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class StatusBoard(CompositeOutputDevice):
|
||||
@@ -862,6 +934,10 @@ class StatusBoard(CompositeOutputDevice):
|
||||
will be initialised with names 'one' to 'five'. If some, but not all
|
||||
strips are given labels, any remaining strips will not be initialised.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _STATUS: https://thepihut.com/status
|
||||
"""
|
||||
default_labels = ('one', 'two', 'three', 'four', 'five')
|
||||
@@ -874,6 +950,7 @@ class StatusBoard(CompositeOutputDevice):
|
||||
(5, 11, 26),
|
||||
(13, 6, 18),
|
||||
)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
if len(labels) == 0:
|
||||
labels = self.default_labels
|
||||
elif len(labels) > len(pins):
|
||||
@@ -881,14 +958,18 @@ class StatusBoard(CompositeOutputDevice):
|
||||
dup, count = Counter(labels).most_common(1)[0]
|
||||
if count > 1:
|
||||
raise ValueError("Duplicate label %s" % dup)
|
||||
super(StatusBoard, self).__init__(_order=labels, **{
|
||||
label: CompositeOutputDevice(
|
||||
button=Button(button),
|
||||
lights=LEDBoard(
|
||||
red=red, green=green, _order=('red', 'green'), **kwargs
|
||||
), _order=('button', 'lights'))
|
||||
for (green, red, button), label in zip(pins, labels)
|
||||
})
|
||||
super(StatusBoard, self).__init__(
|
||||
_order=labels, pin_factory=pin_factory, **{
|
||||
label: CompositeOutputDevice(
|
||||
button=Button(button),
|
||||
lights=LEDBoard(
|
||||
red=red, green=green, _order=('red', 'green'),
|
||||
pin_factory=pin_factory, **kwargs
|
||||
), _order=('button', 'lights'), pin_factory=pin_factory
|
||||
)
|
||||
for (green, red, button), label in zip(pins, labels)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class SnowPi(LEDBoard):
|
||||
@@ -917,30 +998,39 @@ class SnowPi(LEDBoard):
|
||||
in when configured for output (warning: this can be on). If ``True``,
|
||||
the device will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Ryanteck SnowPi: https://ryanteck.uk/raspberry-pi/114-snowpi-the-gpio-snowman-for-raspberry-pi-0635648608303.html
|
||||
"""
|
||||
def __init__(self, pwm=False, initial_value=False):
|
||||
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||
super(SnowPi, self).__init__(
|
||||
arms=LEDBoard(
|
||||
left=LEDBoard(
|
||||
top=17, middle=18, bottom=22,
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
_order=('top', 'middle', 'bottom')),
|
||||
_order=('top', 'middle', 'bottom'),
|
||||
pin_factory=pin_factory),
|
||||
right=LEDBoard(
|
||||
top=7, middle=8, bottom=9,
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
_order=('top', 'middle', 'bottom')),
|
||||
_order=('left', 'right')
|
||||
_order=('top', 'middle', 'bottom'),
|
||||
pin_factory=pin_factory),
|
||||
_order=('left', 'right'),
|
||||
pin_factory=pin_factory
|
||||
),
|
||||
eyes=LEDBoard(
|
||||
left=23, right=24,
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
_order=('left', 'right')
|
||||
_order=('left', 'right'),
|
||||
pin_factory=pin_factory
|
||||
),
|
||||
nose=25,
|
||||
pwm=pwm, initial_value=initial_value,
|
||||
_order=('eyes', 'nose', 'arms')
|
||||
)
|
||||
_order=('eyes', 'nose', 'arms'),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class TrafficLightsBuzzer(CompositeOutputDevice):
|
||||
@@ -957,12 +1047,18 @@ class TrafficLightsBuzzer(CompositeOutputDevice):
|
||||
|
||||
:param Button button:
|
||||
An instance of :class:`Button` representing the button on the HAT.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
|
||||
def __init__(self, lights, buzzer, button):
|
||||
def __init__(self, lights, buzzer, button, pin_factory=None):
|
||||
super(TrafficLightsBuzzer, self).__init__(
|
||||
lights=lights, buzzer=buzzer, button=button,
|
||||
_order=('lights', 'buzzer', 'button'))
|
||||
_order=('lights', 'buzzer', 'button'),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class FishDish(TrafficLightsBuzzer):
|
||||
@@ -985,14 +1081,19 @@ class FishDish(TrafficLightsBuzzer):
|
||||
LED. If ``False`` (the default), construct regular :class:`LED`
|
||||
instances.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Pi Supply FishDish: https://www.pi-supply.com/product/fish-dish-raspberry-pi-led-buzzer-board/
|
||||
"""
|
||||
|
||||
def __init__(self, pwm=False):
|
||||
def __init__(self, pwm=False, pin_factory=None):
|
||||
super(FishDish, self).__init__(
|
||||
TrafficLights(9, 22, 4, pwm=pwm),
|
||||
Buzzer(8),
|
||||
Button(7, pull_up=False),
|
||||
TrafficLights(9, 22, 4, pwm=pwm, pin_factory=pin_factory),
|
||||
Buzzer(8, pin_factory=pin_factory),
|
||||
Button(7, pull_up=False, pin_factory=pin_factory),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
@@ -1016,14 +1117,19 @@ class TrafficHat(TrafficLightsBuzzer):
|
||||
LED. If ``False`` (the default), construct regular :class:`LED`
|
||||
instances.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Ryanteck Traffic HAT: https://ryanteck.uk/hats/1-traffichat-0635648607122.html
|
||||
"""
|
||||
|
||||
def __init__(self, pwm=False):
|
||||
def __init__(self, pwm=False, pin_factory=None):
|
||||
super(TrafficHat, self).__init__(
|
||||
TrafficLights(24, 23, 22, pwm=pwm),
|
||||
Buzzer(5),
|
||||
Button(25),
|
||||
TrafficLights(24, 23, 22, pwm=pwm, pin_factory=pin_factory),
|
||||
Buzzer(5, pin_factory=pin_factory),
|
||||
Button(25, pin_factory=pin_factory),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
@@ -1049,13 +1155,19 @@ class Robot(SourceMixin, CompositeDevice):
|
||||
:param tuple right:
|
||||
A tuple of two GPIO pins representing the forward and backward inputs
|
||||
of the right motor's controller.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
|
||||
def __init__(self, left=None, right=None):
|
||||
def __init__(self, left=None, right=None, pin_factory=None):
|
||||
super(Robot, self).__init__(
|
||||
left_motor=Motor(*left),
|
||||
right_motor=Motor(*right),
|
||||
_order=('left_motor', 'right_motor'))
|
||||
left_motor=Motor(*left, pin_factory=pin_factory),
|
||||
right_motor=Motor(*right, pin_factory=pin_factory),
|
||||
_order=('left_motor', 'right_motor'),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
@@ -1148,11 +1260,17 @@ class RyanteckRobot(Robot):
|
||||
robot = RyanteckRobot()
|
||||
robot.forward()
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Ryanteck MCB: https://ryanteck.uk/add-ons/6-ryanteck-rpi-motor-controller-board-0635648607160.html
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(RyanteckRobot, self).__init__((17, 18), (22, 23))
|
||||
def __init__(self, pin_factory=None):
|
||||
super(RyanteckRobot, self).__init__(
|
||||
(17, 18), (22, 23), pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class CamJamKitRobot(Robot):
|
||||
@@ -1168,20 +1286,31 @@ class CamJamKitRobot(Robot):
|
||||
robot = CamJamKitRobot()
|
||||
robot.forward()
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(CamJamKitRobot, self).__init__((9, 10), (7, 8))
|
||||
def __init__(self, pin_factory=None):
|
||||
super(CamJamKitRobot, self).__init__(
|
||||
(9, 10), (7, 8), pin_factory=pin_factory
|
||||
)
|
||||
|
||||
|
||||
class _EnergenieMaster(SharedMixin, CompositeOutputDevice):
|
||||
def __init__(self):
|
||||
def __init__(self, pin_factory=None):
|
||||
self._lock = Lock()
|
||||
super(_EnergenieMaster, self).__init__(
|
||||
*(OutputDevice(pin) for pin in (17, 22, 23, 27)),
|
||||
mode=OutputDevice(24), enable=OutputDevice(25),
|
||||
_order=('mode', 'enable'))
|
||||
*(
|
||||
OutputDevice(pin, pin_factory=pin_factory)
|
||||
for pin in (17, 22, 23, 27)
|
||||
),
|
||||
mode=OutputDevice(24, pin_factory=pin_factory),
|
||||
enable=OutputDevice(25, pin_factory=pin_factory),
|
||||
_order=('mode', 'enable'), pin_factory=pin_factory
|
||||
)
|
||||
|
||||
def close(self):
|
||||
if self._lock:
|
||||
@@ -1190,7 +1319,7 @@ class _EnergenieMaster(SharedMixin, CompositeOutputDevice):
|
||||
self._lock = None
|
||||
|
||||
@classmethod
|
||||
def _shared_key(cls):
|
||||
def _shared_key(cls, pin_factory):
|
||||
# There's only one Energenie master
|
||||
return None
|
||||
|
||||
@@ -1231,18 +1360,22 @@ class Energenie(SourceMixin, Device):
|
||||
the socket, which will be set upon construction. This defaults to
|
||||
``False`` which will switch the socket off.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _Energenie socket: https://energenie4u.co.uk/index.php/catalogue/product/ENER002-2PI
|
||||
"""
|
||||
|
||||
def __init__(self, socket=None, initial_value=False):
|
||||
def __init__(self, socket=None, initial_value=False, pin_factory=None):
|
||||
if socket is None:
|
||||
raise EnergenieSocketMissing('socket number must be provided')
|
||||
if not (1 <= socket <= 4):
|
||||
raise EnergenieBadSocket('socket number must be between 1 and 4')
|
||||
self._value = None
|
||||
super(Energenie, self).__init__()
|
||||
super(Energenie, self).__init__(pin_factory=pin_factory)
|
||||
self._socket = socket
|
||||
self._master = _EnergenieMaster()
|
||||
self._master = _EnergenieMaster(pin_factory=pin_factory)
|
||||
if initial_value:
|
||||
self.on()
|
||||
else:
|
||||
|
||||
@@ -197,7 +197,11 @@ class Device(ValuesMixin, GPIOBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
# Force pin_factory to be keyword-only, even in Python 2
|
||||
self.pin_factory = kwargs.pop('pin_factory', Device.pin_factory)
|
||||
pin_factory = kwargs.pop('pin_factory', None)
|
||||
if pin_factory is None:
|
||||
self.pin_factory = Device.pin_factory
|
||||
else:
|
||||
self.pin_factory = pin_factory
|
||||
if kwargs:
|
||||
raise TypeError("Device.__init__() got unexpected keyword "
|
||||
"argument '%s'" % kwargs.popitem()[0])
|
||||
@@ -281,8 +285,7 @@ class CompositeDevice(Device):
|
||||
dev.close()
|
||||
raise
|
||||
self._all = args + tuple(kwargs[v] for v in self._order)
|
||||
kwargs = {'pin_factory': pin_factory} if pin_factory is not None else {}
|
||||
super(CompositeDevice, self).__init__(**kwargs)
|
||||
super(CompositeDevice, self).__init__(pin_factory=pin_factory)
|
||||
|
||||
def __getattr__(self, name):
|
||||
# if _named doesn't exist yet, pretend it's an empty dict
|
||||
|
||||
@@ -32,9 +32,13 @@ class InputDevice(GPIODevice):
|
||||
:param bool pull_up:
|
||||
If ``True``, the pin will be pulled high with an internal resistor. If
|
||||
``False`` (the default), the pin will be pulled low.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, pin=None, pull_up=False):
|
||||
super(InputDevice, self).__init__(pin)
|
||||
def __init__(self, pin=None, pull_up=False, pin_factory=None):
|
||||
super(InputDevice, self).__init__(pin, pin_factory=pin_factory)
|
||||
try:
|
||||
self.pin.function = 'input'
|
||||
pull = 'up' if pull_up else 'down'
|
||||
@@ -75,9 +79,16 @@ class DigitalInputDevice(EventsMixin, InputDevice):
|
||||
Specifies the length of time (in seconds) that the component will
|
||||
ignore changes in state after an initial change. This defaults to
|
||||
``None`` which indicates that no bounce compensation will be performed.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, pin=None, pull_up=False, bounce_time=None):
|
||||
super(DigitalInputDevice, self).__init__(pin, pull_up)
|
||||
def __init__(
|
||||
self, pin=None, pull_up=False, bounce_time=None, pin_factory=None):
|
||||
super(DigitalInputDevice, self).__init__(
|
||||
pin, pull_up, pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self.pin.bounce = bounce_time
|
||||
self.pin.edges = 'both'
|
||||
@@ -127,12 +138,18 @@ class SmoothedInputDevice(EventsMixin, InputDevice):
|
||||
(from the :attr:`is_active` property) will block until the queue has
|
||||
filled. If ``True``, a value will be returned immediately, but be
|
||||
aware that this value is likely to fluctuate excessively.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, pull_up=False, threshold=0.5,
|
||||
queue_len=5, sample_wait=0.0, partial=False):
|
||||
queue_len=5, sample_wait=0.0, partial=False, pin_factory=None):
|
||||
self._queue = None
|
||||
super(SmoothedInputDevice, self).__init__(pin, pull_up)
|
||||
super(SmoothedInputDevice, self).__init__(
|
||||
pin, pull_up, pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self._queue = GPIOQueue(self, queue_len, sample_wait, partial)
|
||||
self.threshold = float(threshold)
|
||||
@@ -263,11 +280,17 @@ class Button(HoldMixin, DigitalInputDevice):
|
||||
as long as the device remains active, every *hold_time* seconds. If
|
||||
``False`` (the default) the :attr:`when_held` handler will be only be
|
||||
executed once per hold.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, pull_up=True, bounce_time=None,
|
||||
hold_time=1, hold_repeat=False):
|
||||
super(Button, self).__init__(pin, pull_up, bounce_time)
|
||||
hold_time=1, hold_repeat=False, pin_factory=None):
|
||||
super(Button, self).__init__(
|
||||
pin, pull_up, bounce_time, pin_factory=pin_factory
|
||||
)
|
||||
self.hold_time = hold_time
|
||||
self.hold_repeat = hold_repeat
|
||||
|
||||
@@ -325,14 +348,19 @@ class LineSensor(SmoothedInputDevice):
|
||||
filled with values. Only set this to ``True`` if you require values
|
||||
immediately after object construction.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, queue_len=5, sample_rate=100, threshold=0.5,
|
||||
partial=False):
|
||||
partial=False, pin_factory=None):
|
||||
super(LineSensor, self).__init__(
|
||||
pin, pull_up=False, threshold=threshold,
|
||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial
|
||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self._queue.start()
|
||||
@@ -394,13 +422,18 @@ class MotionSensor(SmoothedInputDevice):
|
||||
:attr:`~SmoothedInputDevice.is_active` until the internal queue has
|
||||
filled with values. Only set this to ``True`` if you require values
|
||||
immediately after object construction.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, queue_len=1, sample_rate=10, threshold=0.5,
|
||||
partial=False):
|
||||
partial=False, pin_factory=None):
|
||||
super(MotionSensor, self).__init__(
|
||||
pin, pull_up=False, threshold=threshold,
|
||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial
|
||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self._queue.start()
|
||||
@@ -460,14 +493,19 @@ class LightSensor(SmoothedInputDevice):
|
||||
filled with values. Only set this to ``True`` if you require values
|
||||
immediately after object construction.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _CamJam #2 EduKit: http://camjam.me/?page_id=623
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, queue_len=5, charge_time_limit=0.01,
|
||||
threshold=0.1, partial=False):
|
||||
threshold=0.1, partial=False, pin_factory=None):
|
||||
super(LightSensor, self).__init__(
|
||||
pin, pull_up=False, threshold=threshold,
|
||||
queue_len=queue_len, sample_wait=0.0, partial=partial
|
||||
queue_len=queue_len, sample_wait=0.0, partial=partial,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self._charge_time_limit = charge_time_limit
|
||||
@@ -568,17 +606,22 @@ class DistanceSensor(SmoothedInputDevice):
|
||||
filled with values. Only set this to ``True`` if you require values
|
||||
immediately after object construction.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
|
||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||
"""
|
||||
def __init__(
|
||||
self, echo=None, trigger=None, queue_len=30, max_distance=1,
|
||||
threshold_distance=0.3, partial=False):
|
||||
threshold_distance=0.3, partial=False, pin_factory=None):
|
||||
if max_distance <= 0:
|
||||
raise ValueError('invalid maximum distance (must be positive)')
|
||||
self._trigger = None
|
||||
super(DistanceSensor, self).__init__(
|
||||
echo, pull_up=False, threshold=threshold_distance / max_distance,
|
||||
queue_len=queue_len, sample_wait=0.0, partial=partial
|
||||
queue_len=queue_len, sample_wait=0.0, partial=partial,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self.speed_of_sound = 343.26 # m/s
|
||||
|
||||
@@ -36,9 +36,15 @@ class OutputDevice(SourceMixin, GPIODevice):
|
||||
``None``, the device will be left in whatever state the pin is found in
|
||||
when configured for output (warning: this can be on). If ``True``, the
|
||||
device will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, pin=None, active_high=True, initial_value=False):
|
||||
super(OutputDevice, self).__init__(pin)
|
||||
def __init__(
|
||||
self, pin=None, active_high=True, initial_value=False,
|
||||
pin_factory=None):
|
||||
super(OutputDevice, self).__init__(pin, pin_factory=pin_factory)
|
||||
self._lock = Lock()
|
||||
self.active_high = active_high
|
||||
if initial_value is None:
|
||||
@@ -126,10 +132,14 @@ class DigitalOutputDevice(OutputDevice):
|
||||
uses an optional background thread to handle toggling the device state
|
||||
without further interaction.
|
||||
"""
|
||||
def __init__(self, pin=None, active_high=True, initial_value=False):
|
||||
def __init__(
|
||||
self, pin=None, active_high=True, initial_value=False,
|
||||
pin_factory=None):
|
||||
self._blink_thread = None
|
||||
self._controller = None
|
||||
super(DigitalOutputDevice, self).__init__(pin, active_high, initial_value)
|
||||
super(DigitalOutputDevice, self).__init__(
|
||||
pin, active_high, initial_value, pin_factory=pin_factory
|
||||
)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
@@ -230,6 +240,10 @@ class LED(DigitalOutputDevice):
|
||||
``None``, the LED will be left in whatever state the pin is found in
|
||||
when configured for output (warning: this can be on). If ``True``, the
|
||||
LED will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -265,6 +279,10 @@ class Buzzer(DigitalOutputDevice):
|
||||
``None``, the buzzer will be left in whatever state the pin is found in
|
||||
when configured for output (warning: this can be on). If ``True``, the
|
||||
buzzer will be switched on initially.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -293,13 +311,21 @@ class PWMOutputDevice(OutputDevice):
|
||||
:param int frequency:
|
||||
The frequency (in Hz) of pulses emitted to drive the device. Defaults
|
||||
to 100Hz.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, pin=None, active_high=True, initial_value=0, frequency=100):
|
||||
def __init__(
|
||||
self, pin=None, active_high=True, initial_value=0, frequency=100,
|
||||
pin_factory=None):
|
||||
self._blink_thread = None
|
||||
self._controller = None
|
||||
if not 0 <= initial_value <= 1:
|
||||
raise OutputDeviceBadValue("initial_value must be between 0 and 1")
|
||||
super(PWMOutputDevice, self).__init__(pin, active_high, initial_value=None)
|
||||
super(PWMOutputDevice, self).__init__(
|
||||
pin, active_high, initial_value=None, pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
# XXX need a way of setting these together
|
||||
self.pin.frequency = frequency
|
||||
@@ -500,6 +526,10 @@ class PWMLED(PWMOutputDevice):
|
||||
:param int frequency:
|
||||
The frequency (in Hz) of pulses emitted to drive the LED. Defaults
|
||||
to 100Hz.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -552,17 +582,24 @@ class RGBLED(SourceMixin, Device):
|
||||
If ``True`` (the default), construct :class:`PWMLED` instances for
|
||||
each component of the RGBLED. If ``False``, construct regular
|
||||
:class:`LED` instances, which prevents smooth color graduations.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, red=None, green=None, blue=None, active_high=True,
|
||||
initial_value=(0, 0, 0), pwm=True):
|
||||
initial_value=(0, 0, 0), pwm=True, pin_factory=None):
|
||||
self._leds = ()
|
||||
self._blink_thread = None
|
||||
if not all(p is not None for p in [red, green, blue]):
|
||||
raise GPIOPinMissing('red, green, and blue pins must be provided')
|
||||
LEDClass = PWMLED if pwm else LED
|
||||
super(RGBLED, self).__init__()
|
||||
self._leds = tuple(LEDClass(pin, active_high) for pin in (red, green, blue))
|
||||
super(RGBLED, self).__init__(pin_factory=pin_factory)
|
||||
self._leds = tuple(
|
||||
LEDClass(pin, active_high, pin_factory=pin_factory)
|
||||
for pin in (red, green, blue)
|
||||
)
|
||||
self.value = initial_value
|
||||
|
||||
red = _led_property(0)
|
||||
@@ -803,17 +840,23 @@ class Motor(SourceMixin, CompositeDevice):
|
||||
variable speed control. If ``False``, construct
|
||||
:class:`DigitalOutputDevice` instances, allowing only direction
|
||||
control.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(self, forward=None, backward=None, pwm=True):
|
||||
def __init__(self, forward=None, backward=None, pwm=True, pin_factory=None):
|
||||
if not all(p is not None for p in [forward, backward]):
|
||||
raise GPIOPinMissing(
|
||||
'forward and backward pins must be provided'
|
||||
)
|
||||
PinClass = PWMOutputDevice if pwm else DigitalOutputDevice
|
||||
super(Motor, self).__init__(
|
||||
forward_device=PinClass(forward),
|
||||
backward_device=PinClass(backward),
|
||||
_order=('forward_device', 'backward_device'))
|
||||
forward_device=PinClass(forward, pin_factory=pin_factory),
|
||||
backward_device=PinClass(backward, pin_factory=pin_factory),
|
||||
_order=('forward_device', 'backward_device'),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
@@ -946,11 +989,15 @@ class Servo(SourceMixin, CompositeDevice):
|
||||
:param float frame_width:
|
||||
The length of time between servo control pulses measured in seconds.
|
||||
This defaults to 20ms which is a common value for servos.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, initial_value=0.0,
|
||||
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
||||
frame_width=20/1000):
|
||||
frame_width=20/1000, pin_factory=None):
|
||||
if min_pulse_width >= max_pulse_width:
|
||||
raise ValueError('min_pulse_width must be less than max_pulse_width')
|
||||
if max_pulse_width >= frame_width:
|
||||
@@ -961,7 +1008,11 @@ class Servo(SourceMixin, CompositeDevice):
|
||||
self._min_value = -1
|
||||
self._value_range = 2
|
||||
super(Servo, self).__init__(
|
||||
pwm_device=PWMOutputDevice(pin, frequency=int(1 / frame_width)))
|
||||
pwm_device=PWMOutputDevice(
|
||||
pin, frequency=int(1 / frame_width), pin_factory=pin_factory
|
||||
),
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
try:
|
||||
self.value = initial_value
|
||||
except:
|
||||
@@ -1146,17 +1197,23 @@ class AngularServo(Servo):
|
||||
:param float frame_width:
|
||||
The length of time between servo control pulses measured in seconds.
|
||||
This defaults to 20ms which is a common value for servos.
|
||||
|
||||
:param Factory pin_factory:
|
||||
See :doc:`api_pins` for more information (this is an advanced feature
|
||||
which most users can ignore).
|
||||
"""
|
||||
def __init__(
|
||||
self, pin=None, initial_angle=0.0,
|
||||
min_angle=-90, max_angle=90,
|
||||
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
||||
frame_width=20/1000):
|
||||
frame_width=20/1000, pin_factory=None):
|
||||
self._min_angle = min_angle
|
||||
self._angular_range = max_angle - min_angle
|
||||
initial_value = 2 * ((initial_angle - min_angle) / self._angular_range) - 1
|
||||
super(AngularServo, self).__init__(
|
||||
pin, initial_value, min_pulse_width, max_pulse_width, frame_width)
|
||||
pin, initial_value, min_pulse_width, max_pulse_width, frame_width,
|
||||
pin_factory=pin_factory
|
||||
)
|
||||
|
||||
@property
|
||||
def min_angle(self):
|
||||
|
||||
@@ -28,7 +28,9 @@ class SPIDevice(Device):
|
||||
"""
|
||||
def __init__(self, **spi_args):
|
||||
self._spi = None
|
||||
super(SPIDevice, self).__init__()
|
||||
super(SPIDevice, self).__init__(
|
||||
pin_factory=spi_args.pop('pin_factory', None)
|
||||
)
|
||||
self._spi = self.pin_factory.spi(**spi_args)
|
||||
|
||||
def close(self):
|
||||
|
||||
Reference in New Issue
Block a user