# 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()