Last active
November 10, 2025 03:36
-
-
Save minimasoft/3784583858c96600b14894e1bd2dedba to your computer and use it in GitHub Desktop.
micropython time switch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from time import ticks_ms, ticks_diff, ticks_add | |
| from machine import Pin | |
| class ButtonFilter: | |
| def __init__(self, pin_number, bounce_filter=90): | |
| now = ticks_ms() | |
| self.pin = Pin(pin_number, Pin.IN, Pin.PULL_UP) | |
| self.bounce_filter = bounce_filter | |
| self.state = self.pin.value() | |
| self.next_state = self.state | |
| self.since = now | |
| def value(self): | |
| now = ticks_ms() | |
| reading = self.pin.value() | |
| if reading == self.next_state and self.next_state != self.state: | |
| if ticks_diff(now, self.since) > self.bounce_filter: | |
| self.state = self.next_state | |
| self.since = now | |
| elif reading != self.next_state: | |
| self.next_state = reading | |
| return self.state | |
| class ArgentinianOutput: # Inverted | |
| def __init__(self, pin_number, default=0): | |
| self.pin = Pin(pin_number, Pin.OUT) | |
| self.value(default) | |
| def on(self): | |
| self.pin.off() | |
| def off(self): | |
| self.pin.on() | |
| def value(self, value): | |
| if value: | |
| self.on() | |
| else: | |
| self.off() | |
| def prevent_flip_on_clock_rollover(now, state): | |
| if ticks_diff(state["power"]["until"], now) > 0 and not state["power"]["value"]: | |
| state["power"]["until"] = 0 | |
| def long_push_actions(now, state, reading): | |
| LONG_PUSH = 1500 | |
| if (state["button"]["value"] == reading) and (reading == 0): | |
| on_time = ticks_diff(now, state["button"]["since"]) | |
| if on_time > LONG_PUSH: | |
| if ticks_diff(state["power"]["since"], state["button"]["since"]) >= 0: | |
| state["power"]["until"] = now | |
| state["hodl"] = True | |
| else: | |
| state["power"]["until"] = 0 | |
| return True | |
| def push_actions(now, state, reading): | |
| PRESS_POWER_TIME = 5000 | |
| if reading != state["button"]["value"]: | |
| state["button"]["value"] = reading | |
| state["button"]["since"] = now | |
| if reading == 0: # pushed | |
| if state["power"]["until"] < now: | |
| state["power"]["until"] = now | |
| state["power"]["until"] = ticks_add( | |
| state["power"]["until"], PRESS_POWER_TIME | |
| ) | |
| print(f"power remaining: {ticks_diff(state['power']['until'], now)} ms") | |
| return True | |
| def update_output(now, state, reading): | |
| power_state = ticks_diff(state["power"]["until"], now) >= 0 | |
| if power_state != state["power"]["value"]: | |
| print(power_state) | |
| state["power"]["since"] = now | |
| state["power"]["value"] = power_state | |
| state["hodl"] = False | |
| return True | |
| # config | |
| inx = ButtonFilter(14) | |
| out = ArgentinianOutput(15) | |
| # bootstrap the state | |
| state = { | |
| "button": { | |
| "value": inx.value(), | |
| "since": ticks_ms(), | |
| }, | |
| "power": { | |
| "value": False, | |
| "until": 0, | |
| "since": ticks_ms(), | |
| }, | |
| "hodl": False, | |
| } | |
| while True: | |
| now = ticks_ms() | |
| reading = inx.value() | |
| prevent_flip_on_clock_rollover(now, state) | |
| long_push_actions(now, state, reading) | |
| push_actions(now, state, reading) | |
| if update_output(now, state, reading): | |
| out.value(state["power"]["value"]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment