Using machine Pin class no way to get pin number or channel when running on Pi Pico?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Jibun no kage
Posts: 144
Joined: Mon Jul 25, 2022 9:45 pm

Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by Jibun no kage » Tue Jul 26, 2022 7:11 pm

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?

User avatar
curt
Posts: 25
Joined: Thu Jul 29, 2021 3:52 am
Location: Big Lake, Alaska

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by curt » Tue Jul 26, 2022 7:55 pm

I asked this awhile back
viewtopic.php?f=15&t=11911&p=64789#p64789

Curt

rkompass
Posts: 66
Joined: Fri Sep 17, 2021 8:25 pm

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by rkompass » Tue Jul 26, 2022 8:48 pm

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.

rkompass
Posts: 66
Joined: Fri Sep 17, 2021 8:25 pm

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by rkompass » Thu Jul 28, 2022 4:16 pm

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

User avatar
scruss
Posts: 360
Joined: Sat Aug 12, 2017 2:27 pm
Location: Toronto, Canada
Contact:

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by scruss » Thu Jul 28, 2022 4:48 pm

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").

rkompass
Posts: 66
Joined: Fri Sep 17, 2021 8:25 pm

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by rkompass » Thu Jul 28, 2022 6:12 pm

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

rkompass
Posts: 66
Joined: Fri Sep 17, 2021 8:25 pm

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by rkompass » Thu Jul 28, 2022 6:19 pm

You are right: I flashed the nightly build and now pin('LED') is possible even on RPI Pico! Nice.

DeaD_EyE
Posts: 19
Joined: Sun Jul 17, 2022 12:57 pm
Contact:

Re: Using machine Pin class no way to get pin number or channel when running on Pi Pico?

Post by DeaD_EyE » Fri Jul 29, 2022 6:51 am

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.

Post Reply