2023-04-13 12:34:37 +00:00
|
|
|
# epaper.py micro-gui demo of multiple controls on an ePaper display type
|
|
|
|
# https://www.waveshare.com/pico-epaper-4.2.htm
|
|
|
|
# Use with setup_examples/pico_epaper_42_pico.py
|
|
|
|
|
|
|
|
# Released under the MIT License (MIT). See LICENSE.
|
|
|
|
# Copyright (c) 2023 Peter Hinch
|
|
|
|
|
|
|
|
# Initialise hardware and framebuf before importing modules.
|
|
|
|
# Create SSD instance. Must be done first because of RAM use.
|
|
|
|
import hardware_setup
|
|
|
|
|
|
|
|
from gui.core.ugui import Screen, ssd
|
|
|
|
from gui.core.writer import CWriter
|
|
|
|
import gui.fonts.arial10 as arial10 # Font for CWriter
|
2023-04-16 12:56:40 +00:00
|
|
|
import gui.fonts.freesans20 as large
|
|
|
|
|
2023-04-13 12:34:37 +00:00
|
|
|
from gui.core.colors import *
|
2023-04-16 17:24:33 +00:00
|
|
|
|
2023-04-13 12:34:37 +00:00
|
|
|
# Widgets
|
2023-04-16 17:24:33 +00:00
|
|
|
from gui.widgets import (
|
|
|
|
Label,
|
|
|
|
Dial,
|
|
|
|
Pointer,
|
|
|
|
Meter,
|
|
|
|
Scale,
|
|
|
|
Button,
|
|
|
|
ButtonList,
|
|
|
|
RadioButtons,
|
|
|
|
CloseButton,
|
|
|
|
Checkbox,
|
|
|
|
LED,
|
|
|
|
)
|
2023-04-16 12:56:40 +00:00
|
|
|
from gui.widgets.graph import CartesianGraph, Curve
|
2023-04-13 12:34:37 +00:00
|
|
|
|
2023-04-16 12:56:40 +00:00
|
|
|
from math import sin, pi
|
2023-04-13 12:34:37 +00:00
|
|
|
import cmath
|
|
|
|
import uasyncio as asyncio
|
|
|
|
import utime
|
|
|
|
import gc
|
|
|
|
|
2023-04-16 17:24:33 +00:00
|
|
|
|
2023-04-13 12:34:37 +00:00
|
|
|
async def full_refresh():
|
|
|
|
Screen.rfsh_done.clear() # Enable completion flag
|
|
|
|
await Screen.rfsh_done.wait() # Wait for a refresh to end
|
|
|
|
ssd.set_full()
|
|
|
|
Screen.rfsh_done.clear() # Enable completion flag
|
|
|
|
await Screen.rfsh_done.wait() # Wait for a single full refresh to end
|
|
|
|
ssd.set_partial()
|
|
|
|
|
|
|
|
|
|
|
|
class FooScreen(Screen):
|
|
|
|
def __init__(self):
|
|
|
|
buttons = []
|
|
|
|
|
|
|
|
# A ButtonList with two entries
|
|
|
|
table_buttonset = (
|
2023-04-16 17:24:33 +00:00
|
|
|
{"fgcolor": RED, "text": "Disable", "args": (buttons, True)},
|
|
|
|
{"fgcolor": GREEN, "text": "Enable", "args": (buttons, False)},
|
2023-04-13 12:34:37 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def tickcb(f, c):
|
|
|
|
if f > 0.8:
|
|
|
|
return RED
|
|
|
|
if f < -0.8:
|
|
|
|
return BLUE
|
|
|
|
return c
|
|
|
|
|
|
|
|
def bcb(b):
|
2023-04-16 17:24:33 +00:00
|
|
|
print("Button pressed", b)
|
2023-04-13 12:34:37 +00:00
|
|
|
|
|
|
|
super().__init__()
|
|
|
|
self.rb0 = None
|
|
|
|
self.bs0 = None
|
|
|
|
wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False)
|
2023-04-16 12:56:40 +00:00
|
|
|
wri_large = CWriter(ssd, large, GREEN, BLACK, verbose=False)
|
2023-04-16 17:24:33 +00:00
|
|
|
lbltim = Label(wri, 65, 100, "this is a test", bdcolor=RED)
|
|
|
|
|
|
|
|
m0 = Meter(
|
|
|
|
wri,
|
|
|
|
10,
|
|
|
|
240,
|
|
|
|
divisions=4,
|
|
|
|
ptcolor=YELLOW,
|
|
|
|
height=80,
|
|
|
|
width=15,
|
|
|
|
label="Meter",
|
|
|
|
style=Meter.BAR,
|
|
|
|
legends=("0.0", "0.5", "1.0"),
|
|
|
|
)
|
2023-04-13 12:34:37 +00:00
|
|
|
# Instantiate displayable objects. bgcolor forces complete redraw.
|
2023-04-16 17:24:33 +00:00
|
|
|
dial = Dial(
|
|
|
|
wri, 2, 2, height=75, ticks=12, bgcolor=BLACK, bdcolor=None, label=120
|
|
|
|
) # Border in fg color
|
|
|
|
scale = Scale(
|
|
|
|
wri, 2, 100, width=124, tickcb=tickcb, pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN
|
|
|
|
)
|
2023-04-13 12:34:37 +00:00
|
|
|
|
|
|
|
row = 105
|
|
|
|
col = 2
|
2023-04-16 17:24:33 +00:00
|
|
|
Label(wri, row, col, "Normal buttons")
|
2023-04-13 12:34:37 +00:00
|
|
|
# Four Button instances
|
|
|
|
row = 120
|
|
|
|
ht = 30
|
2023-04-16 17:24:33 +00:00
|
|
|
for i, s in enumerate(("a", "b", "c", "d")):
|
|
|
|
col = 2 + i * (ht + 5)
|
|
|
|
buttons.append(
|
|
|
|
Button(
|
|
|
|
wri,
|
|
|
|
row,
|
|
|
|
col,
|
|
|
|
height=ht,
|
|
|
|
callback=bcb,
|
|
|
|
text=s,
|
|
|
|
litcolor=RED,
|
|
|
|
shape=CIRCLE,
|
|
|
|
bgcolor=DARKGREEN,
|
|
|
|
)
|
|
|
|
)
|
2023-04-13 12:34:37 +00:00
|
|
|
|
|
|
|
# ButtonList
|
|
|
|
self.bs = ButtonList(self.callback)
|
|
|
|
self.bs0 = None
|
2023-04-16 17:24:33 +00:00
|
|
|
col += 50
|
|
|
|
Label(wri, row - 15, col, "ButtonList")
|
|
|
|
for t in table_buttonset: # Buttons overlay each other at same location
|
|
|
|
button = self.bs.add_button(
|
|
|
|
wri, row, col, shape=RECTANGLE, textcolor=BLUE, height=30, **t
|
|
|
|
)
|
|
|
|
if self.bs0 is None: # Save for reset button callback
|
2023-04-13 12:34:37 +00:00
|
|
|
self.bs0 = button
|
|
|
|
|
|
|
|
# Reset button
|
2023-04-16 17:24:33 +00:00
|
|
|
col += 60
|
|
|
|
btn = Button(
|
|
|
|
wri,
|
|
|
|
row,
|
|
|
|
col,
|
|
|
|
height=30,
|
|
|
|
callback=self.rstcb,
|
|
|
|
text="reset",
|
|
|
|
litcolor=RED,
|
|
|
|
fgcolor=GREEN,
|
|
|
|
bgcolor=DARKGREEN,
|
|
|
|
)
|
2023-04-13 12:34:37 +00:00
|
|
|
|
2023-04-16 12:56:40 +00:00
|
|
|
col = btn.mcol + 15
|
2023-04-13 12:34:37 +00:00
|
|
|
# Checkbox
|
2023-04-16 17:24:33 +00:00
|
|
|
Label(wri, row - 15, col, "Checkbox and LED")
|
2023-04-13 12:34:37 +00:00
|
|
|
Checkbox(wri, row, col, callback=self.cbcb)
|
2023-04-16 17:24:33 +00:00
|
|
|
col += 40
|
2023-04-13 12:34:37 +00:00
|
|
|
self.led = LED(wri, row, col, color=YELLOW, bdcolor=GREEN)
|
2023-04-16 12:56:40 +00:00
|
|
|
|
|
|
|
row = self.bs0.mrow + 5
|
|
|
|
col = 20
|
|
|
|
ht = 75
|
|
|
|
wd = 200
|
2023-04-16 17:24:33 +00:00
|
|
|
self.graph = CartesianGraph(wri, row, col, height=ht, width=wd, bdcolor=False)
|
|
|
|
Label(wri, row + ht + 5, col - 10, "-2.0")
|
|
|
|
Label(wri, row + ht + 5, col - 8 + int(wd // 2), "0.0")
|
|
|
|
lbl = Label(wri, row + ht + 5, col - 10 + wd, "2.0")
|
2023-04-16 12:56:40 +00:00
|
|
|
Label(wri_large, lbl.mrow + 5, col, "y = sinc(x)")
|
|
|
|
|
2023-04-13 17:37:21 +00:00
|
|
|
CloseButton(wri, bgcolor=BLACK)
|
2023-04-13 12:34:37 +00:00
|
|
|
asyncio.create_task(run(dial, lbltim, m0, scale))
|
|
|
|
|
|
|
|
def callback(self, button, buttons, val):
|
|
|
|
buttons[2].greyed_out(val)
|
|
|
|
|
|
|
|
def rstcb(self, button):
|
2023-04-16 17:24:33 +00:00
|
|
|
print("Reset button: init ButtonList, do full refresh.")
|
2023-04-13 12:34:37 +00:00
|
|
|
self.bs.value(self.bs0)
|
|
|
|
asyncio.create_task(full_refresh())
|
|
|
|
|
|
|
|
def cbcb(self, cb):
|
|
|
|
self.led.value(cb.value())
|
|
|
|
gc.collect()
|
2023-04-16 17:24:33 +00:00
|
|
|
print("Free RAM:", gc.mem_free())
|
2023-04-13 12:34:37 +00:00
|
|
|
|
2023-04-16 12:56:40 +00:00
|
|
|
def after_open(self):
|
|
|
|
def populate():
|
|
|
|
x = -0.998
|
|
|
|
while x < 1.01:
|
|
|
|
z = 6 * pi * x
|
|
|
|
y = sin(z) / z
|
|
|
|
yield x, y
|
|
|
|
x += 0.05
|
|
|
|
|
|
|
|
Curve(self.graph, None, populate())
|
2023-05-31 15:16:41 +00:00
|
|
|
asyncio.create_task(full_refresh())
|
2023-04-16 12:56:40 +00:00
|
|
|
|
|
|
|
|
2023-04-13 12:34:37 +00:00
|
|
|
async def run(dial, lbltim, m0, scale):
|
2023-04-16 17:24:33 +00:00
|
|
|
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
|
|
|
|
months = (
|
|
|
|
"Jan",
|
|
|
|
"Feb",
|
|
|
|
"March",
|
|
|
|
"April",
|
|
|
|
"May",
|
|
|
|
"June",
|
|
|
|
"July",
|
|
|
|
"Aug",
|
|
|
|
"Sept",
|
|
|
|
"Oct",
|
|
|
|
"Nov",
|
|
|
|
"Dec",
|
|
|
|
)
|
|
|
|
uv = lambda phi: cmath.rect(1, phi) # Return a unit vector of phase phi
|
2023-04-13 12:34:37 +00:00
|
|
|
pi = cmath.pi
|
|
|
|
hrs = Pointer(dial)
|
|
|
|
mins = Pointer(dial)
|
|
|
|
secs = Pointer(dial)
|
|
|
|
|
2023-04-16 17:24:33 +00:00
|
|
|
hstart = 0 + 0.7j # Pointer lengths and position at top
|
2023-04-13 12:34:37 +00:00
|
|
|
mstart = 0 + 0.92j
|
2023-04-16 17:24:33 +00:00
|
|
|
sstart = 0 + 0.92j
|
2023-04-13 12:34:37 +00:00
|
|
|
|
|
|
|
cv = -1.0 # Scale
|
|
|
|
dv = 0.005
|
|
|
|
while True:
|
|
|
|
t = utime.localtime()
|
2023-04-16 17:24:33 +00:00
|
|
|
hrs.value(hstart * uv(-t[3] * pi / 6 - t[4] * pi / 360), YELLOW)
|
|
|
|
mins.value(mstart * uv(-t[4] * pi / 30), YELLOW)
|
|
|
|
secs.value(sstart * uv(-t[5] * pi / 30), RED)
|
|
|
|
lbltim.value("{:02d}.{:02d}.{:02d}".format(t[3], t[4], t[5]))
|
|
|
|
dial.text("{} {} {} {}".format(days[t[6]], t[2], months[t[1] - 1], t[0]))
|
|
|
|
m0.value(t[5] / 60)
|
2023-04-13 12:34:37 +00:00
|
|
|
scale.value(cv)
|
|
|
|
await asyncio.sleep_ms(200)
|
|
|
|
cv += dv
|
|
|
|
if abs(cv) > 1.0:
|
|
|
|
dv = -dv
|
|
|
|
cv += dv
|
|
|
|
|
|
|
|
|
|
|
|
def test():
|
2023-04-16 17:24:33 +00:00
|
|
|
print("Testing micro-gui...")
|
2023-04-13 17:37:21 +00:00
|
|
|
Screen.change(FooScreen)
|
|
|
|
print("End")
|
|
|
|
ssd.sleep() # Tidy shutdown of EPD
|
2023-04-13 12:34:37 +00:00
|
|
|
|
2023-04-16 17:24:33 +00:00
|
|
|
|
2023-04-13 12:34:37 +00:00
|
|
|
test()
|