Reorganize drivers and utility modules into lib/ subdirectory and update server and upload scripts
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import time
|
||||
from machine import Pin
|
||||
|
||||
class Button:
|
||||
"""A debounced button handler supporting click and long press callbacks using Pin IRQ."""
|
||||
|
||||
def __init__(self, pin_num, name="Button", debounce_ms=50, long_press_ms=800):
|
||||
self.pin = Pin(pin_num, Pin.IN, Pin.PULL_UP)
|
||||
self.name = name
|
||||
self.debounce_ms = debounce_ms
|
||||
self.long_press_ms = long_press_ms
|
||||
|
||||
self.last_state = 1 # Normal high (pull-up)
|
||||
self.press_time = 0
|
||||
self.last_debounce_time = 0
|
||||
|
||||
self.click_callback = None
|
||||
self.long_press_callback = None
|
||||
|
||||
# Setup soft IRQ (default) to allow memory allocation and callbacks inside handler
|
||||
self.pin.irq(handler=self._handle_irq, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)
|
||||
|
||||
def is_pressed(self):
|
||||
"""Returns True if the button is currently pressed (active low)."""
|
||||
return self.pin.value() == 0
|
||||
|
||||
def on_click(self, callback):
|
||||
"""Register a callback function for a single click event."""
|
||||
self.click_callback = callback
|
||||
return callback
|
||||
|
||||
def on_long_press(self, callback):
|
||||
"""Register a callback function for a long press event."""
|
||||
self.long_press_callback = callback
|
||||
return callback
|
||||
|
||||
def _handle_irq(self, pin):
|
||||
now = time.ticks_ms()
|
||||
val = pin.value()
|
||||
|
||||
# Debounce: filter out fast state jitter
|
||||
if time.ticks_diff(now, self.last_debounce_time) < self.debounce_ms:
|
||||
return
|
||||
|
||||
if val != self.last_state:
|
||||
self.last_debounce_time = now
|
||||
self.last_state = val
|
||||
|
||||
if val == 0:
|
||||
# Button pressed
|
||||
self.press_time = now
|
||||
else:
|
||||
# Button released
|
||||
if self.press_time > 0:
|
||||
duration = time.ticks_diff(now, self.press_time)
|
||||
self.press_time = 0 # Reset
|
||||
|
||||
if duration >= self.long_press_ms:
|
||||
if self.long_press_callback:
|
||||
self.long_press_callback()
|
||||
else:
|
||||
if self.click_callback:
|
||||
self.click_callback()
|
||||
|
||||
class BoardButtons:
|
||||
"""Convenience class containing both the BOOT (Pin 0) and KEY (Pin 18) buttons."""
|
||||
|
||||
def __init__(self):
|
||||
self.boot = Button(0, "BOOT")
|
||||
self.key = Button(18, "KEY")
|
||||
Reference in New Issue
Block a user