User:Brushdemon/Raspberry Pi GPIO
Overview
Raspberry Pi single board computers contain GPIO (General-Purpose Input-Output) header pins by default on most boards. These pins allow control of external electronic components ranging from a simple LED to more complex hardware commonly found on Raspberry Pi HATs (Hardware Attached on Top). Some GPIO pins can be configured to provide alternate functionality such as:
- PWM
- I2C
- SPI
- UART
Following steps the at Raspberry_Pi_Install_Guide#Installing_the_Raspberry_Pi_Foundation_files will provide a kernel which contains the /dev/gpiomem kernel character device by default. This character device it is used by programming libraries such as python's gpiozero to provide an easy way of programming GPIO control. The idea behind the /dev/gpiomem device is to allow user access to the GPIO memory bank without giving user access to the entire system memory through the /dev/mem file. The only issue is that by default on a Gentoo system, /dev/gpiomem only allows root read and write access. This page will demonstrate how to configure udev rules so that sudo/root isn't needed to execute programs written using a GPIO library or when using command line pin control tools. These rules will also be useful for configuring alternate pin functionality such as I2C and SPI. The Raspberry Pi 5 operates a little differently to the former versions of the hardware.
Raspberry Pi 5 Changes
All Raspberry Pi's prior to the Raspberry Pi 5 shared the same memory within the VC4 chip to control the GPIO pins, accessed through the /dev/gpiomem character device provided by the Linux Kernel. This required some library writers to manage the GPIO interface using the VC Mailbox API. The Raspberry Pi 5 brought a physically small but practically large change with it's hardware architecture; the RP1 micro-controller.
The RP1 micro-controller is responsible for managing the various south-bridge interfaces. For the purposes of GPIO access, this has meant that the VC4 graphics chip is no longer directly handling the memory for GPIO pins and subsequently, the /dev/gpiomem character device no longer exists on the Pi 5. Instead, you'll find /dev/gpiomem[0-4] as well as gpiochip[0-4]. This change has meant that some older GPIO libraries aren't compatible with the Raspberry Pi 5. As libraries adapt to the RP1, this is subject to change.
The above information can be verified by grepping through the /dev directory on a Raspberry Pi 5:
root #
ls -lFa /dev | grep gpio
crw-rw---- 1 root gpio 254, 0 Jul 1 20:39 gpiochip0 crw-rw---- 1 root gpio 254, 1 Jul 1 20:39 gpiochip1 crw-rw---- 1 root gpio 254, 2 Jul 1 20:39 gpiochip2 crw-rw---- 1 root gpio 254, 3 Jul 1 20:39 gpiochip3 crw-rw---- 1 root gpio 254, 4 Jul 1 20:39 gpiochip4 crw-rw---- 1 root gpio 234, 0 Jul 1 20:39 gpiomem0 crw-rw---- 1 root gpio 239, 0 Jul 1 20:39 gpiomem1 crw-rw---- 1 root gpio 238, 0 Jul 1 20:39 gpiomem2 crw-rw---- 1 root gpio 236, 0 Jul 1 20:39 gpiomem3 crw-rw---- 1 root gpio 235, 0 Jul 1 20:39 gpiomem4
For comparison sake, the following is the output from a Raspberry Pi 1 B+:
root #
ls -lFa /dev | grep gpio
crw-rw---- 1 root gpio 254, 0 May 27 23:40 gpiochip0 crw-rw---- 1 root gpio 242, 0 Jul 1 20:07 gpiomem
This change practically means that instead of addressing /dev/gpiomem, some libraries such as dev-libs/libgpiod will require you to address /dev/gpiochip4. Chip 4 is the `pinctrl` ABI which maps to the RP1's GPIO controller chip. It's always advised to read through your chosen library's documentation to understand if there are any extra requirements when writing software for a Raspberry Pi 5.
The specifics regarding how the RP1 handles pin functionality are found within the RP1 Peripherals datasheet. As per the datasheet, the functional blocks and their locations on the GPIO pins have been chosen to match user-facing functions on the 40-pin header of a Raspberry Pi 4 Model B.
Pin Functions
Raspberry Pi GPIO pins provide and operate with 3.3v tolerant logic. Connecting peripherals which operate at a different logic level, such as 5V, will damage the Raspberry Pi. Ensure that a logic level shifter is used with these peripherals or find peripherals which operate at the recommended 3.3v logic level.
GPIO Pins have two different numbering schemes which they may be referred to:
- Physical Pin Numbering
- Begins from the top left with pin 1 through to the bottom right with pin 40
- Example: Pin 2 which refers to the 5V pin
- GPIO Pin Numbering (also referred to as BCM pin numbering)
- Pins are connected to the Broadcom chip (RP1 on the Pi 5)
- Example: GPIO 18 refers to physical pin 12
Different programming libraries may refer to either physical or GPIO pin numbering.
Power & Ground
Not all pins on the GPIO header operate as Input/Outputs. Some of them provide specialized functionality such as power output and ground pins. Other pins can operate as standard GPIO but can be configured to provide interfaces for different protocols.
Raspberry Pi's provide the following power and ground pins:
- Two 5V power output pins
- Pins 2 & 4
- Will provide as much current as your power adapter allows
- Two 3V3 power output pins
- Pins 1 & 17
- 500mA - Available since the Raspberry Pi 1 B+ and newer
- Eight ground pins (all connected to the same rail)
- Pins 6, 9, 14, 20, 25, 30, 34, and 39
The above power and ground pins can not be reconfigured for regular GPIO functionality. Devices that need higher current should be powered externally and the Pi itself should only be used to control those devices.
GPIO
GPIO pins on Raspberry Pi's can be configured to either read input or provide output. Because the GPIO pins operate using 3.3v digital logic, the inputs and the outputs represent binary bits by setting the voltage between 0v or 3.3v. When a pin is 0v, it can be described as, "low" which represents a 0. The opposite also holds true where 3.3v is described as, "high" which represents a 1.
Setting a GPIO to either an input or output is library specific and the relevant documentation should be consulted.
The dev-embedded/raspberrypi-utils package provides the "pinctrl" program which allows for pull-up and pull-down reads/write of pins. This is useful for one-off tests where the user may wish to, for example, flash an LED on and off. Users may find more documentation in the Raspberry Pi Utils pinctrl page (not to be confused with the Linux kernel driver of the same name).
GPIO pins can provide a maximum current draw of 16mA.[2] High current demanding components such as motors should be powered externally while the GPIO pin should only be used to control the component. Motors in particular may benefit from more fine grained controlled through the use of PWM.
Less power-hungry components such LED's should use a resistor to limit the current and voltage pulled by the component. Failure to do so may damage the GPIO pin (and potentially the Raspberry Pi board itself).
PWM
All GPIO pins can be configured to provide software PWM (Pulse-width modulation). Hardware controlled PWM is available on GPIO12, GPIO13, GPIO18, and GPIO19. PWM is useful for controlling motors and similar hardware where variable speed is desired. The methods for configuring software PWM on a pin are dependent on the GPIO library being used.
I2C
I2C (inter-integrated circuit) is a two wire/signal serial communication protocol. The protocol is a relative of serial protocols in that it provides a master/slave relationship between devices/components. Unlike SPI, I2C allows for multiple devices or components to be configured as masters.[3] Raspberry Pi's can be configured as either a master or slave but operating as both simultaneously is not supported.[4]
The I2C protocol needs the following two signals to function:
- SDA (Data Signal)
- Sends/Receives data
- SCL (Data Clock)
- Keeps the devices/components in sync
On the Raspberry Pi, the following pin pairs can provide an I2C interface[5]:
I2C Function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
Data Signal | 27 | GPIO0 | SDA0/ID_SD |
Data Clock | 28 | GPIO1 | SCL0/ID_SC |
The EEPROM0 I2C interface is primarily used by HATs (Hardware Attached on Top) to communicate it's identification, capabilities and firmware (device tree overlay) necessary for the HAT to function. More information about the HAT standard can be found in HAT+ specification datasheet.
I2C Function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
Data Signal | 3 | GPIO2 | SDA1 |
Data Clock | 5 | GPIO3 | SCL1 |
I2C1 provides the interface for user projects.
Since the Raspberry Pi 4, more GPIO pins can be configured to provide I2C pins. More information can be found regarding the specifics within each Raspberry Pi's CPU (RP1 for Pi 5) peripherals datasheets. For example, for the Pi 4 this can be found in the BCM2711 Peripherals data sheet; chapter 3: BSC. For the Pi 5, this can be found in the RP1 Peripherals data sheet; chapter 3.5: I2C.
SPI
SPI (serial peripheral interface) is a short-distance protocol used primarily by embedded devices to communicate with components. Because SPI is a serial protocol, it operates using a master/slave communication design. On a Raspberry Pi, the SPI interface is used by a number of peripherals which can include: displays, network controllers (Ethernet, CAN bus), UARTs, etc.[6]
The SPI protocol requires 3 serial wires and one chip enable to operate in Standard Mode:
- CE (Chip Enable; also referred to as Chip Select)
- The CE line is pulled low to tell the SPI peripheral that communication is ready
- SCLK (Serial Clock)
- The master device sends a clock cycle which keeps the main device and peripheral in sync
- MOSI (Master Out, Slave In)
- Data line from main device -> peripheral device
- MISO (Master In, Slave Out)
- Data line from peripheral device -> main device
The Raspberry Pi Zero, 1, 2, and 3 have two/three SPI hardware controllers.[7] The specifics of how SPI operates on these versions of the Raspberry Pi may be found within BCM2835 Peripherals Datasheet. Specifically Chapter 2.3 - Universal SPI Master (2x) explains how SPI operates and functions, Chapter 10 - SPI explains the specific implementations of the protocol.
Similar to I2C, each SPI interface is named as SPI0, SPI1, etc. The following tables show the pins used for each SPI interface. These tables are very slightly adapted from Raspberry Pi Hardware documentation: Serial Peripheral Interface (SPI), which you should read.
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 19 | GPIO10 | SPI0_MOSI |
MISO | 21 | GPIO9 | SPI0_MISO |
SCLK | 23 | GPIO11 | SPI0_SCLK |
CE0 | 24 | GPIO8 | SPI0_CE0_N |
CE1 | 26 | GPIO7 | SPI0_CE1_N |
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 38 | GPIO20 | SPI1_MOSI |
MISO | 35 | GPIO19 | SPI1_MISO |
SCLK | 40 | GPIO21 | SPI1_SCLK |
CE0 | 12 | GPIO18 | SPI1_CE0_N |
CE1 | 11 | GPIO17 | SPI1_CE1_N |
CE2 | 36 | GPIO16 | SPI1_CE2_N |
SPI function | Broadcom/GPIO Pin | Pin Function |
---|---|---|
MOSI | GPIO41 | SPI2_MOSI |
MISO | GPIO40 | SPI2_MISO |
SCLK | GPIO42 | SPI2_SCLK |
CE0 | GPIO43 | SPI2_CE0_N |
CE1 | GPIO44 | SPI2_CE1_N |
CE2 | GPIO45 | SPI2_CE2_N |
The Raspberry Pi 4, 400, Compute Module 4, and 5 contain six usable SPI buses. SPI0 and SPI1 are still available on these newer Pi models as well as the following:
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 3 | GPIO2 | SPI3_MOSI |
MISO | 28 | GPIO1 | SPI3_MISO |
SCLK | 5 | GPIO3 | SPI3_SCLK |
CE0 | 27 | GPIO0 | SPI3_CE0_N |
CE1 | 18 | GPIO24 | SPI3_CE1_N |
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 31 | GPIO6 | SPI4_MOSI |
MISO | 29 | GPIO5 | SPI4_MISO |
SCLK | 26 | GPIO7 | SPI4_SCLK |
CE0 | 7 | GPIO4 | SPI4_CE0_N |
CE1 | 22 | GPIO25 | SPI4_CE1_N |
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 8 | GPIO14 | SPI5_MOSI |
MISO | 33 | GPIO13 | SPI5_MISO |
SCLK | 10 | GPIO15 | SPI5_SCLK |
CE0 | 32 | GPIO12 | SPI5_CE0_N |
CE1 | 37 | GPIO26 | SPI5_CE1_N |
SPI function | Physical Pin | Broadcom/GPIO Pin | Pin Function |
---|---|---|---|
MOSI | 38 | GPIO20 | SPI6_MOSI |
MISO | 35 | GPIO19 | SPI6_MISO |
SCLK | 40 | GPIO21 | SPI6_SCLK |
CE0 | 12 | GPIO18 | SPI6_CE0_N |
CE1 | 13 | GPIO27 | SPI6_CE1_N |
UART
UART (Universal Asynchronous Receiver / Transmitter), or more commonly just called, "Serial," is a serial protocol which doesn't rely upon a shared clock. Synchronization between devices is achieved by setting the same baud/bit rate on both ends of the connection.
More information regarding this protocol as well as set up on a Gentoo system running on a Raspberry Pi can be found on the Raspberry_Pi_Serial_Ports page.
Configuration
Configuration of GPIO pins and their alternate functions rely upon two things. The first is the ability to access the memory bank for the GPIO pins which consists of adding udev rules as well as creating groups then adding users to groups. The second is adding the appropriate lines to the /boot/config.txt or /boot/firmware/config.txt. Configuring udev rules and fixing permission issues is a good place to begin.
User GPIO Access
When using using a programming library, such as gpiozero for python or rust_gpiozero for rust, the user running the program won't have the necessary permissions to access the /dev/gpiomem or /dev/gpiochip4 character device. Simply changing the permissions on /dev/gpiomem and similar won't persist between boots. Udev rules provide a way for persistently changing the file ownership and access management of kernel devices.
The Raspberry Pi OS developers have conveniently already written udev rules, which can be found on their RPi-OS github page. Copy the contents of those rules to /etc/udev/rules.d/99-com.rules. You may use your favorite text editor, nano is being used in this demonstration.
root #
nano /etc/udev/rules.d/99-com.rules
SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660"
SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660"
SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys/class/gpio && chmod -R g=u /sys/class/gpio'"
SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'"
# PWM export results in a "change" action on the pwmchip device (not "add" of a new device), so match actions other than "remove".
SUBSYSTEM=="pwm", ACTION!="remove", PROGRAM="/bin/sh -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'"
KERNEL=="ttyAMA[0-9]*|ttyS[0-9]*", PROGRAM="/bin/sh -c '\
ALIASES=/proc/device-tree/aliases; \
TTYNODE=$$\(readlink /sys/class/tty/%k/device/of_node | sed 's/base/:/' | cut -d: -f2); \
if [ -e $$ALIASES/console ]; then \
if [ $$TTYNODE = $$(strings $$ALIASES/console) ]; then \
echo 0; \
elif [ -e $$ALIASES/bluetooth ] && [ $$TTYNODE/bluetooth = $$(strings $$ALIASES/bluetooth) ]; then \
echo 1; \
else \
exit 1; \
fi \
elif [ $$TTYNODE = $$(strings $$ALIASES/serial0) ]; then \
echo 0; \
elif [ $$TTYNODE = $$(strings $$ALIASES/serial1) ]; then \
echo 1; \
else \
exit 1; \
fi \
'", SYMLINK+="serial%c"
ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon1", RUN+="/bin/sh -c '\
if echo RPi-Sense FB | cmp -s /sys/class/graphics/fb0/name; then \
echo 0 > /sys$devpath/bind; \
fi; \
'"
The rules above add more than just GPIO access; it also handles what are called, "Peripherals," or more accurately, "Pads" (semiconductor design term meaning, "chip connection to the outside world") within the Broadcom chip. For broad GPIO access, the rules above allow users in the, "gpio" group to access gpio-related kernel devices such as /dev/gpiomem, /dev/gpiochip0, etc.
Next create the "gpio" group.
root #
groupadd gpio
Now add the user to the "gpio" group.
root #
gpasswd -a youruser gpio
Finally, reboot the Raspberry Pi to ensure that /dev/gpiomem has group permissions set to "gpio".
root #
ls -l /dev/gpiomemcrw-rw---- 1 root gpio 241, 0 Jun 16 15:12 /dev/gpiomem
I2C
Having followed the above udev steps, enabling I2C simply requires creating the i2c group, adding the user to that group then enabling i2c within /boot/config.txt as well as loading the kernel module.
First, create the "i2c" group.
root #
groupadd i2c
Now add the user to the "i2c" group.
root #
gpasswd -a youruser i2c
Now append the following to /boot/config.txt.
...
dtparam=i2c_arm=on
Finally ensure that the "i2c-dev" module loads at boot.
i2c-dev
Now reboot the Raspberry Pi.
When working with I2C, it may be helpful to install sys-apps/i2c-tools. This package is useful in detecting the I2C bus and the connected components.
root #
emerge --ask sys-apps/i2c-tools
sys-apps/i2c-tools installs a command line program "i2cdetect". Running that command with the "-l" option will show available i2c buses. The following is example output on a Raspberry Pi 5.
user $
i2cdetect -l
i2c-1 i2c Synopsys DesignWare I2C adapter I2C adapter i2c-11 i2c 107d508200.i2c I2C adapter i2c-12 i2c 107d508280.i2c I2C adapter
"i2c-1" maps directly to I2C1 as outlined in the Pin Functionality section of this page.
SPI
Similar to I2C, configuring GPIO pins for SPI requires creating the "spi" group, adding a user to it and then appending a line to /boot/config.txt. Enabling an overlay or using dtparam in /boot/config.txt should load the relevant kernel module so there should be no need for creating a new file in the /lib/modprobe.d.
First create the "spi" group.
root #
groupadd spi
Now add the user to the "spi" group.
root #
gpasswd -a youruser spi
Now append the following to /boot/config.txt.
...
dtparam=spi=on
Now reboot the Raspberry Pi.
Upon reboot, the following kernel character devices should be present.
user $
ls -l /dev | grep spi
crw-rw---- 1 root spi 153, 1 Jul 13 16:18 spidev0.0 crw-rw---- 1 root spi 153, 2 Jul 13 16:18 spidev0.1 crw-rw---- 1 root spi 153, 0 Jul 13 16:18 spidev10.0
"spidev" is the kernel driver in use. "spidev0" translates to SPI0 as outlined in the Pin Functionality section of this page. "spidev0.0" and "spidev0.1" represent CE0 and CE1.
Alternate Busses
To enable different SPI busses (provided that the model of Raspberry Pi being used supports it) can be enabled by using the relevant dtoverlay.
Finding what overlays are available should be present within the /boot/overlays directory.
user $
ls /boot/overlays | grep spi[0-9]-
spi0-0cs.dtbo spi0-1cs.dtbo spi0-2cs.dtbo spi1-1cs.dtbo spi1-2cs.dtbo spi1-3cs.dtbo spi2-1cs.dtbo spi2-1cs-pi5.dtbo spi2-2cs.dtbo spi2-2cs-pi5.dtbo spi2-3cs.dtbo spi3-1cs.dtbo spi3-1cs-pi5.dtbo spi3-2cs.dtbo spi3-2cs-pi5.dtbo spi4-1cs.dtbo spi4-2cs.dtbo spi5-1cs.dtbo spi5-1cs-pi5.dtbo spi5-2cs.dtbo spi5-2cs-pi5.dtbo spi6-1cs.dtbo spi6-2cs.dtbo
Take for instance the dtoverlay, "spi1-2cs," will enable SPI1 with only two chip selects CE0 and CE1.
To use this overlay, append the following to /boot/config.txt.
...
dtoverlay=spi1-2cs
Reboot the Raspberry Pi and then confirm that the correct spidev character devices exist.
user $
ls -l /dev | grep spi
crw-rw---- 1 root spi 153, 2 Jul 13 16:50 spidev1.0 crw-rw---- 1 root spi 153, 0 Jul 13 16:50 spidev10.0 crw-rw---- 1 root spi 153, 1 Jul 13 16:50 spidev1.1
UART
Configuring UART can be found on the Raspberry_Pi_Serial_Ports page.
Common GPIO Libraries
There are many Raspberry Pi GPIO libraries available. The table below includes the names of some libraries and links to the relevant locations for documentation.
Many of these libraries have working ebuilds found within the Home Assistant Repository.
Library | Language(s) | Download | Documentation | Notes |
---|---|---|---|---|
pigpio | C Python |
dev-libs/pigpio | The pigpio library | |
libgpiod | C Python Rust |
dev-libs/libgpiod | kernel.org git README's; the documentation is the code |
|
bcm2835 | C | airspayce website | airspayce website |
|
wiringpi | C Bindings for other languages exist - Severely out of date |
Github | None currently - Web Archive version only | |
gpiozero | Python | Github | readthedocs.io | |
RPi.GPIO | Python | pypi sourceforge |
sourceforge |
|
rust_gpiozero | Rust | Github | docs.rs Github README provides beginner examples |
|
rppal | Rust | Github | docs.rs Github README provides important information |
|
External Resources
- GPIO and the 40 pin header section from the Raspberry Pi's hardware page.
- RPi Low-Level peripherals page at eLinux wiki.
- pinout.xyz is an interactive GPIO tool which provides brief details regarding pin functions and can be useful if using multiple hats.
- I2C Primer: What is I2C? (Part 1) is an explainer regarding the I2C protocol.
- UART Theory and Programming on the Raspberry Pi talks about programming asynchronous UART and provides details regarding the UART protocol.
Datasheets
- BCM2835 Peripherals - CPU package used on the Pi 1 and Zero. May prove useful for Pi's up to the 3b+.
- BCM2836 Peripherals - CPU package used on the Pi 2. The following use use the same peripherals data sheet:
- BCM2837 - CPU package of the Pi 2 version 1.2 and 3B. The package is the same as the BCM2836 except the Cortex-A7 cluster was switched out for a quad core Cortex-A52 cluster.
- BCM2837B0 - CPU package of the Pi 3A+ and 3B+. The package is the same as the BCM2837 except the Cortex-A52 cluser was switched out for a quad core Cortex-A53 MPCore cluster.
- RP3A0 - CPU package used in the Pi Zero 2 W. The package is similar to the BCM2837.
- BCM2711 Peripherals - CPU package used in the Pi 4.
- RP1 Peripherals - The Raspberry Pi 5 southbridge microcontroller. This chip controls most of the IO hardware on the Pi 5.
References
- ↑ Raspberry Pi Ltd, GPIO-Pinout-Diagram, GPIO and the 40-pin header, Retrieved on June 25th, 2024
- ↑ Les Pounder, Raspberry Pi GPIO Pinout: What Each Pin Does on Pi 4, Earlier Models, Tom's Hardware, Marth 28th, 2023. Retrieved July 6th, 2024
- ↑ Sam, I2C with Raspberry Pi, Core Electronics, October 28th, 2022. Retrieved July 12th, 2024
- ↑ Raspberry Pi Ltd, RP1 Peripherals: 3.5. I2C, Raspberry Pi Website, 2023. Retrieved July 6th, 2024
- ↑ Raspberry Pi Ltd, GPIO and the 40-pin header: Alternative Functions, Raspberry Pi Website, Retrieved July 6th, 2024
- ↑ Raspberry Pi Ltd, Serial Peripheral Interface (SPI), Raspberry Pi Website, Retrieved July 10th, 2024
- ↑ Raspberry Pi Ltd, Serial Peripheral Interface (SPI), Raspberry Pi Website, Retrieved July 10th, 2024
- ↑ joan2937, pigpio Issue 586, pigpio Github repository, September 28th, 2023. Retrieved on July 2nd, 2024
- ↑ JinShil, pigpio Issue 589, pigpio Github repository, November 7th, 2023. Retrieved on July 2nd, 2024
- ↑ hhk7734, python3-gpiod README, python3-gpiod Github repository, May 20th, 2024. Retrieved on July 2nd, 2024
- ↑ Gordon Henderson, wiringPi - deprecated (web archive), wiringpi.com (web archive), August 6th, 2019. Retrieved July 2nd 2024
- ↑ GrazerComputerClub, wiringPi README, GrazerComputerClub Github Page, March 13th, 2024. Retrieved on July 2nd, 2024
- ↑ mstroh76, Wiring Pi Issue 21, GrazerComputerClub Github Page, February 27th, 2024. Retrieved July 2nd, 2024
- ↑ Raspberry Pi Ltd, Use Python on a Raspberry Pi, Raspberry Pi, Retrieved July 2 2024
- ↑ Ben Nuttall, gpiozero Documentation - Development, gpiozero readthedocs, Retrieved July 2, 2024
- ↑ Ben Nuttall & Dave Jones, gpiozero setup.cfg, gpiozero Github, Retrieved July 2nd, 2024
- ↑ Melissa LeBlanc-Williams, Plans to support Raspberry Pi 5, RPi.GPIO sourceforge, October 19th, 2023. Retrieved July 2nd, 2024