
Micropython: Manejo de pines
- Dacadev
- Electronica
- May 8, 2024
Tabla de Contenido
Note
En este artículo aprenderás que es la clase Pin
de Micropython 🐍 y como esta gestiona las diferentes funcionalidades genéricas de los pines de cualquier tipo de chip. Además, verás ejemplos de cómo configurarla y usarla con la RP2040.
¿Qué es la clase Pin
?
Empecemos definiendo qué es un pin dentro de nuestro microcontrolador (uM), un pin hace referencia a una interfaz I/O asociada a un pin físico de nuestro uM. Con él podemos interactuar con el mundo real, ya sea leyendo o escribiendo señales digitales, o incluso analógicas.
La clase Pin
es una de las principales clases que provee Micropython 🐍, ya que es la que nos permitirá interactuar con los pines de nuestros uM. Esta clase se encuentra en el paquete machine
.
Instancia de la Clase Pin
La clase Pin
, tiene la siguiente firma de constructor
class Pin(id, mode=-1, pull=-1, *, value=None, drive=0, alt=-1)
En donde:
controla cuál será el comportamiento del pin. En Micropython 🐍 encuentras constantes que te ayudan a establecer el funcionamiento:
id
es el unico parámetro obligatorio y hace referencia al pin que quieres controlar. Cada uM tiene su propio mapeo de pines, por lo que deberás de consultar la documentación de tu uM para saber que pines puedes controlar.mode
* controla cuál será el comportamiento del pin. En Micropython 🐍 encuentras constantes que te ayudan a establecer el funcionamiento:Pin.IN
establece el pin como entrada.Pin.OUT
establece el pin como salida.Pin.OPEN_DRAIN
establece el pin como salida de tipo Open-drain (colector abierto), lo que significa que, si la salida está en nivel bajo, es un cero lógico, y si está en alto (1), se configura como alta impedancia.Pin.ALT
establece el pin para funcionar de manera alterna, utilizando un propósito específico del hardware.Pin.ALT_OPEN_DRAIN
es la combinación dePin.ALT
yPin.OPEN_DRAIN
Pin.ANALOG
establece el pin como entrada analógica
pull
* activas o no la opción de usar una resistencia de pull-up o pull-down, sus opciones validas son:Pin.PULL_UP
Pin.PULL_DOWN
None
= No se activa ninguna resistencia, es el valor por defecto
value
es el valor inicial que quieres asignar al pin y solo funciona cuando el pin es configurado como salida, es decir quePin.OUT
oPin.OPEN_DRAIN
drive
se utiliza para especificar la fuerza de la salida del pin. Esto es importante cuando conectas el pin a circuitos que tienen diferentes requerimientos de corriente. Los valores típicos para drive son algo así como Pin.DRIVE_0, Pin.DRIVE_1, etc., donde los números más altos representan una mayor capacidad de corriente de salida.alt
* cuando el pin está configurado como Pin.ALT o Pin.ALT_OPEN_DRAIN, este parámetro se utiliza para especificar la función alternativa que se desea utilizar.
Note
* No todos los pines tiene disponibles todas las configuraciones descritas, para validarlo debes de consultar la documentación de tu uM
Métodos de la Clase Pin
Pin.init
Pin.init(mode=-1, pull=-1, *, value=None, drive=0, alt=-1)
Una vez tengas una instancia de la clase Pin
, puedes cambiar su configuración inicial usando el método init
el cual recibe los mismos atributos del constructor salvo el identificador id
. Un ejemplo de su uso sería
from machine import Pin
led = Pin(25)
led.init(mode=Pin.OUT, value=True)
En el ejemplo anterior, estoy creando una instancia asociada al pin 25 (mapeado de mi uM) y posteriormente configurándolo con el método init
Pin.value
Pin.value([x])
Este método se utiliza para leer o escribir el valor del pin. Si no se pasa ningún parámetro, el método se comporta como un lector. Si se pasa un valor, el método se comporta como un escritor. Un ejemplo de su uso sería
from machine import Pin
led = Pin(25, Pin.OUT)
led.value(1)
print(led.value())
En el ejemplo, estamos creando un pin como salida y configurando su valor a 1, para luego leer el valor del pin.
Pin.on()
Este método es un atajo para configurar el valor del pin a 1, es decir, que el pin se configura en alto, lo cual sería lo mismo que hacer:
Pin.value(1)
Pin.off()
Este método es un atajo para configurar el valor del pin a 0, es decir, que el pin se configura en bajo, lo cual sería lo mismo que hacer:
Pin.value(0)
Pin.toggle()
Este método es un atajo para cambiar el valor del pin. Si el pin está en 1, lo cambia a 0 y viceversa, lo cual sería lo mismo que hacer:
Pin.value(not Pin.value())
Pin.irq()
Pin.irq(handler=None, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, *, priority=1, wake=None, hard=False)¶
Este método es muy importante, ya que sirve para configurar los pines para que sean asociados a interrupciones y poder ejecutar un callback
cuando se cumpla una condición. Los parámetros que recibe son:
handler
: Es uncallable
de python, es decir, una función o método de clase que recibe como parámetro únicamente un objeto de tipoPin
, que será la instancia del pin que activó la interrupción.trigger
: A través de este atributo controlaremos el tipo de comportamiento que se deberá cumplir para activar la interrupción. Para entender los posibles valores que podemos asignar, veamos primero cómo es una señal digital.Una señal digital oscila entre dos valores, 0 o 1, y la transición entre esos valores es lo que llamamos flancos. Como hay dos valores, tenemos 2 tipos de flancos. Los flancos de subida ocurren cuando cambiamos de 0 a 1 y los flancos de bajada cuando cambiamos de 1 a 0. De esta manera, en Micropython encontramos 4 tipos de activadores que podemos configurar en nuestra interrupción por pin:Pin.IRQ_FALLING
: Configura la interrupción para que se active cuando el pin cambie de 1 a 0Pin.IRQ_RISING
: Configura la interrupción para que se active cuando el pin cambie de 0 a 1Pin.IRQ_LOW_LEVEL
: Configura la interrupción para que se active cuando el pin se encuentre en 0Pin.IRQ_HIGH_LEVEL
: Configura la interrupción para que se active cuando el pin se encuentre en 1
En el siguiente diagrama puedes visualizar las fases de la señal:
Note
En el siguiente artículo te explico más del tema de interrupciones con Micropython 🐍.
Ejemplos prácticos de Pin
con RP2040
En el siguiente embebido estamos creando un proyecto en la plataforma Wokwi
, que nos permite simular proyectos con tarjetas como Arduino Uno, ESP32, Raspberry Pi Pico, entre otras, junto con un amplio conjunto de sensores y actuadores. En este caso, estamos utilizando una Raspberry Pi Pico y conjunto de LEDs y botones para mostrar cómo se puede controlar un pin con la clase Pin
de Micropython 🐍
En el ejemplo podemos ver 4 casos de uso sencillos para la clase Pin
- Caso 1: Configuramos un pin como salida y lo encendemos en la función
main
en un intervalo de 500ms con la fuinciónsleep
- Caso 2: Declaramos un pin como salida, pero primero instanciamos la clase
Pin
y luego configuramos el pin con el métodoinit
. - Case 3: Configuramos dos pines con la clase
Pin
, uno como salida y otro como entrada. Leemos el valor del pin de entrada y lo asignamos al pin de salida - Caso 4: Configuramos un pin como entrada y configuramos una interrupción para que se active cuando el pin cambie de 0 a 1. En el
callback
simplemente cambiamos el valor del pin de salida.
Note
- En el siguiente enlace puedes ver el código fuente del proyecto en una nueva pestaña.
- El caso 4 de nuestro proyecto funciona con interrupciones, y es posible que en la simulación no funcione correctamente debido a que no se está procesando el debounce del botón.
Info
Podrás encontrar toda la documentación de la clase Pin para micropython 🐍 en el siguiente link