buttons: Use ADC batching for ADC based buttons

Increase ADC report time from every 15ms to every 10ms and batch every
5 reports into a single message.  This should improve the
responsiveness and reduce the communication overhead when using ADC
buttons.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2026-02-17 13:10:16 -05:00
parent 8ed426b54c
commit 2f2219b4b7

View file

@ -86,10 +86,11 @@ class MCU_buttons:
# ADC button tracking
######################################################################
ADC_REPORT_TIME = 0.015
ADC_REPORT_TIME = 0.010
ADC_DEBOUNCE_TIME = 0.025
ADC_SAMPLE_TIME = 0.001
ADC_SAMPLE_COUNT = 6
ADC_BATCH_COUNT = 5
class MCU_ADC_buttons:
def __init__(self, printer, pin, pullup):
@ -105,7 +106,8 @@ class MCU_ADC_buttons:
ppins = printer.lookup_object('pins')
self.mcu_adc = ppins.setup_pin('adc', self.pin)
self.mcu_adc.setup_adc_sample(ADC_REPORT_TIME,
ADC_SAMPLE_TIME, ADC_SAMPLE_COUNT)
ADC_SAMPLE_TIME, ADC_SAMPLE_COUNT,
batch_num=ADC_BATCH_COUNT)
self.mcu_adc.setup_adc_callback(self.adc_callback)
query_adc = printer.lookup_object('query_adc')
query_adc.register_adc('adc_button:' + pin.strip(), self.mcu_adc)
@ -116,35 +118,35 @@ class MCU_ADC_buttons:
self.buttons.append((min_value, max_value, callback))
def adc_callback(self, samples):
read_time, read_value = samples[-1]
adc = max(.00001, min(.99999, read_value))
value = self.pullup * adc / (1.0 - adc)
for read_time, read_value in samples:
adc = max(.00001, min(.99999, read_value))
value = self.pullup * adc / (1.0 - adc)
# Determine button pressed
btn = None
if self.min_value <= value <= self.max_value:
for i, (min_value, max_value, cb) in enumerate(self.buttons):
if min_value < value < max_value:
btn = i
break
# Determine button pressed
btn = None
if self.min_value <= value <= self.max_value:
for i, (min_value, max_value, cb) in enumerate(self.buttons):
if min_value < value < max_value:
btn = i
break
# If the button changed, due to noise or pressing:
if btn != self.last_button:
# reset the debouncing timer
self.last_debouncetime = read_time
# If the button changed, due to noise or pressing:
if btn != self.last_button:
# reset the debouncing timer
self.last_debouncetime = read_time
# button debounce check & new button pressed
if ((read_time - self.last_debouncetime) >= ADC_DEBOUNCE_TIME
and self.last_button == btn and self.last_pressed != btn):
# release last_pressed
if self.last_pressed is not None:
self.call_button(self.last_pressed, False)
self.last_pressed = None
if btn is not None:
self.call_button(btn, True)
self.last_pressed = btn
# button debounce check & new button pressed
if ((read_time - self.last_debouncetime) >= ADC_DEBOUNCE_TIME
and self.last_button == btn and self.last_pressed != btn):
# release last_pressed
if self.last_pressed is not None:
self.call_button(self.last_pressed, False)
self.last_pressed = None
if btn is not None:
self.call_button(btn, True)
self.last_pressed = btn
self.last_button = btn
self.last_button = btn
def call_button(self, button, state):
minval, maxval, callback = self.buttons[button]