|
# ==================== 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 |