Skip to content

Instantly share code, notes, and snippets.

Last active June 10, 2023 13:20
Show Gist options
  • Save webdeb/631146376085e01789fc3ca89616130f to your computer and use it in GitHub Desktop.
Save webdeb/631146376085e01789fc3ca89616130f to your computer and use it in GitHub Desktop.
Simple Inputs ladder on single ADC pin.
import uasyncio as asyncio
from machine import ADC
import time
class Levels:
_last_level = None
debounce_ms = 200
none_level = 65000
callbacks = {}
def __init__(self, pin, levels, cb):
self.cb = cb
self.levels = sorted(levels)
self.adc = ADC(pin)
self._run = asyncio.create_task(
def on(self, level, cb):
self.callbacks[level] = cb
async def watch(self):
while True:
state = self.adc.read_u16()
for level in self.levels:
if self.is_level(state, level):
# The same level must be hold for some time to trigger,
# to avoid spontanous triggering due to static discharges etc.
await asyncio.sleep_ms(5)
if self.is_level(self.adc.read_u16(), level) and await self.release():
self._last_level = level
await asyncio.sleep_ms(self.debounce_ms)
async def release(self):
now = time.ticks_ms()
while (now + 1000) > time.ticks_ms():
if self.is_level(self.adc.read_u16(), self.none_level):
return True
await asyncio.sleep_ms(1)
return False
async def _cb(self, level):
if (level in self.callbacks and callable(self.callbacks[level])):
def is_level(self, state, level):
# Determine the correct level by providing a narrow window for the level
return min(level - 1000, level * 0.8) < state < max(level * 1.2, level + 1000)
Usage (in an asyc context)
SW1 = 3000
SW2 = 10000
Buttons = Levels(
levels=(SW1, SW2),
cb=lambda level: print(level)
Buttons.on(SW1, lambda: print("SW1 pressed"))
Buttons.on(SW2, lambda: print("SW2 pressed"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment