def setup_timer(callback, delay, initial_delay=0, data=()): next_run = ticks_add(ticks_ms(), initial_delay) while True: now = ticks_ms() if ticks_less(next_run, now): callback(now, data) next_run = ticks_add(next_run, delay) yield
def __init__(self, callback, delay, initial=None, data=()): now = ticks_ms() self.callback = callback self.delay = int(delay * 1000) if initial is None: self.initial_delay = self.delay else: self.initial_delay = int(initial * 1000) self.data = data self.next_run = ticks_add(now, self.initial_delay)
def update_all(): updated = False now = ticks_ms() for timer in all_timers: if ticks_less(timer.next_run, now): timer.run() updated = True else: break if updated: all_timers.sort(key=Tick)
def update(self): super().update() if self._pushed(): self.last_change_ms = ticks_ms() self.short_counter = self.short_counter + 1 elif self._released(): self.last_change_ms = ticks_ms() if self.long_registered: self.long_registered = False self.long_showed = False else: duration = ticks_diff(ticks_ms(), self.last_change_ms) if (not self.long_registered and self.value != self.active_down and duration > self.long_duration_ms): self.long_registered = True self.short_to_show = self.short_counter - 1 self.short_counter = 0 elif (self.short_counter > 0 and self.value == self.active_down and duration > self.short_duration_ms): self.short_to_show = self.short_counter self.short_counter = 0
def __init__(self, pin, short_duration_ms=200, long_duration_ms=500, active_down=True, **kwargs): self.short_duration_ms = short_duration_ms self.long_duration_ms = long_duration_ms self.active_down = active_down self.last_change_ms = ticks_ms() self.short_counter = 0 self.short_to_show = 0 self.long_registered = False self.long_showed = False super().__init__(pin, **kwargs)
def update(self): """Update the debouncer state. MUST be called frequently""" now_ticks = ticks_ms() self._unset_state(_CHANGED_STATE) current_state = self.function() if current_state != self._get_state(_UNSTABLE_STATE): self._last_bounce_ticks = now_ticks self._toggle_state(_UNSTABLE_STATE) else: if ticks_diff(now_ticks, self._last_bounce_ticks) >= self._interval_ticks: if current_state != self._get_state(_DEBOUNCED_STATE): self._last_bounce_ticks = now_ticks self._toggle_state(_DEBOUNCED_STATE) self._set_state(_CHANGED_STATE) self._last_duration_ticks = ticks_diff( now_ticks, self._state_changed_ticks) self._state_changed_ticks = now_ticks
TIMER_1_DELAY = 5000 # every 2 seconds: TIMER_2_DELAY = 2000 # Change *_next_run to now or 0 if you want to trigger it on the first loop. # Or "now + X" to trigger at a different time the first time. """Examples: - Trigger the first run after the DELAY next_run = now + DELAY - Trigger the first run in the first loop next_run = 0 - Trigger the first run after 10 seconds next_run = now + 10_000 """ now = ticks_ms() timer_1_next_run = ticks_add(now, TIMER_1_DELAY) timer_2_next_run = ticks_add(now, TIMER_2_DELAY) while True: # set "now" only once per loop, it's the time reference for the loop. now = ticks_ms() if ticks_less(timer_1_next_run, now): # Next time based on last time # This avoids drifting, but can cause multiple triggerings if the rest # of the loop takes too long and delays are too short. timer_1_next_run = ticks_add(timer_1_next_run, TIMER_1_DELAY) print("TIMER 1 TRIGGERED", time.monotonic()) if ticks_less(timer_2_next_run, now): # Next time based on current time. # This causes drifting, but guarantees a minimum delay between triggers.
def update(self, now=ticks_ms()): if ticks_less(self.next_run, now): self.run()
def restart(self): now = ticks_ms() if self.initial_delay == 0: self.run() else: self.next_run = ticks_add(now, self.initial_delay)
def current_duration(self): """Return the number of seconds since the most recent transition.""" return ticks_diff(ticks_ms(), self._state_changed_ticks) / _TICKS_PER_SEC