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

183 wiersze
6.2 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
from gui.core.colors import *
# Widgets
from gui.widgets.label import Label
from gui.widgets.dial import Dial, Pointer
from gui.widgets.meter import Meter
from gui.widgets.scale import Scale
from gui.widgets.buttons import Button, ButtonList, RadioButtons, CloseButton
from gui.widgets.checkbox import Checkbox
from gui.widgets.led import LED
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)},
)
table_radiobuttons = (
{'text' : '1', 'args' : ('1',)},
{'text' : '2', 'args' : ('2',)},
{'text' : '3', 'args' : ('3',)},
{'text' : '4', 'args' : ('4',)},
)
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)
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 example', 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 = 2
row = 170
Label(wri, row, col, 'Radio buttons')
# Radio buttons
row = 185
self.rb = RadioButtons(BLUE, self.rbcb) # color of selected button
self.rb0 = None
for t in table_radiobuttons:
button = self.rb.add_button(wri, row, col, textcolor = WHITE,
fgcolor = BLUE, bgcolor = DARKBLUE, shape=CIRCLE, height = 30, **t)
if self.rb0 is None: # Save for reset button callback
self.rb0 = button
col+= 35
# Checkbox
col+= 35
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)
CloseButton(wri, bgcolor=BLACK)
asyncio.create_task(run(dial, lbltim, m0, scale))
def callback(self, button, buttons, val):
buttons[2].greyed_out(val)
def rbcb(self, button, val):
print('RadioButtons callback', val)
def rstcb(self, button):
print('Reset button: init ButtonList and RadioButtons, do full refresh.')
self.bs.value(self.bs0)
self.rb.value(self.rb0)
asyncio.create_task(full_refresh())
def cbcb(self, cb):
self.led.value(cb.value())
gc.collect()
print('Free RAM:', gc.mem_free())
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()