Skip to content

Instantly share code, notes, and snippets.

@RedstoneWizard08
Last active February 7, 2023 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RedstoneWizard08/8f736b001bad383e9997aa2b89647155 to your computer and use it in GitHub Desktop.
Save RedstoneWizard08/8f736b001bad383e9997aa2b89647155 to your computer and use it in GitHub Desktop.
RPi.GPIO development polyfill

RPi.GPIO development polyfill

A handy little polyfill to aid in development with RPi.GPIO in Python.

Installation

  1. Create a folder called "RPi".
  2. Create a file called __init__.py inside the RPi folder. Leave it blank.
  3. Copy the contents of the GPIO.py file linked here into a file called GPIO.py inside the RPi folder.
  4. Import it as usual!

Notes

Everything I used to create this was pulled from here.

# ==================== RPi.GPIO Development Polyfill ====================
# A handy little polyfill to aid in development with RPi.GPIO in Python.
from typing import Callable, TypeAlias
HIGH = 1
LOW = 0
IN = 1
OUT = 0
HARD_PWM = 43
SERIAL = 40
I2C = 42
SPI = 41
UNKNOWN = -1
BOARD = 10
BCM = 11
PWM = 43
PUD_OFF = 0
PUD_UP = 2
PUD_DOWN = 1
# PY_CONST_EVENT_OFFSET = 30
# RISING = RISING_EDGE (1) + PY_CONST_EVENT_OFFSET
# FALLING = FALLING_EDGE (2) + PY_CONST_EVENT_OFFSET
# BOTH = BOTH_EDGE (3) + PY_CONST_EVENT_OFFSET
RISING = 31
FALLING = 31
BOTH = 33
NumberingMode: TypeAlias = BOARD | BCM
GPIOFunction: TypeAlias = IN | OUT | PWM | SERIAL | I2C | SPI
IODirection: TypeAlias = IN | OUT
PUDValue: TypeAlias = PUD_OFF | PUD_UP | PUD_DOWN
IOValue: TypeAlias = 0 | 1 | True | False | HIGH | LOW
Edge: TypeAlias = RISING | FALLING | BOTH
VERBOSE = False
def setup(channel: int, direction: IODirection, pull_up_down: PUDValue = PUD_OFF, initial: any = "") -> None:
"""
Set up a GPIO channel or list of channels with a direction and (optional) pull/up down control
Parameters
----------
channel : int
Either board pin number or BCM number depending on which mode is set.
direction : IODirection
IN or OUT.
[pull_up_down] : PUDValue
PUD_OFF (default), PUD_UP or PUD_DOWN
[initial] : any
Initial value for an output channel
"""
print("Setup called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
print(f">> Direction: {direction}") if VERBOSE else None
print(f">> P/U/D: {pull_up_down}") if VERBOSE else None
print(f">> Initial: {initial}") if VERBOSE else None
def cleanup(channel: int | list[int] | tuple[int, int] = 0) -> None:
"""
Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection
Parameters
----------
[channel] : int | list[int] | tuple[int, int]
individual channel or list/tuple of channels to clean up. Default - clean every channel that has been used.
"""
print("Cleanup called!") if VERBOSE else None
print(f">> Channel(s): {channel}") if VERBOSE else None
def output(channel: int, value: IOValue) -> None:
"""
Output to a GPIO channel or list of channels
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
value : int
0 / 1 or False / True or LOW / HIGH
"""
print("Output called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
print(f">> Value: {value}") if VERBOSE else None
def input(channel: int) -> IOValue:
"""
Input from a GPIO channel.
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
Returns
-------
int
HIGH = 1 = True
-- or --
LOW = 0 = False
"""
print("Input called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
def setmode(mode: NumberingMode):
"""
Set up numbering mode to use for channels.
Parameters
----------
mode : int
BOARD - Use Raspberry Pi board numbers
BCM - Use Broadcom GPIO 00..nn numbers
"""
print("SetMode called!") if VERBOSE else None
print(f">> Mode: {mode}") if VERBOSE else None
def getmode() -> NumberingMode:
"""
Get numbering mode used for channel numbers.
Returns
-------
int
BOARD, BCM, or None
"""
print("GetMode called!") if VERBOSE else None
def add_event_detect(channel: int, edge: int, callback: Callable[[], None] | None = None, bouncetime: int = 0) -> None:
"""
Enable edge detection events for a particular GPIO channel.
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
edge : int
RISING, FALLING or BOTH
[callback] : Callable[[], None] | None
A callback function for the event (optional)
[bouncetime] : int
Switch bounce timeout in ms for callback
"""
print("AddEventDetect called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
print(f">> Edge: {edge}") if VERBOSE else None
print(f">> Callback: {callback}") if VERBOSE else None
print(f">> BounceTime: {bouncetime}") if VERBOSE else None
def remove_event_detect(channel: int) -> None:
"""
Remove edge detection for a particular GPIO channel
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
"""
print("RemoveEventDetect called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
def event_detected(channel: int) -> bool:
"""
Returns True if an edge has occurred on a given GPIO.
You need to enable edge detection using add_event_detect() first.
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
Returns
-------
bool
True if an edge has occured on a given GPIO.
"""
print("EventDetected called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
def add_event_callback(channel: int, callback: Callable[[], None]) -> None:
"""
Add a callback for an event already defined using add_event_detect()
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
callback : Callable[[], None]
a callback function
"""
print("AddEventCallback called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
print(f">> Callback: {callback}") if VERBOSE else None
def wait_for_edge(channel: int, edge: Edge, bouncetime: int = 0, timeout: int = 0) -> int | None:
"""
Wait for an edge.
Parameters
----------
channel : int
either board pin number or BCM number depending on which mode is set.
edge : Edge
RISING, FALLING or BOTH
[bouncetime] : int
time allowed between calls to allow for switchbounce
[timeout] : int
timeout in ms
Returns
-------
int | None
The channel number or None on timeout.
"""
print("WaitForEdge called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
print(f">> Edge: {edge}") if VERBOSE else None
print(f">> BounceTime: {bouncetime}") if VERBOSE else None
print(f">> Timeout: {timeout}") if VERBOSE else None
def gpio_function(channel: int):
"""
Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI)
Parameters
----------
channel : int
Either board pin number or BCM number depending on which mode is set.
Returns
-------
GPIOFunction
The current GPIO function.
"""
print("GPIOFunction called!") if VERBOSE else None
print(f">> Channel: {channel}") if VERBOSE else None
def setwarnings(enable: bool) -> None:
"""
Enable or disable warning messages
Parameters
----------
enable : bool
Enable or disable warning messages.
"""
print("SetWarnings called!") if VERBOSE else None
print(f">> enable: {enable}") if VERBOSE else None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment