Button fix
This commit is contained in:
@@ -5,7 +5,6 @@ from sensors.lock import grove_lock
|
|||||||
from shared.logging import log
|
from shared.logging import log
|
||||||
|
|
||||||
button = 2
|
button = 2
|
||||||
button_switch_state = 0
|
|
||||||
grovepi.pinMode(button, "INPUT")
|
grovepi.pinMode(button, "INPUT")
|
||||||
|
|
||||||
button_callback = None
|
button_callback = None
|
||||||
@@ -15,7 +14,9 @@ def read_button_state():
|
|||||||
if not grove_lock.acquire(timeout=0.2):
|
if not grove_lock.acquire(timeout=0.2):
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
return grovepi.digitalRead(button)
|
val = grovepi.digitalRead(button)
|
||||||
|
# Force strict binary output (0 or 1)
|
||||||
|
return 1 if val == 1 else 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"BTN Error: {e}")
|
log(f"BTN Error: {e}")
|
||||||
return None
|
return None
|
||||||
@@ -23,21 +24,47 @@ def read_button_state():
|
|||||||
grove_lock.release()
|
grove_lock.release()
|
||||||
|
|
||||||
def monitor_button():
|
def monitor_button():
|
||||||
global button_switch_state
|
last_stable_state = 0
|
||||||
last_button_state = button_switch_state
|
candidate_state = 0
|
||||||
|
consecutive_count = 0
|
||||||
|
|
||||||
|
# Require 3 consecutive identical reads (~60ms) to confirm a valid state change
|
||||||
|
REQUIRED_CONSECUTIVE_READS = 3
|
||||||
|
|
||||||
|
# Minimum time gap (in seconds) between allowed button triggers (cooldown)
|
||||||
|
DEBOUNCE_COOLDOWN = 0.3
|
||||||
|
last_trigger_time = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
current_state = read_button_state()
|
current_state = read_button_state()
|
||||||
|
|
||||||
if current_state is not None:
|
if current_state is not None:
|
||||||
# Rising edge detection (0 -> 1 transition)
|
if current_state == candidate_state:
|
||||||
if current_state == 1 and last_button_state == 0:
|
consecutive_count += 1
|
||||||
if button_callback:
|
else:
|
||||||
button_callback()
|
candidate_state = current_state
|
||||||
last_button_state = current_state
|
consecutive_count = 1
|
||||||
time.sleep(0.02) # Fast 20ms poll when lock is clear
|
|
||||||
|
# State is confirmed stable across multiple reads
|
||||||
|
if consecutive_count >= REQUIRED_CONSECUTIVE_READS:
|
||||||
|
now = time.time()
|
||||||
|
|
||||||
|
# Rising edge detection (0 -> 1 transition) with cooldown timer
|
||||||
|
if candidate_state == 1 and last_stable_state == 0:
|
||||||
|
if (now - last_trigger_time) > DEBOUNCE_COOLDOWN:
|
||||||
|
last_trigger_time = now
|
||||||
|
if button_callback:
|
||||||
|
try:
|
||||||
|
button_callback()
|
||||||
|
except Exception as e:
|
||||||
|
log(f"[Button] Callback exception: {e}")
|
||||||
|
|
||||||
|
last_stable_state = candidate_state
|
||||||
|
|
||||||
|
time.sleep(0.02) # 20ms poll interval
|
||||||
else:
|
else:
|
||||||
# Lock was busy; retry quickly without updating last_button_state
|
# Lock was busy or read failed; reset candidate counter to reject noisy spikes
|
||||||
|
consecutive_count = 0
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
def start_button_monitoring_thread():
|
def start_button_monitoring_thread():
|
||||||
|
|||||||
Reference in New Issue
Block a user