Minor changes to primitives.

pull/18/head
Peter Hinch 2022-08-13 10:44:08 +01:00
rodzic 423f61fdce
commit ce82fe6aa5
6 zmienionych plików z 84 dodań i 69 usunięć

Wyświetl plik

@ -74,7 +74,7 @@ class Input:
_vb and print("Using encoder.") _vb and print("Using encoder.")
if incr is None or decr is None: if incr is None or decr is None:
raise ValueError("Must specify pins for encoder.") raise ValueError("Must specify pins for encoder.")
from gui.primitives.encoder import Encoder from gui.primitives import Encoder
self._enc = Encoder(incr, decr, div=encoder, callback=Screen.adjust) self._enc = Encoder(incr, decr, div=encoder, callback=Screen.adjust)
else: else:

Wyświetl plik

@ -1,26 +1,7 @@
# __init__.py Common functions for uasyncio primitives # __init__.py Common functions for uasyncio primitives used bu ugui
# Copyright (c) 2018-2020 Peter Hinch # Copyright (c) 2018-2022 Peter Hinch
# Released under the MIT License (MIT) - see LICENSE file # Released under the MIT License (MIT) - see LICENSE file
_attrs = {
"Delay_ms": "delay_ms",
"Switch": "switch",
"Pushbutton": "pushbutton",
"ESP32Touch": "pushbutton",
}
# Lazy loader, effectively does:
# global attr
# from .mod import attr
# Filched from uasyncio.__init__.py
def __getattr__(attr):
mod = _attrs.get(attr, None)
if mod is None:
raise AttributeError(attr)
value = getattr(__import__(mod, None, None, True, 1), attr)
globals()[attr] = value
return value
try: try:
import uasyncio as asyncio import uasyncio as asyncio
@ -41,10 +22,22 @@ def launch(func, tup_args):
res = asyncio.create_task(res) res = asyncio.create_task(res)
return res return res
def set_global_exception(): _attrs = {
def _handle_exception(loop, context): "Delay_ms": "delay_ms",
import sys "Encoder": "encoder",
sys.print_exception(context["exception"]) "Pushbutton": "pushbutton",
sys.exit() "ESP32Touch": "pushbutton",
loop = asyncio.get_event_loop() "Switch": "switch",
loop.set_exception_handler(_handle_exception) }
# Copied from uasyncio.__init__.py
# Lazy loader, effectively does:
# global attr
# from .mod import attr
def __getattr__(attr):
mod = _attrs.get(attr, None)
if mod is None:
raise AttributeError(attr)
value = getattr(__import__(mod, None, None, True, 1), attr)
globals()[attr] = value
return value

Wyświetl plik

@ -26,6 +26,7 @@ class Delay_ms:
self._trig = asyncio.ThreadSafeFlag() self._trig = asyncio.ThreadSafeFlag()
self._tout = asyncio.Event() # Timeout event self._tout = asyncio.Event() # Timeout event
self.wait = self._tout.wait # Allow: await wait_ms.wait() self.wait = self._tout.wait # Allow: await wait_ms.wait()
self.clear = self._tout.clear
self._ttask = self._fake # Timer task self._ttask = self._fake # Timer task
self._mtask = asyncio.create_task(self._run()) #Main task self._mtask = asyncio.create_task(self._run()) #Main task
@ -40,7 +41,6 @@ class Delay_ms:
async def _timer(self, dt): async def _timer(self, dt):
await asyncio.sleep_ms(dt) await asyncio.sleep_ms(dt)
self._tout.set() # Only gets here if not cancelled. self._tout.set() # Only gets here if not cancelled.
self._tout.clear()
self._busy = False self._busy = False
if self._func is not None: if self._func is not None:
self._retn = launch(self._func, self._args) self._retn = launch(self._func, self._args)

Wyświetl plik

@ -27,17 +27,24 @@ class Pushbutton:
self._dd = False # Ditto for doubleclick self._dd = False # Ditto for doubleclick
self.sense = pin.value() if sense is None else sense # Convert from electrical to logical value self.sense = pin.value() if sense is None else sense # Convert from electrical to logical value
self.state = self.rawstate() # Initial state self.state = self.rawstate() # Initial state
self._run = asyncio.create_task(self.buttoncheck()) # Thread runs forever self._run = asyncio.create_task(self._go()) # Thread runs forever
def press_func(self, func=False, args=()): def press_func(self, func=False, args=()):
self._tf = func if func is None:
self.press = asyncio.Event()
self._tf = self.press.set if func is None else func
self._ta = args self._ta = args
def release_func(self, func=False, args=()): def release_func(self, func=False, args=()):
self._ff = func if func is None:
self.release = asyncio.Event()
self._ff = self.release.set if func is None else func
self._fa = args self._fa = args
def double_func(self, func=False, args=()): def double_func(self, func=False, args=()):
if func is None:
self.double = asyncio.Event()
func = self.double.set
self._df = func self._df = func
self._da = args self._da = args
if func: # If double timer already in place, leave it if func: # If double timer already in place, leave it
@ -47,6 +54,9 @@ class Pushbutton:
self._dd = False # Clearing down double func self._dd = False # Clearing down double func
def long_func(self, func=False, args=()): def long_func(self, func=False, args=()):
if func is None:
self.long = asyncio.Event()
func = self.long.set
if func: if func:
if self._ld: if self._ld:
self._ld.callback(func, args) self._ld.callback(func, args)
@ -69,41 +79,44 @@ class Pushbutton:
if not self._ld or (self._ld and not self._ld()): if not self._ld or (self._ld and not self._ld()):
launch(self._ff, self._fa) launch(self._ff, self._fa)
async def buttoncheck(self): def _check(self, state):
while True: if state == self.state:
state = self.rawstate() return
# State has changed: act on it now. # State has changed: act on it now.
if state != self.state: self.state = state
self.state = state if state: # Button pressed: launch pressed func
if state: # Button pressed: launch pressed func if self._tf:
if self._tf: launch(self._tf, self._ta)
launch(self._tf, self._ta) if self._ld: # There's a long func: start long press delay
if self._ld: # There's a long func: start long press delay self._ld.trigger(Pushbutton.long_press_ms)
self._ld.trigger(Pushbutton.long_press_ms) if self._df:
if self._df: if self._dd(): # Second click: timer running
if self._dd(): # Second click: timer running self._dd.stop()
self._dd.stop() self._dblpend = False
self._dblpend = False self._dblran = True # Prevent suppressed launch on release
self._dblran = True # Prevent suppressed launch on release launch(self._df, self._da)
launch(self._df, self._da) else:
else: # First click: start doubleclick timer
# First click: start doubleclick timer self._dd.trigger(Pushbutton.double_click_ms)
self._dd.trigger(Pushbutton.double_click_ms) self._dblpend = True # Prevent suppressed launch on release
self._dblpend = True # Prevent suppressed launch on release else: # Button release. Is there a release func?
else: # Button release. Is there a release func? if self._ff:
if self._ff: if self._supp:
if self._supp: d = self._ld
d = self._ld # If long delay exists, is running and doubleclick status is OK
# If long delay exists, is running and doubleclick status is OK if not self._dblpend and not self._dblran:
if not self._dblpend and not self._dblran: if (d and d()) or not d:
if (d and d()) or not d:
launch(self._ff, self._fa)
else:
launch(self._ff, self._fa) launch(self._ff, self._fa)
if self._ld: else:
self._ld.stop() # Avoid interpreting a second click as a long push launch(self._ff, self._fa)
self._dblran = False if self._ld:
# Ignore state changes until switch has settled self._ld.stop() # Avoid interpreting a second click as a long push
self._dblran = False
async def _go(self):
while True:
self._check(self.rawstate())
# Ignore state changes until switch has settled. Also avoid hogging CPU.
# See https://github.com/peterhinch/micropython-async/issues/69 # See https://github.com/peterhinch/micropython-async/issues/69
await asyncio.sleep_ms(Pushbutton.debounce_ms) await asyncio.sleep_ms(Pushbutton.debounce_ms)

Wyświetl plik

@ -1,4 +1,4 @@
# color_setup.py Customise for your hardware config # hardware_setup.py Customise for your hardware config
# Released under the MIT License (MIT). See LICENSE. # Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch, Ihor Nehrutsa # Copyright (c) 2021 Peter Hinch, Ihor Nehrutsa

Wyświetl plik

@ -1,8 +1,17 @@
# color_setup.py Customise for your hardware config # hardware_setup.py Customise for your hardware config
# Released under the MIT License (MIT). See LICENSE. # Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch, Ihor Nehrutsa # Copyright (c) 2021 Peter Hinch, Ihor Nehrutsa
# TTGO T-Display 1.14" 135*240(Pixel) based on ST7789V
# http://www.lilygo.cn/claprod_view.aspx?TypeId=62&Id=1274
# http://www.lilygo.cn/prod_view.aspx?TypeId=50044&Id=1126
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/image/pinmap.jpg
# https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/schematic/ESP32-TFT(6-26).pdf
# This version is based on a touch button interface.
from machine import Pin, SPI, ADC, freq from machine import Pin, SPI, ADC, freq
import gc import gc