Skip to content

Instantly share code, notes, and snippets.

@CortesAguilar
Created November 2, 2025 16:37
Show Gist options
  • Select an option

  • Save CortesAguilar/c73401f1625512208d32e8de9c1630ca to your computer and use it in GitHub Desktop.

Select an option

Save CortesAguilar/c73401f1625512208d32e8de9c1630ca to your computer and use it in GitHub Desktop.
Debounce por software para botones
# =========================================================
# Práctica: Debounce por software para botones
# Placa: Raspberry Pi Pico W SIMULADOR WOWKI
# Alumno: Javier Ulises Cortes Aguilar | Control: 22211541
# Fecha: 11/02/2025
# =========================================================
from machine import Pin
import utime
# Configuración
BTN_PIN = 14
MODE_MS = 30_000 # 30 s por modo
DEBOUNCE_MS = 250 # Ventana de debounce (exagerada para que se note)
SAMPLE_MS = 1 # Muestreo rápido en Modo A para evidenciar rebotes
# I/O
btn = Pin(BTN_PIN, Pin.IN, Pin.PULL_UP) # Botón a GND con pull-up interno
# Estado
mode = 0 # 0 = SIN debounce, 1 = CON debounce
mode_since = utime.ticks_ms()
press_count = 0
# Detección de flancos
last_raw = btn.value() # 1 = liberado, 0 = presionado
last_press_time = -1000000 # timestamp del último 'press' validado (Modo B)
def banner():
global press_count
press_count = 0
if mode == 0:
print("\n=== MODO A: SIN DEBOUNCE ===")
print("Cuenta cada flanco 1→0; los rebotes aparecerán como múltiples 'press'.")
else:
print("\n=== MODO B: CON DEBOUNCE ===")
print(f"Ventana de {DEBOUNCE_MS} ms; cada pulsación válida registra un solo 'press'.")
print("Contador reiniciado a 0.\n")
def swap_mode_if_needed():
global mode, mode_since
if utime.ticks_diff(utime.ticks_ms(), mode_since) >= MODE_MS:
mode = 1 - mode
mode_since = utime.ticks_ms()
banner()
def handle_no_debounce():
# Cuenta TODOS los flancos de bajada (1→0)
global last_raw, press_count
raw = btn.value()
if last_raw == 1 and raw == 0:
press_count += 1
print(f"[SIN] press #{press_count}")
last_raw = raw
utime.sleep_ms(SAMPLE_MS)
def handle_with_debounce():
# Acepta solo el primer flanco 1→0 si pasaron >= DEBOUNCE_MS desde el último aceptado
global last_raw, press_count, last_press_time
raw = btn.value()
now = utime.ticks_ms()
if last_raw == 1 and raw == 0:
if utime.ticks_diff(now, last_press_time) >= DEBOUNCE_MS:
press_count += 1
last_press_time = now
print(f"[CON] press #{press_count}")
last_raw = raw
utime.sleep_ms(2)
# Inicio
print("Raspberry Pi Pico W · Debounce por software (Wokwi)")
print(f"Botón: GP{BTN_PIN} a GND con pull-up interno")
print("Alterna modos automáticamente cada 30 s.\n")
banner()
while True:
swap_mode_if_needed()
if mode == 0:
handle_no_debounce()
else:
handle_with_debounce()

VIDEO DEL SIMULADOR WOWKI: https://gist.github.com/user-attachments/assets/f69a9d13-5075-4c6a-abde-541632dba479

Explicación breve del funcionamiento

El programa compara dos modos de lectura de un botón digital en la Raspberry Pi Pico W: sin debounce y con debounce.
Cada 30 segundos, el código cambia de modo automáticamente.
En el modo sin debounce, el sistema detecta todos los cambios eléctricos generados por el rebote del botón, produciendo múltiples lecturas por una sola pulsación.
En el modo con debounce, se establece una ventana de tiempo de 180 ms que filtra los rebotes.
Solo se cuenta una pulsación si el pin se mantiene estable durante ese intervalo.
La salida en consola muestra el número de pulsaciones detectadas en cada modo, evidenciando la diferencia de comportamiento entre ambos enfoques.


Pinout utilizado

Componente Pin Pico W Descripción
Botón GP14 Entrada digital con Pin.PULL_UP
Botón GND Referencia a tierra (retorno)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment