micropython-micro-gui/gui/demos/epaper.py

182 wiersze
6.0 KiB
Python

# 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
import gui.fonts.freesans20 as large
from gui.core.colors import *
# Widgets
from gui.widgets import Label, Dial, Pointer, Meter, Scale, Button, ButtonList, RadioButtons, CloseButton, Checkbox, LED
from gui.widgets.graph import CartesianGraph, Curve
from math import sin, pi
import cmath
import uasyncio as asyncio
import utime
import gc
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 = (
{'fgcolor' : RED, 'text' : 'Disable', 'args' : (buttons, True)},
{'fgcolor' : GREEN, 'text' : 'Enable', 'args' : (buttons, False)},
)
def tickcb(f, c):
if f > 0.8:
return RED
if f < -0.8:
return BLUE
return c
def bcb(b):
print('Button pressed', b)
super().__init__()
self.rb0 = None
self.bs0 = None
wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False)
wri_large = CWriter(ssd, large, GREEN, BLACK, verbose=False)
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'))
# Instantiate displayable objects. bgcolor forces complete redraw.
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)
row = 105
col = 2
Label(wri, row, col, 'Normal buttons')
# Four Button instances
row = 120
ht = 30
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))
# ButtonList
self.bs = ButtonList(self.callback)
self.bs0 = None
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
self.bs0 = button
# Reset button
col+= 60
btn = Button(wri, row, col, height=30, callback=self.rstcb, text='reset', litcolor=RED, fgcolor=GREEN, bgcolor=DARKGREEN)
col = btn.mcol + 15
# Checkbox
Label(wri, row - 15, col, 'Checkbox and LED')
Checkbox(wri, row, col, callback=self.cbcb)
col+= 40
self.led = LED(wri, row, col, color=YELLOW, bdcolor=GREEN)
row = self.bs0.mrow + 5
col = 20
ht = 75
wd = 200
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')
Label(wri_large, lbl.mrow + 5, col, "y = sinc(x)")
CloseButton(wri, bgcolor=BLACK)
asyncio.create_task(run(dial, lbltim, m0, scale))
def callback(self, button, buttons, val):
buttons[2].greyed_out(val)
def rstcb(self, button):
print('Reset button: init ButtonList, do full refresh.')
self.bs.value(self.bs0)
asyncio.create_task(full_refresh())
def cbcb(self, cb):
self.led.value(cb.value())
gc.collect()
print('Free RAM:', gc.mem_free())
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())
async def run(dial, lbltim, m0, scale):
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
pi = cmath.pi
hrs = Pointer(dial)
mins = Pointer(dial)
secs = Pointer(dial)
hstart = 0 + 0.7j # Pointer lengths and position at top
mstart = 0 + 0.92j
sstart = 0 + 0.92j
cv = -1.0 # Scale
dv = 0.005
while True:
t = utime.localtime()
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)
scale.value(cv)
await asyncio.sleep_ms(200)
cv += dv
if abs(cv) > 1.0:
dv = -dv
cv += dv
def test():
print('Testing micro-gui...')
Screen.change(FooScreen)
print("End")
ssd.sleep() # Tidy shutdown of EPD
test()