2021-01-23 18:53:54 +00:00
|
|
|
# epd29_async.py Demo program for nano_gui on an Adafruit 2.9" flexible ePaper screen
|
2021-01-13 17:21:32 +00:00
|
|
|
|
|
|
|
# Released under the MIT License (MIT). See LICENSE.
|
|
|
|
# Copyright (c) 2020 Peter Hinch
|
|
|
|
|
2021-01-15 16:54:29 +00:00
|
|
|
# color_setup must set landcsape True, asyn True and must not set demo_mode
|
2021-01-23 18:53:54 +00:00
|
|
|
from cmath import exp, pi
|
2024-05-12 10:19:11 +00:00
|
|
|
import asyncio
|
2021-01-13 17:21:32 +00:00
|
|
|
from color_setup import ssd
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-17 16:08:08 +00:00
|
|
|
# On a monochrome display Writer is more efficient than CWriter.
|
2021-01-13 17:21:32 +00:00
|
|
|
from gui.core.writer import Writer
|
|
|
|
from gui.core.nanogui import refresh
|
|
|
|
from gui.widgets.meter import Meter
|
|
|
|
from gui.widgets.label import Label
|
2021-01-23 18:53:54 +00:00
|
|
|
from gui.widgets.dial import Dial, Pointer
|
2021-01-13 17:21:32 +00:00
|
|
|
|
|
|
|
# Fonts
|
|
|
|
import gui.fonts.arial10 as arial10
|
|
|
|
import gui.fonts.font6 as small
|
|
|
|
|
2024-06-07 13:55:19 +00:00
|
|
|
# ssd._asyn = True # HACK to make it config agnostic
|
2021-01-13 17:21:32 +00:00
|
|
|
# Some ports don't support uos.urandom.
|
|
|
|
# See https://github.com/peterhinch/micropython-samples/tree/master/random
|
2024-05-12 10:19:11 +00:00
|
|
|
def xorshift64star(modulo, seed=0xF9AC6BA4):
|
2021-01-13 17:21:32 +00:00
|
|
|
x = seed
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-13 17:21:32 +00:00
|
|
|
def func():
|
|
|
|
nonlocal x
|
|
|
|
x ^= x >> 12
|
2024-05-12 10:19:11 +00:00
|
|
|
x ^= (x << 25) & 0xFFFFFFFFFFFFFFFF # modulo 2**64
|
2021-01-13 17:21:32 +00:00
|
|
|
x ^= x >> 27
|
|
|
|
return (x * 0x2545F4914F6CDD1D) % modulo
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-13 17:21:32 +00:00
|
|
|
return func
|
|
|
|
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-24 10:37:56 +00:00
|
|
|
async def compass(evt):
|
2021-01-23 18:53:54 +00:00
|
|
|
wri = Writer(ssd, arial10, verbose=False)
|
2021-01-13 17:21:32 +00:00
|
|
|
wri.set_clip(False, False, False)
|
2021-01-23 18:53:54 +00:00
|
|
|
v1 = 0 + 0.9j
|
|
|
|
v2 = exp(0 - (pi / 6) * 1j)
|
2024-05-12 10:19:11 +00:00
|
|
|
dial = Dial(
|
|
|
|
wri, 5, 5, height=75, ticks=12, bdcolor=None, label="Direction", style=Dial.COMPASS
|
|
|
|
)
|
2021-01-23 18:53:54 +00:00
|
|
|
ptr = Pointer(dial)
|
2021-01-13 17:21:32 +00:00
|
|
|
while True:
|
2021-01-23 18:53:54 +00:00
|
|
|
ptr.value(v1)
|
|
|
|
v1 *= v2
|
|
|
|
await evt.wait()
|
|
|
|
|
2021-01-13 17:21:32 +00:00
|
|
|
|
|
|
|
async def multi_fields(evt):
|
|
|
|
wri = Writer(ssd, small, verbose=False)
|
|
|
|
wri.set_clip(False, False, False)
|
|
|
|
|
|
|
|
nfields = []
|
|
|
|
dy = small.height() + 10
|
|
|
|
row = 2
|
|
|
|
col = 100
|
2024-05-12 10:19:11 +00:00
|
|
|
width = wri.stringlen("99.990")
|
|
|
|
for txt in ("X:", "Y:", "Z:"):
|
2021-01-13 17:21:32 +00:00
|
|
|
Label(wri, row, col, txt)
|
|
|
|
nfields.append(Label(wri, row, col, width, bdcolor=None)) # Draw border
|
|
|
|
row += dy
|
|
|
|
|
2024-05-12 10:19:11 +00:00
|
|
|
random = xorshift64star(2 ** 24 - 1)
|
2021-01-13 17:21:32 +00:00
|
|
|
while True:
|
|
|
|
for _ in range(10):
|
|
|
|
for field in nfields:
|
|
|
|
value = random() / 167772
|
2024-05-12 10:19:11 +00:00
|
|
|
field.value("{:5.2f}".format(value))
|
2021-01-13 17:21:32 +00:00
|
|
|
await evt.wait()
|
|
|
|
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-13 17:21:32 +00:00
|
|
|
async def meter(evt):
|
|
|
|
wri = Writer(ssd, arial10, verbose=False)
|
2021-01-23 18:53:54 +00:00
|
|
|
wri.set_clip(False, False, False)
|
2021-01-13 17:21:32 +00:00
|
|
|
row = 10
|
2021-01-23 18:53:54 +00:00
|
|
|
col = 170
|
2024-05-12 10:19:11 +00:00
|
|
|
args = {"height": 80, "width": 15, "divisions": 4, "style": Meter.BAR}
|
|
|
|
m0 = Meter(wri, row, col, legends=("0.0", "0.5", "1.0"), **args)
|
|
|
|
m1 = Meter(wri, row, col + 40, legends=("-1", "0", "+1"), **args)
|
|
|
|
m2 = Meter(wri, row, col + 80, legends=("-1", "0", "+1"), **args)
|
|
|
|
random = xorshift64star(2 ** 24 - 1)
|
2021-01-13 17:21:32 +00:00
|
|
|
while True:
|
|
|
|
steps = 10
|
|
|
|
for n in range(steps + 1):
|
|
|
|
m0.value(random() / 16777216)
|
2024-05-12 10:19:11 +00:00
|
|
|
m1.value(n / steps)
|
|
|
|
m2.value(1 - n / steps)
|
2021-01-13 17:21:32 +00:00
|
|
|
await evt.wait()
|
|
|
|
|
2024-05-12 10:19:11 +00:00
|
|
|
|
2021-01-13 17:21:32 +00:00
|
|
|
async def main():
|
|
|
|
refresh(ssd, True) # Clear display
|
2024-06-07 13:55:19 +00:00
|
|
|
await ssd.complete.wait()
|
2024-05-12 10:19:11 +00:00
|
|
|
print("Ready")
|
2021-01-13 17:21:32 +00:00
|
|
|
evt = asyncio.Event()
|
|
|
|
asyncio.create_task(meter(evt))
|
|
|
|
asyncio.create_task(multi_fields(evt))
|
2021-01-23 18:53:54 +00:00
|
|
|
asyncio.create_task(compass(evt))
|
2021-01-13 17:21:32 +00:00
|
|
|
while True:
|
|
|
|
# Normal procedure before refresh, but 10s sleep should mean it always returns immediately
|
2024-06-07 13:55:19 +00:00
|
|
|
await ssd.complete.wait()
|
2021-01-13 17:21:32 +00:00
|
|
|
refresh(ssd) # Launches ._as_show()
|
2024-06-07 13:55:19 +00:00
|
|
|
await ssd.updated.wait()
|
2021-01-13 17:21:32 +00:00
|
|
|
# Content has now been shifted out so coros can update
|
|
|
|
# framebuffer in background
|
|
|
|
evt.set()
|
|
|
|
evt.clear()
|
2021-01-23 18:53:54 +00:00
|
|
|
await asyncio.sleep(10) # Allow for slow refresh
|
2024-05-12 10:19:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
tstr = """Test of asynchronous code updating the EPD. This should
|
2021-01-13 17:21:32 +00:00
|
|
|
not be run for long periods as the EPD should not be updated more
|
|
|
|
frequently than every 180s.
|
2024-05-12 10:19:11 +00:00
|
|
|
"""
|
2021-01-13 17:21:32 +00:00
|
|
|
|
|
|
|
print(tstr)
|
|
|
|
|
|
|
|
try:
|
|
|
|
asyncio.run(main())
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
# Defensive code: avoid leaving EPD hardware in an undefined state.
|
2024-05-12 10:19:11 +00:00
|
|
|
print("Waiting for display to become idle")
|
2021-01-15 16:54:29 +00:00
|
|
|
ssd.sleep() # Synchronous code. May block for 5s if display is updating.
|
2021-01-13 17:21:32 +00:00
|
|
|
finally:
|
|
|
|
_ = asyncio.new_event_loop()
|