'''
Programa de ejemplo para definir una ISR para botón
que distinga entre click corto, click largo y doble click
Importante !!!!!!
poner parámetro "bounce": "0" en componente "wokwi-pushbutton"
{
"type": "wokwi-pushbutton",
"id": "btn1",
"top": 118.6,
"left": 115.4,
"rotate": 180,
"attrs": { "bounce": "0", "color": "green", "xray": "1" }
}
'''
import time, micropython
from micropython import const
from machine import Pin
micropython.alloc_emergency_exception_buf(100)
class Button:
'''
Modelo de botón digital.
Implementa tanto la definición del pin como la isr
'''
SHORT_CLICK = const(0)
LONG_CLICK = const(1)
def __init__(self, pin :int, butLong :int, upDown :int, callback):
'''
Instanciador de la clase Button
Parametros:
pin: el pin donde está conectado fisicamente el boton
butLong: es la duracion en ms a partir de la cual un click es largo. Si es cero no tomará clicks largos
upDown: si el boton activa a low, va 0. Si activa a high va 1
callback: es la funcion de Callback que llamara la isr cuando resuelva el click
'''
# butLong es un entero. Es la cantidad de ms de un click largo
if butLong < 0:
raise ValueError("butLong no debe ser menor que cero")
self._butLong :int = butLong
# pin debe ser un entero
if not isinstance (pin, int):
raise TypeError("Pin debe ser entero")
self._pin = pin
# upDown es 0 para botones que activan en low o 1 para los que activan en high
if not upDown in (0, 1):
raise ValueError("upDown debe ser 0 o 1")
self._upDown = upDown
# Validación del callBack
if not callable (callback):
raise TypeError("callback debe ser una función")
self.callback = callback
# Variables globales del objeto
self._butOn = 0
self._pinButton = Pin(self._pin, Pin.IN)
self._pinButton.irq(handler=self.buttonPressed, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)
def buttonPressed(self, pin):
'''
Funcion de servicio de la irq
'''
if pin.value() == self._upDown:
self._butOn = time.ticks_ms()
else:
# butLong = 0 -> no se toma long click
if self._butLong == 0:
micropython.schedule(self.callback, Button.SHORT_CLICK)
else:
# butLong > 0 se contempla long click
if time.ticks_diff(time.ticks_ms(), self._butOn) > self._butLong:
micropython.schedule(self.callback, Button.LONG_CLICK)
else:
micropython.schedule(self.callback, Button.SHORT_CLICK)
def MuestraButton(LongShort:int) ->None:
if LongShort:
print('Largo')
else:
print('Corto')
boton = Button(22, 0, 0, MuestraButton)
while True:
time.sleep(.1)