En este tutorial de MicroPython vamos a seguir viendo cómo interactuar con el hardware básico, viendo cómo realizar la lectura de un pulsador como entrada digital.
Un pulsador es un componente electrónico que permite o impide el flujo de corriente eléctrica cuando se presiona.
En su estado normal (sin presionar), el pulsador puede estar abierto (no conduce corriente) o cerrado (conduce corriente).
En un microcontrolador podemos usar una entrada digital para detectar si el pulsador está presionado o no. Lo cuál, en principio es muy común y bastante habitual, pero tiene su par de “cositas” que tenemos que saber.
Así que vamos a ver cómo leer un pulsador o un interruptor con un pin digital en MicroPython.
Si quieres aprender más consulta,
Configuración de un Pin GPIO como Entrada
Como vimos en la entrada anterior, en MicroPython los pines GPIO se configuran utilizando la clase Pin
del módulo machine
.
Recordemos, en resumen, que para configurar un pin como entrada, utilizamos el modo Pin.IN
. Después ya podemos leer su estado utilizando el método value()
(sin parámetros).
from machine import Pin
# Configurar el pin 5 como entrada
pulsador = Pin(5, Pin.IN)
estado = pulsador.value()
El método value()
- Devuelve
1
si el pin está en estado HIGH (pulsador presionado) 0
si está en estado LOW (pulsador no presionado).
Resistencias Pull-Up y Pull-Down
Cuando trabajamos con entradas digitales, es necesario asegurarnos de que el pin tenga un estado definido cuando el pulsador no esté presionado.
Para ello, utilizamos resistencias pull-up o pull-down.
- Resistencia Pull-Up: Conecta el pin a un voltaje alto (VCC) a través de una resistencia. Cuando el pulsador no está presionado, el pin lee HIGH. Cuando se presiona, el pin se conecta a tierra (GND) y lee LOW.
- Resistencia Pull-Down: Conecta el pin a tierra (GND) a través de una resistencia. Cuando el pulsador no está presionado, el pin lee LOW. Cuando se presiona, el pin se conecta a VCC y lee HIGH.
Muchos dispositivos incluyen resistencias de pull-up o pull-down internas. Podemos activarlas desde MicroPython, utilizando los modos Pin.PULL_UP
o Pin.PULL_DOWN
.
# Configurar el pin 5 como entrada con resistencia pull-up interna
pulsador = Pin(5, Pin.IN, Pin.PULL_UP)
En este caso, cuando el pulsador no esté presionado, el pin leerá HIGH. Cuando se presione, leerá LOW.
Manejo del rebote del pulsador
Un quebradero de cabeza común al trabajar con pulsadores es el rebote (bounce). Cuando se presiona o suelta un pulsador, los contactos suelen generar múltiples transiciones rápidas entre HIGH y LOW antes de estabilizarse (que te van a arruinar la medición).
Para manejar el rebote, podemos implementar un debounce sencillo por software en software. Una forma sencilla de hacerlo es introducir un pequeño retardo después de detectar una pulsación.
from machine import Pin
import time
# Configurar el pin 5 como entrada con resistencia pull-up interna
pulsador = Pin(5, Pin.IN, Pin.PULL_UP)
# Variable para almacenar el último estado del pulsador
ultimo_estado = pulsador.value()
while True:
estado_actual = pulsador.value()
if estado_actual != ultimo_estado:
time.sleep(0.05) # Pequeño retardo para evitar el rebote
estado_actual = pulsador.value() # Leer el estado nuevamente
if estado_actual == 0: # Pulsador presionado (LOW debido a pull-up)
print("Pulsador presionado")
else:
print("Pulsador no presionado")
ultimo_estado = estado_actual
time.sleep(0.01) # Pequeña pausa para evitar lecturas repetidas
En este código, después de detectar un cambio en el estado del pulsador, esperamos 50 ms antes de leer el estado nuevamente. Esto ayuda a evitar falsas detecciones debido al rebote.
Hay otras formas de gestionar el rebote. Esta es sencilla, y por tanto muy utilizada, pero para aplicaciones complicadas puede ser necesario métodos mejores.
Ejemplos prácticos
Encender un LED al presionar el pulsador
Vamos a combinar lo aprendido para crear un ejemplo práctico: encender un LED cuando se presiona un pulsador.
from machine import Pin
import time
# Configurar el pin 5 como entrada con resistencia pull-up interna
pulsador = Pin(5, Pin.IN, Pin.PULL_UP)
# Configurar el pin 2 como salida para el LED
led = Pin(2, Pin.OUT)
while True:
estado = pulsador.value()
if estado == 0: # Pulsador presionado (LOW debido a pull-up)
led.value(1) # Encender el LED
else:
led.value(0) # Apagar el LED
time.sleep(0.1) # Pequeña pausa para evitar lecturas repetidas
En este ejemplo, el LED conectado al pin 2 se enciende cuando se presiona el pulsador y se apaga cuando se suelta.
Leer el pulsador en un bucle continuo
Una vez configurado el pin como entrada, podemos leer su estado en un bucle para detectar cuándo se presiona el pulsador.
from machine import Pin
import time
# Configurar el pin 5 como entrada con resistencia pull-up interna
pulsador = Pin(5, Pin.IN, Pin.PULL_UP)
while True:
estado = pulsador.value()
if estado == 0: # Pulsador presionado (LOW debido a pull-up)
print("Pulsador presionado")
else:
print("Pulsador no presionado")
time.sleep(0.1) # Pequeña pausa para evitar lecturas repetidas
En este ejemplo, el programa imprime “Pulsador presionado” cuando se detecta que el pulsador está presionado (estado LOW) y “Pulsador no presionado” cuando no lo está (estado HIGH).
Contador de Pulsaciones
Este ejemplo cuenta cuántas veces se presiona un botón y muestra el resultado en la consola.
from machine import Pin
import time
# Configuración del botón
boton = Pin(25, Pin.IN, Pin.PULL_UP)
contador = 0
while True:
if boton.value() == 0: # Detecta presión del botón
time.sleep(0.02) # Anti-rebote
if boton.value() == 0:
contador += 1
print(f"Pulsaciones: {contador}")
while boton.value() == 0: # Esperar a que se suelte
pass
Cambio de estado entre múltiples modos
Este ejemplo alterna entre diferentes modos de operación al presionar el botón.
from machine import Pin
import time
# Configuración
boton = Pin(25, Pin.IN, Pin.PULL_UP)
modos = ["Modo 1", "Modo 2", "Modo 3"]
indice_modo = 0
while True:
if boton.value() == 0: # Detecta presión
time.sleep(0.02) # Anti-rebote
if boton.value() == 0:
indice_modo = (indice_modo + 1) % len(modos) # Cambia modo
print(f"Modo actual: {modos[indice_modo]}")
while boton.value() == 0: # Esperar a que se suelte
pass