|
# AnalogButtons - use ADC to give you multiple buttons |
|
# 29 Jul 2025 - @todbot / Tod Kurt |
|
# from an issue https://github.com/adafruit/circuitpython/issues/105272 |
|
# wiring is similar to https://www.instructables.com/How-to-Multiple-Buttons-on-1-Analog-Pin-Arduino-Tu/ |
|
|
|
import time |
|
import board |
|
import analogio |
|
|
|
from collections import namedtuple |
|
Event = namedtuple('Event', 'key_number pressed released') |
|
|
|
class AnalogButtons: |
|
""" |
|
One analog pin to several buttons with resistors per button in a resistor ladder. |
|
Each button produces a unique value on an analog input |
|
:param analog_in: An object with a .value property, like analogio.AnalogIn() |
|
:param levels: A tuple of values arranged lowest to highest that are about 10% lower |
|
than that seen on analog_in. |
|
""" |
|
|
|
def __init__(self, analog_in, levels=()): |
|
self.analog_in = analog_in |
|
self.levels = levels |
|
self.events = [] |
|
self.button_state = None |
|
self.last_button = None |
|
|
|
def events_get(self): |
|
events = self.events |
|
self.events = [] # reset event queue |
|
return events |
|
|
|
def update(self): |
|
val = self.analog_in.value |
|
|
|
# greater-than max level means no press or release |
|
if val > max(self.levels): |
|
if self.last_button is not None: |
|
event = Event(self.last_button, False, True) |
|
self.events.append(event) |
|
self.last_button = None # done with button |
|
# less than max means a press, start at lowest level first |
|
else: |
|
for i,level in enumerate(self.levels): |
|
if val < level: # some button was pressed |
|
if self.last_button is None: # no previous button pressed |
|
self.last_button = i |
|
event = Event(i, True, False) # push new button |
|
self.events.append(event) |
|
return |
|
else: # previous button pressed |
|
if self.last_button == i: # same button as before? |
|
return # if so, do nothing |
|
else: # else, new button |
|
event = Event(self.last_button, False, True) # release last button |
|
self.events.append(event) |
|
event = Event(i, True, False) # push new button |
|
self.events.append(event) |
|
self.last_button = i # save new button |
|
return |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
button_levels = (25000, 35000, 45000, 55000) |
|
analog_buttons = AnalogButtons(analogio.AnalogIn(board.A0), button_levels) |
|
|
|
while True: |
|
time.sleep(0.2) |
|
print('hi', time.monotonic()) |
|
|
|
analog_buttons.update() |
|
|
|
events = analog_buttons.events_get() |
|
if events: |
|
print("events:",events) |