From dea7ba6ec28e45edf812e6c671b6ad68781ad1b2 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Tue, 10 Jan 2017 09:43:53 +0000 Subject: [PATCH 01/13] Docs updates: add installing, advanced recipes, remote gpio and remote recipes - wip --- README.rst | 20 +- docs/examples/led_button_remote_1.py | 10 + docs/examples/led_button_remote_2.py | 12 ++ docs/examples/led_remote_1.py | 11 ++ docs/examples/led_remote_2.py | 14 ++ docs/examples/led_remote_3.py | 14 ++ docs/examples/led_remote_4.py | 14 ++ docs/examples/led_remote_5.py | 17 ++ docs/examples/multi_room_doorbell.py | 14 ++ docs/examples/multi_room_motion_alert.py | 14 ++ docs/examples/traffichat_remote_1.py | 7 + docs/examples/traffichat_remote_2.py | 8 + docs/index.rst | 3 +- docs/installing.rst | 82 ++++++++ docs/notes.rst | 5 +- docs/recipes.rst | 92 +-------- docs/recipes_advanced.rst | 66 +++++++ docs/recipes_remote_gpio.rst | 45 +++++ docs/remote_gpio.rst | 229 +++++++++++++++++++++++ 19 files changed, 578 insertions(+), 99 deletions(-) create mode 100644 docs/examples/led_button_remote_1.py create mode 100644 docs/examples/led_button_remote_2.py create mode 100644 docs/examples/led_remote_1.py create mode 100644 docs/examples/led_remote_2.py create mode 100644 docs/examples/led_remote_3.py create mode 100644 docs/examples/led_remote_4.py create mode 100644 docs/examples/led_remote_5.py create mode 100644 docs/examples/multi_room_doorbell.py create mode 100644 docs/examples/multi_room_motion_alert.py create mode 100644 docs/examples/traffichat_remote_1.py create mode 100644 docs/examples/traffichat_remote_2.py create mode 100644 docs/installing.rst create mode 100644 docs/recipes_advanced.rst create mode 100644 docs/recipes_remote_gpio.rst create mode 100644 docs/remote_gpio.rst diff --git a/README.rst b/README.rst index 8ecedd0..3210fec 100644 --- a/README.rst +++ b/README.rst @@ -56,23 +56,15 @@ together: The library includes interfaces to many simple everyday components, as well as some more complex things like sensors, analogue-to-digital converters, full -colour LEDs, robotics kits and more. +colour LEDs, robotics kits and more. See the :doc:`recipes` page for ideas on +how to get started. Install ======= -First, update your repositories list:: - - sudo apt-get update - -Then install the package of your choice. Both Python 3 and Python 2 are -supported. Python 3 is recommended:: - - sudo apt-get install python3-gpiozero - -or:: - - sudo apt-get install python-gpiozero +GPIO Zero is installed by default in Raspbian Jessie, available from +`raspberrypi.org`_. To install on Jessie Lite or other operating systems, +including for PCs using remote GPIO, see the :doc:`installing` page. Documentation ============= @@ -116,6 +108,7 @@ Other contributors: .. _Raspberry Pi Foundation: https://www.raspberrypi.org/ +.. _raspberrypi.org: https://www.raspberrypi.org/downloads/ .. _GitHub: https://github.com/RPi-Distro/python-gpiozero .. _issues: https://github.com/RPi-Distro/python-gpiozero/issues .. _recipes: https://gpiozero.readthedocs.io/en/latest/recipes.html @@ -135,4 +128,3 @@ Other contributors: .. _Clare Macrae: https://github.com/claremacrae .. _Tim Golden: https://github.com/tjguk .. _Phil Howard: https://github.com/Gadgetoid - diff --git a/docs/examples/led_button_remote_1.py b/docs/examples/led_button_remote_1.py new file mode 100644 index 0000000..7fb7363 --- /dev/null +++ b/docs/examples/led_button_remote_1.py @@ -0,0 +1,10 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from signal import pause + +button = Button(2) +led = LED(PiGPIOPin(17, host='192.168.1.3')) + +led.source = button.values + +pause() diff --git a/docs/examples/led_button_remote_2.py b/docs/examples/led_button_remote_2.py new file mode 100644 index 0000000..bacc443 --- /dev/null +++ b/docs/examples/led_button_remote_2.py @@ -0,0 +1,12 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from gpiozero.tools import all_values +from signal import pause + +led = LED(17) +button_1 = Button(PiGPIOPin(17, host='192.168.1.3')) +button_2 = Button(PiGPIOPin(17, host='192.168.1.4')) + +led.source = all_values(button_1.values, button_2.values) + +pause() diff --git a/docs/examples/led_remote_1.py b/docs/examples/led_remote_1.py new file mode 100644 index 0000000..0bfd9f4 --- /dev/null +++ b/docs/examples/led_remote_1.py @@ -0,0 +1,11 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from time import sleep + +led = LED(PiGPIOPin(17, host='192.168.1.3')) + +while True: + led.on() + sleep(1) + led.off() + sleep(1) diff --git a/docs/examples/led_remote_2.py b/docs/examples/led_remote_2.py new file mode 100644 index 0000000..c3bdb02 --- /dev/null +++ b/docs/examples/led_remote_2.py @@ -0,0 +1,14 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from time import sleep + +led_1 = LED(PiGPIOPin(17, host='192.168.1.3')) +led_2 = LED(PiGPIOPin(17, host='192.168.1.4')) + +while True: + led_1.on() + led_2.off() + sleep(1) + led_1.off() + led_2.on() + sleep(1) diff --git a/docs/examples/led_remote_3.py b/docs/examples/led_remote_3.py new file mode 100644 index 0000000..1e7133b --- /dev/null +++ b/docs/examples/led_remote_3.py @@ -0,0 +1,14 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from time import sleep + +led_1 = LED(17) # local pin +led_2 = LED(PiGPIOPin(17, host='192.168.1.3')) # remote pin + +while True: + led_1.on() + led_2.off() + sleep(1) + led_1.off() + led_2.on() + sleep(1) diff --git a/docs/examples/led_remote_4.py b/docs/examples/led_remote_4.py new file mode 100644 index 0000000..5d88d8b --- /dev/null +++ b/docs/examples/led_remote_4.py @@ -0,0 +1,14 @@ +from gpiozero import LED +from gpiozero.pins.rpigpio import RPiGPIOPin +from time import sleep + +led_1 = LED(RPiGPIOPin(17)) # local pin +led_2 = LED(17) # remote pin + +while True: + led_1.on() + led_2.off() + sleep(1) + led_1.off() + led_2.on() + sleep(1) diff --git a/docs/examples/led_remote_5.py b/docs/examples/led_remote_5.py new file mode 100644 index 0000000..ab403ee --- /dev/null +++ b/docs/examples/led_remote_5.py @@ -0,0 +1,17 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from time import sleep + +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 + +while True: + led_1.on() + led_2.off() + led_3.on() + sleep(1) + led_1.off() + led_2.on() + led_3.off() + sleep(1) diff --git a/docs/examples/multi_room_doorbell.py b/docs/examples/multi_room_doorbell.py new file mode 100644 index 0000000..da8a070 --- /dev/null +++ b/docs/examples/multi_room_doorbell.py @@ -0,0 +1,14 @@ +from gpiozero import Buzzer, Button +from gpiozero.pins.pigpio import PiGPIOPin +from signal import pause + +ips = ['192.168.1.3', '192.168.1.4', '192.168.1.5', '192.168.1.6'] +remote_pins = [PiGPIOPin(17, host=ip) for ip in ips] + +button = Button(17) # button on this pi +buzzers = [Buzzer(pin) for pin in remote_pins] # buzzers on remote pins + +for buzzer in buzzers: + buzzer.source = button.values + +pause() diff --git a/docs/examples/multi_room_motion_alert.py b/docs/examples/multi_room_motion_alert.py new file mode 100644 index 0000000..8f3e5d1 --- /dev/null +++ b/docs/examples/multi_room_motion_alert.py @@ -0,0 +1,14 @@ +from gpiozero import LEDBoard, MotionSensor +from gpiozero.pins.pigpio import PiGPIOPin +from signal import pause + +ips = ['192.168.1.3', '192.168.1.4', '192.168.1.5', '192.168.1.6'] +remote_pins = [PiGPIOPin(17, host=ip) for ip in ips] + +leds = LEDBoard(2, 3, 4, 5) # leds on this pi +sensors = [MotionSensor(pin) for pin in remote_pins] # motion sensors on other pis + +for led, sensor in zip(leds, sensors): + led.source = sensor.values + +pause() diff --git a/docs/examples/traffichat_remote_1.py b/docs/examples/traffichat_remote_1.py new file mode 100644 index 0000000..9b08eb7 --- /dev/null +++ b/docs/examples/traffichat_remote_1.py @@ -0,0 +1,7 @@ +import gpiozero +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')) +th = TrafficHat() # traffic hat on 192.168.1.3 using remote pins diff --git a/docs/examples/traffichat_remote_2.py b/docs/examples/traffichat_remote_2.py new file mode 100644 index 0000000..5795455 --- /dev/null +++ b/docs/examples/traffichat_remote_2.py @@ -0,0 +1,8 @@ +import gpiozero +from gpiozero import TrafficHat +from gpiozero.pins.pigpio import PiGPIOFactory +from time import sleep + +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 diff --git a/docs/index.rst b/docs/index.rst index 0f36e08..964bcb1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,6 +7,7 @@ Table of Contents :maxdepth: 2 recipes + recipes_remote_gpio notes contributing api_input @@ -18,7 +19,7 @@ Table of Contents api_tools api_pins api_exc + remote_gpio source_values changelog license - diff --git a/docs/installing.rst b/docs/installing.rst new file mode 100644 index 0000000..2777540 --- /dev/null +++ b/docs/installing.rst @@ -0,0 +1,82 @@ +==================== +Installing GPIO Zero +==================== + +GPIO Zero is installed by default in `Raspbian Jessie`_ and `PIXEL x86`_, available +from `raspberrypi.org`_. Follow these guides to installing on other operating +systems, including for PCs using the :doc:`remote_gpio` feature. + +Raspberry Pi +============ + +First, update your repositories list:: + + sudo apt-get update + +Then install the package for Python 3:: + + sudo apt-get install python3-gpiozero + +or Python 2:: + + sudo apt-get install python-gpiozero + +Linux +===== + +First, update your distribution's repositories list. For example:: + + sudo apt-get update + +Then install pip for Python 3:: + + sudo apt-get install python3-pip + +or Python 3:: + + sudo apt-get install python-pip + +(Alternatively, install pip with `get-pip`_.) + +Next, install gpiozero for Python 3:: + + sudo pip3 install gpiozero + +or Python 2:: + + sudo pip install gpiozero + +.. note:: + + We welcome Linux distribution maintainers to include the gpiozero packages + in their repositories. Any questions you have, please ask questions on + `GitHub`_ and we'll be happy to help. + +Mac OS +====== + +First, install pip:: + + ??? + +Next, install gpiozero with pip:: + + pip install gpiozero + +Windows +======= + +First, install pip:: + + ??? + +Next, install gpiozero with pip:: + + pip install gpiozero + + +.. Raspbian Jessie_: https://www.raspberrypi.org/downloads/raspbian/ +.. PIXEL x86_: https://www.raspberrypi.org/blog/pixel-pc-mac/ +.. raspberrypi.org_: https://www.raspberrypi.org/downloads/ +.. get-pip_: https://pip.pypa.io/en/stable/installing/ +.. GitHub: https://github.com/RPi-Distro/python-gpiozero/issues diff --git a/docs/notes.rst b/docs/notes.rst index 7c4ba69..d207ae6 100644 --- a/docs/notes.rst +++ b/docs/notes.rst @@ -35,7 +35,6 @@ manually (e.g. by pressing Ctrl+C). Similarly, when setting up callbacks on button presses or other input devices, the script needs to be running for the events to be detected:: - from gpiozero import Button from signal import pause @@ -93,3 +92,7 @@ the ``pip`` utility. This can be done with the following command in Raspbian:: $ sudo apt-get install python-pip +Alternatively, install pip with `get-pip`_. + + +.. get_pip: https://pip.pypa.io/en/stable/installing/ diff --git a/docs/recipes.rst b/docs/recipes.rst index 5c64dd3..e32c794 100644 --- a/docs/recipes.rst +++ b/docs/recipes.rst @@ -1,14 +1,13 @@ -======= -Recipes -======= +================ +Recipes (Simple) +================ .. currentmodule:: gpiozero -The following recipes demonstrate some of the capabilities of the gpiozero +The following recipes demonstrate some of the capabilities of the GPIO Zero library. Please note that all recipes are written assuming Python 3. Recipes *may* work under Python 2, but no guarantees! - .. _pin_numbering: Pin Numbering @@ -26,7 +25,6 @@ example, if an LED was attached to "GPIO17" you would specify the pin number as .. image:: images/pin_layout.* - LED === @@ -46,7 +44,6 @@ Alternatively: may be reset. Keep your script alive with :func:`signal.pause`. See :ref:`keep-your-script-running` for more information. - LED with variable brightness ============================ @@ -61,7 +58,6 @@ out continuously): .. literalinclude:: examples/led_pulse.py - Button ====== @@ -93,7 +89,6 @@ Similarly, functions can be attached to button releases: .. literalinclude:: examples/button_4.py - Button controlled LED ===================== @@ -107,7 +102,6 @@ Alternatively: .. literalinclude:: examples/button_led_2.py - Button controlled camera ======================== @@ -125,7 +119,6 @@ another to capture: .. literalinclude:: examples/button_camera_2.py - Shutdown button =============== @@ -135,7 +128,6 @@ the Raspberry Pi when the button is held for 2 seconds: .. literalinclude:: examples/button_shutdown.py - LEDBoard ======== @@ -148,7 +140,6 @@ controlled: .. literalinclude:: examples/led_board_2.py - LEDBarGraph =========== @@ -165,7 +156,6 @@ values using LED brightness: .. literalinclude:: examples/led_bargraph_2.py - Traffic Lights ============== @@ -185,19 +175,6 @@ Using :class:`LED` components: .. literalinclude:: examples/traffic_lights_3.py - -Travis build LED indicator -========================== - -Use LEDs to indicate the status of a Travis build. A green light means the -tests are passing, a red light means the build is broken: - -.. literalinclude:: examples/led_travis.py - -Note this recipe requires `travispy`_. Install with ``sudo pip3 install -travispy``. - - Push button stop motion ======================= @@ -207,7 +184,6 @@ Capture a picture with the camera module every time a button is pressed: See `Push Button Stop Motion`_ for a full resource. - Reaction Game ============= @@ -219,7 +195,6 @@ When you see the light come on, the first person to press their button wins! See `Quick Reaction Game`_ for a full resource. - GPIO Music Box ============== @@ -229,7 +204,6 @@ Each button plays a different sound! See `GPIO Music Box`_ for a full resource. - All on when pressed =================== @@ -247,7 +221,6 @@ Using :class:`LED`, :class:`Buzzer`, and :class:`Button` components: .. literalinclude:: examples/all_on_3.py - Full color LED ============== @@ -257,7 +230,6 @@ Making colours with an :class:`RGBLED`: .. literalinclude:: examples/rgbled.py - Motion sensor ============= @@ -267,7 +239,6 @@ Light an :class:`LED` when a :class:`MotionSensor` detects motion: .. literalinclude:: examples/motion_sensor.py - Light sensor ============ @@ -286,7 +257,6 @@ level: .. literalinclude:: examples/light_sensor_3.py - Distance sensor =============== @@ -300,7 +270,6 @@ Run a function when something gets near the sensor: .. literalinclude:: examples/distance_sensor_2.py - Motors ====== @@ -310,7 +279,6 @@ Spin a :class:`Motor` around forwards and backwards: .. literalinclude:: examples/motor.py - Robot ===== @@ -325,7 +293,6 @@ Make a robot with a distance sensor that runs away when things get within .. literalinclude:: examples/robot_2.py - Button controlled robot ======================= @@ -333,11 +300,6 @@ Use four GPIO buttons as forward/back/left/right controls for a robot: .. literalinclude:: examples/robot_buttons_1.py -Alternatively, use four buttons to program the directions and add a fifth -button to process them in turn, like a Bee-Bot or Turtle robot. - -.. literalinclude:: examples/robot_buttons_2.py - Keyboard controlled robot ========================= @@ -362,7 +324,6 @@ suffice: with ``sudo pip3 install evdev`` first. Be aware that ``evdev`` will only work with local input devices; this recipe will *not* work over SSH. - Motion sensor robot =================== @@ -374,7 +335,6 @@ Alternatively: .. literalinclude:: examples/robot_motion_2.py - Potentiometer ============= @@ -390,7 +350,6 @@ states that won't "fill" an LED: .. literalinclude:: examples/pot_2.py - Measure temperature with an ADC =============================== @@ -401,7 +360,6 @@ analog to digital converter: .. literalinclude:: examples/thermometer.py - Full color LED controlled by 3 potentiometers ============================================= @@ -419,48 +377,16 @@ Alternatively, the following example is identical, but uses the Please note the example above requires Python 3. In Python 2, :func:`zip` doesn't support lazy evaluation so the script will simply hang. +More recipes +============ -Controlling the Pi's own LEDs -============================= +Continue to: -On certain models of Pi (specifically the model A+, B+, and 2B) it's possible -to control the power and activity LEDs. This can be useful for testing GPIO -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:: - - $ echo none | sudo tee /sys/class/leds/led0/trigger - $ echo gpio | sudo tee /sys/class/leds/led1/trigger - -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:: - - $ echo mmc0 | sudo tee /sys/class/leds/led0/trigger - $ echo input | sudo tee /sys/class/leds/led1/trigger - -.. note:: - - On the Pi Zero you can control the activity LED with this recipe, but - there's no separate power LED to control (it's also worth noting the - activity LED is active low, so set ``active_high=False`` when constructing - your LED component). - - On the original Pi 1 (model A or B), the activity LED can be controlled - with GPIO16 (after disabling its trigger as above) but the power LED is - hard-wired on. - - On the Pi 3B the LEDs are controlled by a GPIO expander which is not - accessible from gpiozero (yet). +* :doc:`recipes_advanced` +* :doc:`recipes_remote_gpio` .. _travispy: https://travispy.readthedocs.io/ .. _Push Button Stop Motion: https://www.raspberrypi.org/learning/quick-reaction-game/ .. _Quick Reaction Game: https://www.raspberrypi.org/learning/quick-reaction-game/ .. _GPIO Music Box: https://www.raspberrypi.org/learning/gpio-music-box/ - diff --git a/docs/recipes_advanced.rst b/docs/recipes_advanced.rst new file mode 100644 index 0000000..dd4520c --- /dev/null +++ b/docs/recipes_advanced.rst @@ -0,0 +1,66 @@ +================ +Recipes (Simple) +================ + +.. currentmodule:: gpiozero + +The following recipes demonstrate some of the capabilities of the GPIO Zero +library. Please note that all recipes are written assuming Python 3. Recipes +*may* work under Python 2, but no guarantees! + +Travis build LED indicator +========================== + +Use LEDs to indicate the status of a Travis build. A green light means the +tests are passing, a red light means the build is broken: + +.. literalinclude:: examples/led_travis.py + +Note this recipe requires `travispy`_. Install with ``sudo pip3 install +travispy``. + +Button controlled robot +======================= + +Alternatively, use four buttons to program the directions and add a fifth +button to process them in turn, like a Bee-Bot or Turtle robot. + +.. literalinclude:: examples/robot_buttons_2.py + +Controlling the Pi's own LEDs +============================= + +On certain models of Pi (specifically the model A+, B+, and 2B) it's possible +to control the power and activity LEDs. This can be useful for testing GPIO +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:: + + $ echo none | sudo tee /sys/class/leds/led0/trigger + $ echo gpio | sudo tee /sys/class/leds/led1/trigger + +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:: + + $ echo mmc0 | sudo tee /sys/class/leds/led0/trigger + $ echo input | sudo tee /sys/class/leds/led1/trigger + +.. note:: + + On the Pi Zero you can control the activity LED with this recipe, but + there's no separate power LED to control (it's also worth noting the + activity LED is active low, so set ``active_high=False`` when constructing + your LED component). + + On the original Pi 1 (model A or B), the activity LED can be controlled + with GPIO16 (after disabling its trigger as above) but the power LED is + hard-wired on. + + On the Pi 3B the LEDs are controlled by a GPIO expander which is not + accessible from gpiozero (yet). diff --git a/docs/recipes_remote_gpio.rst b/docs/recipes_remote_gpio.rst new file mode 100644 index 0000000..a322682 --- /dev/null +++ b/docs/recipes_remote_gpio.rst @@ -0,0 +1,45 @@ +=================== +Remote GPIO Recipes +=================== + +.. currentmodule:: gpiozero + +The following recipes demonstrate some of the capabilities of the feature of the +GPIO Zero library. Before you start following these examples, please read up on +preparing your Pi and your host PC to work with :doc:`remote_gpio`. + +Please note that all recipes are written assuming Python 3. Recipes *may* work +under Python 2, but no guarantees! + +LED + Button +============ + +Let a button on one Raspberry Pi control the LED of another: + +.. literalinclude:: examples/led_button_remote_1.py + +LED + 2 Buttons +=============== + +The LED will come on when both buttons are pressed: + +.. literalinclude:: examples/led_button_remote_2.py + +Multi-room motion alert +======================= + +Install a Raspberry Pi with a motion sensor in each room of your house, and have +an LED indicator showing when there's motion in each room: + +.. literalinclude:: examples/multi_room_motion_alert.py + +Multi-room doorbell +=================== + +Install a Raspberry Pi with a buzzer attached in each room you want to hear the +doorbell, and use a push button ad the doorbell:: + +.. literalinclude:: examples/multi_room_doorbell.py + +This could also be used as an internal doorbell (tell people it's time for +dinner from the kitchen). diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst new file mode 100644 index 0000000..7737dea --- /dev/null +++ b/docs/remote_gpio.rst @@ -0,0 +1,229 @@ +=========== +Remote GPIO +=========== + +.. currentmodule:: gpiozero + +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` +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. + +See the :doc:`recipes_remote_gpio` page for examples on how remote pins can be +used. + +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:: + + sudo apt-get install pigpio + +Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration +tool: + + IMAGE + +(Alternatively, use ``sudo raspi-config`` on the command line) + +Then launch the pigpio daemon:: + + sudo pigpiod + +You will need to launch the pigpio daemon every time you wish to use this +feature. To automate running the daemon at boot time: + + ??? + +Preparing the host computer +=========================== + +If the host computer is a Raspberry Pi running Raspbian Jessie (or a PC running +x86 PIXEL), then you have everything you need. If you're using another Linux +distribution, Mac OS or Windows then you'll need to install the pigpio Python +library on the PC. + +Raspberry Pi +------------ + +First, update your repositories list:: + + sudo apt-get update + +Then install the pigpio library for Python 3:: + + sudo apt-get install python3-pigpio + +or Python 2:: + + sudo apt-get install python-pigpio + +Alternatively, install with pip:: + + sudo pip3 install pigpio + +or: + + sudo pip install pigpio + +Linux +----- + +First, update your distribution's repositories list. For example:: + + sudo apt-get update + +Then install pip for Python 3:: + + sudo apt-get install python3-pip + +or Python 2:: + + sudo apt-get install python-pip + +(Alternatively, install pip with `get-pip`_.) + +Next, install pigpio for Python 3:: + + sudo pip3 install pigpio + +or Python 2:: + + sudo pip install pigpio + +Mac OS +------ + +First, install pip:: + + ??? + +Next, install pigpio with pip:: + + pip install pigpio + +Windows +------- + +First install pip:: + + ??? + +Next, install pigpio with pip:: + + pip install pigpio + +Environment variables +===================== + +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:: + + $ PIGPIO_ADDR=192.168.1.3 python3 hello.py + $ PIGPIO_ADDR=192.168.1.3 python3 + $ PIGPIO_ADDR=192.168.1.3 ipython3 + $ PIGPIO_ADDR=192.168.1.3 idle3 & + +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``:: + + $ 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. + +With this usage, you can write gpiozero code like you would on a Raspberry Pi, +with no modifications needed. For example: + +.. literalinclude:: examples/led_1.py + +When run with:: + + $ 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:: + + $ PIGPIO_ADDR=192.168.1.4 python3 led.py + +will flash the LED connected to pin 17 of the Raspberry Pi with the IP address +``192.168.1.4``, without any code changes. + +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: + +.. literalinclude:: examples/led_remote_1.py + +This allows devices on multiple Raspberry Pis to be used in the same script: + +.. literalinclude:: examples/led_remote_2.py + +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: + +.. literalinclude:: examples/led_remote_3.py + +Alternatively, when run with the environment variables +``GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3`` set, the following +script will behave exactly the same as the previous one: + +.. literalinclude:: examples/led_remote_4.py + +Of course, multiple IP addresses can be used: + +.. literalinclude:: examples/led_remote_5.py + +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 setting ``gpiozero.Device._pin_factory``: + +.. literalinclude:: examples/traffichat_remote_1.py + +This also allows you to swap between two IP addresses and create instances of +mutliple HATs connected to different Pis: + +.. literalinclude:: examples/traffichat_remote_2.py + +Energenie example??? +MCP3008 example??? + +.. note:: + + When running code directly on a Raspberry Pi, any pin type 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. + +Pi Zero +======= + +??? + +.. RPi.GPIO_: https://pypi.python.org/pypi/RPi.GPIO +.. pigpio_: http://abyz.co.uk/rpi/pigpio/python.html +.. get-pip_: https://pip.pypa.io/en/stable/installing/ From 582839c7826a9af6129f97e2a363a769a9ca610b Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Tue, 10 Jan 2017 10:09:09 +0000 Subject: [PATCH 02/13] Add missing advanced recipes to index and reorder --- docs/index.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 964bcb1..262eac0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,7 +7,6 @@ Table of Contents :maxdepth: 2 recipes - recipes_remote_gpio notes contributing api_input @@ -19,7 +18,9 @@ Table of Contents api_tools api_pins api_exc - remote_gpio source_values + remote_gpio + recipes_advanced + recipes_remote_gpio changelog license From 92f5288803e6082be4e30af7b7d25f82946a4d44 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Tue, 10 Jan 2017 10:33:43 +0000 Subject: [PATCH 03/13] Move travispy link to correct page --- docs/recipes.rst | 1 - docs/recipes_advanced.rst | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/recipes.rst b/docs/recipes.rst index e32c794..7cfe500 100644 --- a/docs/recipes.rst +++ b/docs/recipes.rst @@ -386,7 +386,6 @@ Continue to: * :doc:`recipes_remote_gpio` -.. _travispy: https://travispy.readthedocs.io/ .. _Push Button Stop Motion: https://www.raspberrypi.org/learning/quick-reaction-game/ .. _Quick Reaction Game: https://www.raspberrypi.org/learning/quick-reaction-game/ .. _GPIO Music Box: https://www.raspberrypi.org/learning/gpio-music-box/ diff --git a/docs/recipes_advanced.rst b/docs/recipes_advanced.rst index dd4520c..6f9996c 100644 --- a/docs/recipes_advanced.rst +++ b/docs/recipes_advanced.rst @@ -64,3 +64,6 @@ run the following commands:: On the Pi 3B the LEDs are controlled by a GPIO expander which is not accessible from gpiozero (yet). + + +.. _travispy: https://travispy.readthedocs.io/ From 8c2264566a78f9f0442491843abeee6ebe6687bb Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Tue, 10 Jan 2017 10:45:05 +0000 Subject: [PATCH 04/13] Add missing raspi-config screenshot --- docs/images/raspi-config.png | Bin 0 -> 33392 bytes docs/remote_gpio.rst | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/images/raspi-config.png diff --git a/docs/images/raspi-config.png b/docs/images/raspi-config.png new file mode 100644 index 0000000000000000000000000000000000000000..7880adb81a39b1a9e92592a924eebe47567cac6e GIT binary patch literal 33392 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 literal 0 HcmV?d00001 diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index 7737dea..f8c35a2 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -30,7 +30,7 @@ or another distribution, you'll need to install pigpio:: Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration tool: - IMAGE +.. image:: images/raspi-config.png (Alternatively, use ``sudo raspi-config`` on the command line) From d846d5b2bdcae2ed4986ef3638331c79e82172ae Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Fri, 10 Mar 2017 15:05:33 +0000 Subject: [PATCH 05/13] Fix broken internal links and use apt over apt-get --- docs/index.rst | 3 ++- docs/installing.rst | 28 ++++++++++++++-------------- docs/notes.rst | 8 ++++---- docs/recipes_advanced.rst | 6 +++--- docs/remote_gpio.rst | 31 +++++++++++++++++++------------ 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 262eac0..5ff29db 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,7 +8,7 @@ Table of Contents recipes notes - contributing + installing api_input api_output api_spi @@ -22,5 +22,6 @@ Table of Contents remote_gpio recipes_advanced recipes_remote_gpio + contributing changelog license diff --git a/docs/installing.rst b/docs/installing.rst index 2777540..30c80a5 100644 --- a/docs/installing.rst +++ b/docs/installing.rst @@ -2,39 +2,39 @@ Installing GPIO Zero ==================== -GPIO Zero is installed by default in `Raspbian Jessie`_ and `PIXEL x86`_, available -from `raspberrypi.org`_. Follow these guides to installing on other operating -systems, including for PCs using the :doc:`remote_gpio` feature. +GPIO Zero is installed by default in `Raspbian Jessie`_ and `PIXEL x86`_, +available from `raspberrypi.org`_. Follow these guides to installing on other +operating systems, including for PCs using the :doc:`remote_gpio` feature. Raspberry Pi ============ First, update your repositories list:: - sudo apt-get update + sudo apt update Then install the package for Python 3:: - sudo apt-get install python3-gpiozero + sudo apt install python3-gpiozero or Python 2:: - sudo apt-get install python-gpiozero + sudo apt install python-gpiozero Linux ===== First, update your distribution's repositories list. For example:: - sudo apt-get update + sudo apt update Then install pip for Python 3:: - sudo apt-get install python3-pip + sudo apt install python3-pip or Python 3:: - sudo apt-get install python-pip + sudo apt install python-pip (Alternatively, install pip with `get-pip`_.) @@ -75,8 +75,8 @@ Next, install gpiozero with pip:: pip install gpiozero -.. Raspbian Jessie_: https://www.raspberrypi.org/downloads/raspbian/ -.. PIXEL x86_: https://www.raspberrypi.org/blog/pixel-pc-mac/ -.. raspberrypi.org_: https://www.raspberrypi.org/downloads/ -.. get-pip_: https://pip.pypa.io/en/stable/installing/ -.. GitHub: https://github.com/RPi-Distro/python-gpiozero/issues +.. _Raspbian Jessie: https://www.raspberrypi.org/downloads/raspbian/ +.. _PIXEL x86: https://www.raspberrypi.org/blog/pixel-pc-mac/ +.. _raspberrypi.org: https://www.raspberrypi.org/downloads/ +.. _get-pip: https://pip.pypa.io/en/stable/installing/ +.. _GitHub: https://github.com/RPi-Distro/python-gpiozero/issues diff --git a/docs/notes.rst b/docs/notes.rst index d207ae6..97a650f 100644 --- a/docs/notes.rst +++ b/docs/notes.rst @@ -82,15 +82,15 @@ version of gpiozero is available in your Python environment like so:: >>> require('gpiozero')[0].version '1.2.0' -If you have multiple versions installed (e.g. from ``pip`` and ``apt-get``) -they will not show up in the list returned by the ``require`` method. However, -the first entry in the list will be the version that ``import gpiozero`` will +If you have multiple versions installed (e.g. from ``pip`` and ``apt``) they +will not show up in the list returned by the ``require`` method. However, the +first entry in the list will be the version that ``import gpiozero`` will import. If you receive the error "No module named pkg_resources", you need to install the ``pip`` utility. This can be done with the following command in Raspbian:: - $ sudo apt-get install python-pip + $ sudo apt install python-pip Alternatively, install pip with `get-pip`_. diff --git a/docs/recipes_advanced.rst b/docs/recipes_advanced.rst index 6f9996c..bb99583 100644 --- a/docs/recipes_advanced.rst +++ b/docs/recipes_advanced.rst @@ -1,6 +1,6 @@ -================ -Recipes (Simple) -================ +================== +Recipes (Advanced) +================== .. currentmodule:: gpiozero diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index f8c35a2..d74408f 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -25,7 +25,7 @@ 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:: - sudo apt-get install pigpio + sudo apt install pigpio Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration tool: @@ -38,6 +38,13 @@ Then launch the pigpio daemon:: sudo pigpiod +To only allow connections from a specific IP address, use the ``-n`` flag. For +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 + You will need to launch the pigpio daemon every time you wish to use this feature. To automate running the daemon at boot time: @@ -48,23 +55,23 @@ Preparing the host computer If the host computer is a Raspberry Pi running Raspbian Jessie (or a PC running x86 PIXEL), then you have everything you need. If you're using another Linux -distribution, Mac OS or Windows then you'll need to install the pigpio Python -library on the PC. +distribution, Mac OS or Windows then you'll need to install the ``pigpio`` +Python library on the PC. Raspberry Pi ------------ First, update your repositories list:: - sudo apt-get update + sudo apt update Then install the pigpio library for Python 3:: - sudo apt-get install python3-pigpio + sudo apt install python3-pigpio or Python 2:: - sudo apt-get install python-pigpio + sudo apt install python-pigpio Alternatively, install with pip:: @@ -79,15 +86,15 @@ Linux First, update your distribution's repositories list. For example:: - sudo apt-get update + sudo apt update Then install pip for Python 3:: - sudo apt-get install python3-pip + sudo apt install python3-pip or Python 2:: - sudo apt-get install python-pip + sudo apt install python-pip (Alternatively, install pip with `get-pip`_.) @@ -224,6 +231,6 @@ Pi Zero ??? -.. RPi.GPIO_: https://pypi.python.org/pypi/RPi.GPIO -.. pigpio_: http://abyz.co.uk/rpi/pigpio/python.html -.. get-pip_: https://pip.pypa.io/en/stable/installing/ +.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO +.. _pigpio: http://abyz.co.uk/rpi/pigpio/python.html +.. _get-pip: https://pip.pypa.io/en/stable/installing/ From ad6b85a3d81108e2b3a52283f310797cc455f0fb Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Sat, 11 Mar 2017 01:15:24 +0000 Subject: [PATCH 06/13] Formatting fixes --- docs/api_tools.rst | 8 +++----- docs/notes.rst | 8 ++++---- docs/recipes_remote_gpio.rst | 2 +- docs/remote_gpio.rst | 6 +++--- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/api_tools.rst b/docs/api_tools.rst index 6f23668..185eb19 100644 --- a/docs/api_tools.rst +++ b/docs/api_tools.rst @@ -5,10 +5,9 @@ Source Tools .. currentmodule:: gpiozero.tools GPIO Zero includes several utility routines which are intended to be used with -the :attr:`~gpiozero.SourceMixin.source` and -:attr:`~gpiozero.ValuesMixin.values` attributes common to most devices in the -library. These utility routines are in the ``tools`` module of GPIO Zero and -are typically imported as follows:: +the :doc:`source_values` attributes common to most devices in the library. These +utility routines are in the ``tools`` module of GPIO Zero and are typically +imported as follows:: from gpiozero.tools import scaled, negated, all_values @@ -76,4 +75,3 @@ Artificial sources .. autofunction:: random_values .. autofunction:: sin_values - diff --git a/docs/notes.rst b/docs/notes.rst index 97a650f..b9547fd 100644 --- a/docs/notes.rst +++ b/docs/notes.rst @@ -78,9 +78,9 @@ version of gpiozero is available in your Python environment like so:: >>> from pkg_resources import require >>> require('gpiozero') - [gpiozero 1.2.0 (/usr/local/lib/python2.7/dist-packages)] + [gpiozero 1.3.2 (/usr/lib/python3/dist-packages)] >>> require('gpiozero')[0].version - '1.2.0' + '1.3.2' If you have multiple versions installed (e.g. from ``pip`` and ``apt``) they will not show up in the list returned by the ``require`` method. However, the @@ -90,9 +90,9 @@ import. If you receive the error "No module named pkg_resources", you need to install the ``pip`` utility. This can be done with the following command in Raspbian:: - $ sudo apt install python-pip + sudo apt install python-pip Alternatively, install pip with `get-pip`_. -.. get_pip: https://pip.pypa.io/en/stable/installing/ +.. _get_pip: https://pip.pypa.io/en/stable/installing/ diff --git a/docs/recipes_remote_gpio.rst b/docs/recipes_remote_gpio.rst index a322682..c0adf77 100644 --- a/docs/recipes_remote_gpio.rst +++ b/docs/recipes_remote_gpio.rst @@ -37,7 +37,7 @@ Multi-room doorbell =================== Install a Raspberry Pi with a buzzer attached in each room you want to hear the -doorbell, and use a push button ad the doorbell:: +doorbell, and use a push button ad the doorbell: .. literalinclude:: examples/multi_room_doorbell.py diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index d74408f..0c308d8 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -39,14 +39,14 @@ Then launch the pigpio daemon:: 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 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:: ??? @@ -77,7 +77,7 @@ Alternatively, install with pip:: sudo pip3 install pigpio -or: +or:: sudo pip install pigpio From 816dc9f6d9c7d5cd88c8229f486fcdddc2313e52 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Sat, 11 Mar 2017 01:27:39 +0000 Subject: [PATCH 07/13] Fix typo --- docs/recipes_remote_gpio.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes_remote_gpio.rst b/docs/recipes_remote_gpio.rst index c0adf77..9d681be 100644 --- a/docs/recipes_remote_gpio.rst +++ b/docs/recipes_remote_gpio.rst @@ -37,7 +37,7 @@ Multi-room doorbell =================== Install a Raspberry Pi with a buzzer attached in each room you want to hear the -doorbell, and use a push button ad the doorbell: +doorbell, and use a push button as the doorbell: .. literalinclude:: examples/multi_room_doorbell.py From 8e4da94f8b755d23304d6cf47200128651b2c4c1 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Sun, 12 Mar 2017 20:22:13 +0000 Subject: [PATCH 08/13] Use InternalDevice examples that work --- gpiozero/other_devices.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gpiozero/other_devices.py b/gpiozero/other_devices.py index ccc77b5..b15317a 100644 --- a/gpiozero/other_devices.py +++ b/gpiozero/other_devices.py @@ -39,10 +39,12 @@ class PingServer(InternalDevice): from gpiozero import PingServer, LED from signal import pause - server = PingServer('my-server') + google = PingServer('google.com') led = LED(4) - led.source_delay = 1 - led.source = server.values + + led.source_delay = 60 # check once per minute + led.source = google.values + pause() :param str host: @@ -86,8 +88,10 @@ class CPUTemperature(InternalDevice): # Use minimums and maximums that are closer to "normal" usage so the # bar graph is a bit more "lively" temp = CPUTemperature(min_temp=50, max_temp=90) + graph = LEDBarGraph(5, 6, 13, 19, 25, pwm=True) graph.source = temp.values + pause() :param str sensor_file: @@ -158,14 +162,15 @@ class TimeOfDay(InternalDevice): The following example turns on a lamp attached to an :class:`Energenie` plug between 7 and 8 AM:: - from datetime import time from gpiozero import TimeOfDay, Energenie + from datetime import time from signal import pause lamp = Energenie(0) morning = TimeOfDay(time(7), time(8)) - morning.when_activated = lamp.on - morning.when_deactivated = lamp.off + + lamp.source = morning.values + pause() :param ~datetime.time start_time: @@ -240,4 +245,3 @@ class TimeOfDay(InternalDevice): return self.start_time <= datetime.utcnow().time() <= self.end_time else: return self.start_time <= datetime.now().time() <= self.end_time - From 0507273d8a4b0a7c528ca4584f9269be83b5ecd3 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Sun, 12 Mar 2017 20:23:19 +0000 Subject: [PATCH 09/13] Add Pi Zero OTG, sense hat examples and more docs --- docs/examples/pi_zero_remote.py | 9 +++++ docs/examples/sense_hat_remote.py | 10 ++++++ docs/examples/sense_hat_remote_2.py | 15 +++++++++ docs/recipes_remote_gpio.rst | 16 +++++++++ docs/remote_gpio.rst | 52 ++++++++++++++++++++++++----- 5 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 docs/examples/pi_zero_remote.py create mode 100644 docs/examples/sense_hat_remote.py create mode 100644 docs/examples/sense_hat_remote_2.py diff --git a/docs/examples/pi_zero_remote.py b/docs/examples/pi_zero_remote.py new file mode 100644 index 0000000..553460d --- /dev/null +++ b/docs/examples/pi_zero_remote.py @@ -0,0 +1,9 @@ +from gpiozero import LED +from gpiozero.pins.pigpio import PiGPIOPin +from signal import pause + +led = LED(PiGPIOPin(17, host='raspberrypi.local')) + +led.blink() + +pause() diff --git a/docs/examples/sense_hat_remote.py b/docs/examples/sense_hat_remote.py new file mode 100644 index 0000000..0b93178 --- /dev/null +++ b/docs/examples/sense_hat_remote.py @@ -0,0 +1,10 @@ +from gpiozero import MotionSensor +from gpiozero.pins.pigpio import PiGPIOPin +from sense_hat import SenseHat + +pir = MotionSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor +sense = SenseHat() # local sense hat + +while True: + pir.wait_for_motion() + sense.show_message(sense.temperature) diff --git a/docs/examples/sense_hat_remote_2.py b/docs/examples/sense_hat_remote_2.py new file mode 100644 index 0000000..c13eba9 --- /dev/null +++ b/docs/examples/sense_hat_remote_2.py @@ -0,0 +1,15 @@ +from gpiozero import LightSensor +from gpiozero.pins.pigpio import PiGPIOPin +from sense_hat import SenseHat + +light = LightSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor +sense = SenseHat() # local sense hat + +blue = (0, 0, 255) +yellow = (255, 255, 0) + +while True: + if light.value > 0.5: + sense.clear(yellow) + else: + sense.clear(blue) diff --git a/docs/recipes_remote_gpio.rst b/docs/recipes_remote_gpio.rst index 9d681be..650732f 100644 --- a/docs/recipes_remote_gpio.rst +++ b/docs/recipes_remote_gpio.rst @@ -43,3 +43,19 @@ doorbell, and use a push button as the doorbell: This could also be used as an internal doorbell (tell people it's time for dinner from the kitchen). + +Light sensor + Sense HAT +========================= + +The `Sense HAT`_ (not supported by GPIO Zero) includes temperature, humidity and +pressure sensors, but no light sensor. Remote pins allow an external light +sensor to be used as well. The Sense HAT LED display can be used to show +different colours according to the light levels: + +.. literalinclude:: examples/sense_hat_remote_2.py + +Note that in this case, the Sense HAT code must be run locally, and the GPIO +remotely. + + +.. _Sense HAT: https://www.raspberrypi.org/products/sense-hat/ diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index 0c308d8..9617f3e 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -207,7 +207,7 @@ 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 setting ``gpiozero.Device._pin_factory``: +environment variables, or by setting :attr:~Device._pin_factory`: .. literalinclude:: examples/traffichat_remote_1.py @@ -216,21 +216,55 @@ mutliple HATs connected to different Pis: .. literalinclude:: examples/traffichat_remote_2.py -Energenie example??? -MCP3008 example??? +You could even use a HAT which is not supported by GPIO Zero (such as the +`Sense HAT`_) on one Pi, and use remote pins to control another over the +network: + +.. literalinclude:: examples/sense_hat_remote.py + +Note that in this case, the Sense HAT code must be run locally, and the GPIO +remotely. + +Pi Zero USB OTG +=============== + +The `Raspberry Pi Zero`_ and `Pi Zero W`_ feature a USB OTG port, allowing users +to configure the device as (amongst other things) an Ethernet device. In this +mode, it is possible to control the Pi Zero's GPIO pins over USB from another +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. +1. Create an empty file called ``ssh`` (no file extension) and save it in the +boot partition. +1. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after +``rootwait``. + +(See `blog.gbaman.info`_ for more information) + +Then connect the Pi Zero to your computer using a micro USB cable (connecting it +to the USB port, not the power port). You'll see the indicator LED flashing as +the Pi Zero boots. When it's ready, you will be able to ping and SSH into it +using the hostname ``raspberrypi.local``. SSH into the Pi Zero, ensure Remote +GPIO is enabled and the pigpio daemon is running, and you can use remote pins +from the computer, referencing the host by its hostname, like so: + +.. literalinclude:: examples/pi_zero_remote.py .. note:: When running code directly on a Raspberry Pi, any pin type 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:`PiGPIOPin` can be used, as pigpio is the only pin + library which supports remote GPIO. -Pi Zero -======= - -??? .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO .. _pigpio: http://abyz.co.uk/rpi/pigpio/python.html .. _get-pip: https://pip.pypa.io/en/stable/installing/ +.. _Sense HAT: https://www.raspberrypi.org/products/sense-hat/ +.. _Raspberry Pi Zero: https://www.raspberrypi.org/products/pi-zero/ +.. _Pi Zero W: https://www.raspberrypi.org/products/pi-zero-w/ +.. _blog.gbaman.info: http://blog.gbaman.info/?p=791 From c05fc2e5706840b33560b639e530b37baaac2517 Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Sun, 12 Mar 2017 20:43:31 +0000 Subject: [PATCH 10/13] Formatting fixes --- docs/remote_gpio.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index 9617f3e..6ead08f 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -207,7 +207,7 @@ 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 setting :attr:~Device._pin_factory`: +environment variables, or by using :meth:`~Device._set_pin_factory`: .. literalinclude:: examples/traffichat_remote_1.py @@ -237,9 +237,9 @@ 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. -1. Create an empty file called ``ssh`` (no file extension) and save it in the +2. Create an empty file called ``ssh`` (no file extension) and save it in the boot partition. -1. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after +3. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after ``rootwait``. (See `blog.gbaman.info`_ for more information) From 0115cce324fb79afdd68cd6d10f6077b22cd2127 Mon Sep 17 00:00:00 2001 From: rgm Date: Fri, 21 Apr 2017 11:20:11 -0500 Subject: [PATCH 11/13] Fix env var for pigpio Also provide example for starting pigpiod on boot. --- docs/remote_gpio.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index 6ead08f..cd8d810 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -48,7 +48,7 @@ example:: 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 Preparing the host computer =========================== @@ -149,7 +149,7 @@ 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``:: - $ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py + $ GPIOZERO_PIN_FACTORY=PiGPIOPin 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 @@ -212,7 +212,7 @@ environment variables, or by using :meth:`~Device._set_pin_factory`: .. literalinclude:: examples/traffichat_remote_1.py This also allows you to swap between two IP addresses and create instances of -mutliple HATs connected to different Pis: +multiple HATs connected to different Pis: .. literalinclude:: examples/traffichat_remote_2.py From e68f624d139fa21be92542bab2c2814efd1a3118 Mon Sep 17 00:00:00 2001 From: rgm Date: Fri, 21 Apr 2017 11:21:19 -0500 Subject: [PATCH 12/13] Spelling typos --- docs/api_spi.rst | 2 +- docs/contributing.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api_spi.rst b/docs/api_spi.rst index 7fdc3bb..143b409 100644 --- a/docs/api_spi.rst +++ b/docs/api_spi.rst @@ -64,7 +64,7 @@ omit any arguments from either scheme. The defaults are: * *clock_pin* defaults to 11, *mosi_pin* defaults to 10, *miso_pin* defaults to 9, and *select_pin* defaults to 8. -Hence the following constructors are all equiavlent:: +Hence the following constructors are all equivalent:: from gpiozero import MCP3008 diff --git a/docs/contributing.rst b/docs/contributing.rst index 5c58da8..ec537b1 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -34,7 +34,7 @@ LED example"). Commits which close (or intend to close) an issue should include the phrase "fix #123" or "close #123" where ``#123`` is the issue number, as well as include a short description, for example: "Add LED example, close #123", and -pull requests should aim to match or closely match the correspoding issue +pull requests should aim to match or closely match the corresponding issue title. Backwards compatibility From e2927356ce4752acc56bc99e3144f7d26b27917e Mon Sep 17 00:00:00 2001 From: Ben Nuttall Date: Fri, 21 Apr 2017 19:26:51 +0100 Subject: [PATCH 13/13] Correct pigpio pin factory example back --- docs/remote_gpio.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/remote_gpio.rst b/docs/remote_gpio.rst index cd8d810..ef19b88 100644 --- a/docs/remote_gpio.rst +++ b/docs/remote_gpio.rst @@ -149,7 +149,7 @@ 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``:: - $ GPIOZERO_PIN_FACTORY=PiGPIOPin PIGPIO_ADDR=192.168.1.3 python3 hello.py + $ 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