Page 1 of 1
Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Tue Jul 26, 2022 7:11 pm
by Jibun no kage
Using machine Pin class no way to get pin number or channel when running on Pi Pico? If I print using repr on the pin object, I can see a GPIO pin number, GPIO0 for example. but can't seem to figure out a way to access that property or attribute?
For example, using repr(thePin) returns "Pin(WL_GPIO0, mode=OUT)" which is the Pin assignment and configured mode.
Trying to develop a generic callback for handing the pin state, where I don't have to pass in the Pin object, the callback can just figure out which pin is applicable. RPi.GPIO does this in that the pin call back gets a channel int or number that tells you the pin applicable, but MicroPython rp2 module does not seem to support similar methodology?
I could create a class and jump through some hoops, tracking the Pin info, but when it is right there already?
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Tue Jul 26, 2022 7:55 pm
by curt
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Tue Jul 26, 2022 8:48 pm
by rkompass
you could try:
Code: Select all
baddr=bytes(array('O', [pin]))
mem32[int.from_bytes(baddr, 'little')+4]
but I'm not sure this is "Future-safe".
It works here for RPi2040.
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Thu Jul 28, 2022 4:16 pm
by rkompass
Hello Jibun,
I'm not sure I understood your question.
Perhaps this is what you are looking for:
Code: Select all
from machine import Pin
pin1 = Pin('A12', Pin.OUT)
print(list((name for name, code in Pin.board.__dict__.items() if code == pin1)))
# or
print(list((name for name, code in Pin.cpu.__dict__.items() if code == pin1)))
returns
['D26', 'A12']
['GPIO_AD_B1_14']
for me on Teensy 4.1
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Thu Jul 28, 2022 4:48 pm
by scruss
rkompass wrote: ↑Tue Jul 26, 2022 8:48 pm
but I'm not sure this is "Future-safe".
I suspect it might break for the new named rather than numbered pins on the RP2040: the LED pin, formerly Pin(25), is now Pin("LED").
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Thu Jul 28, 2022 6:12 pm
by rkompass
Hey Scruss,
Pin('LED') works for me on Teensy 4.1 and this name is revealed indeed if I look it up in Pin.board.__dict__.items() like posted above.
In RPI Pico I don't find Pin.board or Pin.cpu (those nasty inconsistencies in different ports .., is there something similar at least?). So the only way apart form extracting from repr string seems to be the array('O' , [pin]) thing?
BTW: In the official docs the array typecode 'O' does not exist. I 'stole' this part of code and can only assume that O might stand for Object.
Greetings,
Raul
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Thu Jul 28, 2022 6:19 pm
by rkompass
You are right: I flashed the nightly build and now pin('LED') is possible even on RPI Pico! Nice.
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Fri Jul 29, 2022 6:51 am
by DeaD_EyE
On boards which have a
repr of Pin(number) could use a regex:
Code: Select all
import re
import micropython
from machine import Pin
pin_regex = micropython.const(re.compile(r"(\d+)"))
def pin_number(pin: Pin):
if match := pin_regex.search(repr(pin)):
return int(match.group(1))
return -1
# Tested with esp32 and rp2
p1 = Pin(22)
p2 = Pin(23)
p3 = Pin(25, mode=Pin.OUT, value=0)
for p in (p1, p2, p3):
print(pin_number(p))
Boards which uses a combination of characters and numbers, need a different regex and the value could not return as an int.
Code: Select all
import re
import micropython
from machine import Pin
# I'm not sure if micropython.const is here useful
pin_char_digit_regex = micropython.const(re.compile("\((\d+)|'(\w+\d+)'\)"))
def pin_number(pin: Pin):
if match := pin_char_digit_regex.search(repr(pin)):
for group in match.groups():
if not group:
continue
try:
return int(group)
except ValueError:
return group
p1 = Pin(22)
p2 = Pin(23)
p3 = Pin(25, mode=Pin.OUT, value=0)
for p in (p1, p2, p3):
print(pin_number(p))
PS: I have tested this only on ESP32 and RP2040. I don't have a board with character in Pin mapping.
Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?
Posted: Sat May 04, 2024 2:28 pm
by dmccreary
I could not get those to work,
I wrote the following function:
def extract_gpio_pin(pin_struct):
# Use a regular expression to find the GPIO number in the pin struct since .id() and .pin() don't work
match = re.search(r"GPIO(\d+)", str(pin_struct))
if match:
# Convert the extracted number to an integer to remove any leading zeros
return int(match.group(1))
else:
# Return None if no match is found (or raise an exception if that's preferable)
return None
This seems to work for me on the Pico RP2.
p1 = Pin(1)
p2 = Pin(23)
p3 = Pin(25, mode=Pin.OUT, value=0)
for p in (p1, p2, p3):
print(str(p))
print(extract_gpio_pin(p))
Returns:
Pin(GPIO1, mode=ALT, pull=PULL_DOWN, alt=31)
1
Pin(GPIO23, mode=ALT, pull=PULL_DOWN, alt=31)
23
Pin(GPIO25, mode=OUT)
25