def meter(): print('Meter test.') refresh(ssd, True) # Clear any prior image color = lambda v: RED if v > 0.7 else YELLOW if v > 0.5 else GREEN txt = lambda v: 'ovr' if v > 0.7 else 'high' if v > 0.5 else 'ok' m0 = Meter(wri, 5, 2, divisions=4, ptcolor=YELLOW, label='left', style=Meter.BAR, legends=('0.0', '0.5', '1.0')) l0 = LED(wri, ssd.height - 16 - wri.height, 2, bdcolor=YELLOW, label='over') m1 = Meter(wri, 5, 50, divisions=4, ptcolor=YELLOW, label='right', style=Meter.BAR, legends=('0.0', '0.5', '1.0')) l1 = LED(wri, ssd.height - 16 - wri.height, 50, bdcolor=YELLOW, label='over') m2 = Meter(wri, 5, 98, divisions=4, ptcolor=YELLOW, label='bass', style=Meter.BAR, legends=('0.0', '0.5', '1.0')) l2 = LED(wri, ssd.height - 16 - wri.height, 98, bdcolor=YELLOW, label='over') steps = 10 for n in range(steps): v = int.from_bytes(uos.urandom(3), 'little') / 16777216 m0.value(v, color(v)) l0.color(color(v)) l0.text(txt(v), fgcolor=color(v)) v = n / steps m1.value(v, color(v)) l1.color(color(v)) l1.text(txt(v), fgcolor=color(v)) v = 1 - n / steps m2.value(v, color(v)) l2.color(color(v)) l2.text(txt(v), fgcolor=color(v)) refresh(ssd) utime.sleep(1)
def cart(): print('Cartesian data test.') def populate_1(func): x = -1 while x < 1.01: yield x, func(x) # x, y x += 0.1 def populate_2(): x = -1 while x < 1.01: yield x, x**2 # x, y x += 0.1 refresh(ssd, True) # Clear any prior image g = CartesianGraph(wri, 2, 2, yorigin=2, fgcolor=WHITE, gridcolor=LIGHTGREEN) # Asymmetric y axis curve1 = Curve(g, YELLOW, populate_1(lambda x: x**3 + x**2 - x, )) # args demo curve2 = Curve(g, RED, populate_2()) refresh(ssd)
def aclock(): uv = lambda phi : cmath.rect(1, phi) # Return a unit vector of phase phi pi = cmath.pi days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday') months = ('Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec') # Instantiate CWriter CWriter.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False) wri.set_clip(True, True, False) # Instantiate displayable objects dial = Dial(wri, 2, 2, height = 75, ticks = 12, bdcolor=None, label=120, pip=False) # Border in fg color lbltim = Label(wri, 5, 85, 35) 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 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])) refresh(ssd) utime.sleep(1)
def multi_fields(use_spi=False, soft=True): ssd = setup(use_spi, soft) # Create a display instance Writer.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = Writer(ssd, small, verbose=False) wri.set_clip(False, False, False) nfields = [] dy = small.height() + 6 y = 2 col = 15 width = wri.stringlen('99.99') for txt in ('X:', 'Y:', 'Z:'): Label(wri, y, 0, txt) nfields.append(Label(wri, y, col, width, bdcolor=None)) # Draw border y += dy random = xorshift64star(2**24 - 1) for _ in range(10): for field in nfields: value = random() / 167772 field.value('{:5.2f}'.format(value)) refresh(ssd) utime.sleep(1) Label(wri, 0, 64, ' DONE ', True) refresh(ssd)
def main(): print('alevel test is running.') CWriter.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False) wri.set_clip(True, True, False) acc = pyb.Accel() dial = Dial(wri, 5, 5, height=75, ticks=12, bdcolor=None, label='Tilt Pyboard', style=Dial.COMPASS, pip=YELLOW) # Border in fg color ptr = Pointer(dial) scale = 1 / 40 while True: x, y, z = acc.filtered_xyz() # Depending on relative alignment of display and Pyboard this line may # need changing: swap x and y or change signs so arrow points in direction # board is tilted. ptr.value(-y * scale + 1j * x * scale, YELLOW) refresh(ssd) utime.sleep_ms(200)
async def clip(wri): ss = ('clip demo', 'short', 'longer line', 'much longer line with spaces', 'antidisestablishmentarianism', 'line with\nline break', 'Done') tb = Textbox(wri, *pargs, clip=True, **tbargs) for s in ss: tb.append(s, ntrim=100) # Default line=None scrolls to show most recent refresh(ssd) await asyncio.sleep(1)
def main(): refresh(ssd, True) graph() compass() meter() labels() ssd.wait_until_ready() refresh(ssd) print('Waiting for display update') ssd.wait_until_ready()
def compass(x): print('Compass test.') refresh(ssd, True) # Clear any prior image dial = Dial(wri, 5, 5, height = 75, bdcolor=None, label=50, style = Dial.COMPASS) bearing = Pointer(dial) bearing.value(0 + 1j, RED) dh = cmath.rect(1, -cmath.pi/30) # Rotate by 6 degrees CW for n in range(x): utime.sleep_ms(200) bearing.value(bearing.value() * dh, RED) refresh(ssd)
def rt_polar(): print('Simulate realtime polar data acquisition.') refresh(ssd, True) # Clear any prior image g = PolarGraph(wri, 2, 2, fgcolor=WHITE, gridcolor=LIGHTGREEN) curvey = PolarCurve(g, YELLOW) curver = PolarCurve(g, RED) for x in range(100): curvey.point(cmath.rect(x / 100, -x * cmath.pi / 30)) curver.point(cmath.rect((100 - x) / 100, -x * cmath.pi / 30)) utime.sleep_ms(60) refresh(ssd)
async def meter(n, x, text, t): print('Meter {} test.'.format(n)) m = Meter(wri, 5, x, divisions = 4, ptcolor=YELLOW, label=text, style=Meter.BAR, legends=('0.0', '0.5', '1.0')) l = LED(wri, ssd.height - 16 - wri.height, x, bdcolor=YELLOW, label ='over') while True: v = int.from_bytes(uos.urandom(3),'little')/16777216 m.value(v, color(v)) l.color(color(v)) l.text(txt(v), fgcolor=color(v)) refresh(ssd) await asyncio.sleep_ms(t)
def show(): # Low power version of .wait_until_ready() def wait_ready(): while not ssd.ready(): upower.lpdelay(1000) refresh(ssd, True) # Init and clear. busy will go True for ~5s populate() wait_ready() # wait for display ready (seconds) refresh(ssd) wait_ready() ssd.sleep() # Put into "off" state
def liss(): print('Lissajous figure.') def populate(): t = -math.pi while t <= math.pi: yield math.sin(t), math.cos(3 * t) # x, y t += 0.1 refresh(ssd, True) # Clear any prior image g = CartesianGraph(wri, 2, 2, fgcolor=WHITE, gridcolor=LIGHTGREEN) curve = Curve(g, YELLOW, populate()) refresh(ssd)
async def default(scale, lbl): cv = -1.0 # Current val = 1.0 while True: v1, v2 = val, cv steps = 400 delta = (val - cv) / steps for _ in range(steps): cv += delta scale.value(cv) lbl.value('{:4.3f}'.format(cv)) refresh(ssd) await asyncio.sleep_ms(250) val, cv = v2, v1
async def wrap(wri): s = '''The textbox displays multiple lines of text in a field of fixed dimensions. \ Text may be clipped to the width of the control or may be word-wrapped. If the number \ of lines of text exceeds the height available, scrolling may be performed \ by calling a method. ''' tb = Textbox(wri, *pargs, clip=False, **tbargs) tb.append(s, ntrim=100, line=0) refresh(ssd) while True: await asyncio.sleep(1) if not tb.scroll(1): break refresh(ssd)
def polar_clip(): print('Test of polar data clipping.') def populate(rot): f = lambda theta: cmath.rect(1.15 * math.sin(5 * theta), theta ) * rot # complex nmax = 150 for n in range(nmax + 1): yield f(2 * cmath.pi * n / nmax) # complex z refresh(ssd, True) # Clear any prior image g = PolarGraph(wri, 2, 2, fgcolor=WHITE, gridcolor=LIGHTGREEN) curve = PolarCurve(g, YELLOW, populate(1)) curve1 = PolarCurve(g, RED, populate(cmath.rect(1, cmath.pi / 5), )) refresh(ssd)
def meter(): ssd.fill(0) refresh(ssd) wri = Writer(ssd, arial10, verbose=False) m0 = Meter(wri, 5, 2, height = 50, divisions = 4, legends=('0.0', '0.5', '1.0')) m1 = Meter(wri, 5, 44, height = 50, divisions = 4, legends=('-1', '0', '+1')) m2 = Meter(wri, 5, 86, height = 50, divisions = 4, legends=('-1', '0', '+1')) steps = 10 random = xorshift64star(2**24 - 1) for n in range(steps + 1): m0.value(random() / 16777216) m1.value(n/steps) m2.value(1 - n/steps) refresh(ssd) utime.sleep(1)
def polar(): print('Polar data test.') def populate(): def f(theta): return cmath.rect(math.sin(3 * theta), theta) # complex nmax = 150 for n in range(nmax + 1): yield f(2 * cmath.pi * n / nmax) # complex z refresh(ssd, True) # Clear any prior image g = PolarGraph(wri, 2, 2, fgcolor=WHITE, gridcolor=LIGHTGREEN) curve = PolarCurve(g, YELLOW, populate()) refresh(ssd)
async def main(): refresh(ssd, True) # Clear display await ssd.wait() print('Ready') evt = asyncio.Event() asyncio.create_task(meter(evt)) asyncio.create_task(multi_fields(evt)) asyncio.create_task(compass(evt)) while True: # Normal procedure before refresh, but 10s sleep should mean it always returns immediately await ssd.wait() refresh(ssd) # Launches ._as_show() await ssd.updated() # Content has now been shifted out so coros can update # framebuffer in background evt.set() evt.clear() await asyncio.sleep(10) # Allow for slow refresh
def clock(x): print('Clock test.') refresh(ssd, True) # Clear any prior image lbl = Label(wri, 5, 85, 'Clock') dial = Dial(wri, 5, 5, height = 75, ticks = 12, bdcolor=None, label=50) # Border in fg color hrs = Pointer(dial) mins = Pointer(dial) hrs.value(0 + 0.7j, RED) mins.value(0 + 0.9j, YELLOW) dm = cmath.rect(1, -cmath.pi/30) # Rotate by 1 minute (CW) dh = cmath.rect(1, -cmath.pi/1800) # Rotate hours by 1 minute for n in range(x): refresh(ssd) utime.sleep_ms(200) mins.value(mins.value() * dm, YELLOW) hrs.value(hrs.value() * dh, RED) dial.text('ticks: {}'.format(n)) lbl.value('Done')
async def aclock(): do_connect.do_connect() asyncio.create_task(set_rtc()) asyncio.create_task(ramcheck()) uv = lambda phi: cmath.rect(1, phi) # Return a unit vector of phase phi pi = cmath.pi days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday') months = ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December') # Instantiate CWriter CWriter.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = CWriter(ssd, font, GREEN, BLACK, verbose=False) wri.set_clip(True, True, False) # Instantiate displayable objects dial = Dial(wri, 2, 2, height=130, ticks=12, bdcolor=None) # Border in fg color lbltim = Label(wri, 140, 2, 130) lblday = Label(wri, 170, 2, 130) lblmonth = Label(wri, 190, 2, 130) lblyr = Label(wri, 210, 2, 130) 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 t = time.localtime() while True: hrs.value(hstart * uv(-t[3] * pi / 6 - t[4] * pi / 360), YELLOW) mins.value(mstart * uv(-t[4] * pi / 30 - t[5] * pi / 1800), YELLOW) secs.value(sstart * uv(-t[5] * pi / 30), RED) lbltim.value('{:02d}.{:02d}.{:02d} {}'.format(t[3], t[4], t[5], 'BST' if bst else 'UTC')) lblday.value('{}'.format(days[t[6]])) lblmonth.value('{} {}'.format(t[2], months[t[1] - 1])) lblyr.value('{}'.format(t[0])) refresh(ssd) st = t while st == t: await asyncio.sleep_ms(100) t = time.localtime()
def seq(): print('Time sequence test - sine and cosine.') refresh(ssd, True) # Clear any prior image # y axis at t==now, no border g = CartesianGraph(wri, 2, 2, xorigin=10, fgcolor=WHITE, gridcolor=LIGHTGREEN, bdcolor=False) tsy = TSequence(g, YELLOW, 50) tsr = TSequence(g, RED, 50) for t in range(100): g.clear() tsy.add(0.9 * math.sin(t / 10)) tsr.add(0.4 * math.cos(t / 10)) refresh(ssd) utime.sleep_ms(100)
def fields(use_spi=False, soft=True): ssd = setup(use_spi, soft) # Create a display instance Writer.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = Writer(ssd, fixed, verbose=False) wri.set_clip(False, False, False) textfield = Label(wri, 0, 2, wri.stringlen('longer')) numfield = Label(wri, 25, 2, wri.stringlen('99.99'), bdcolor=None) countfield = Label(wri, 0, 90, wri.stringlen('1')) n = 1 random = xorshift64star(65535) for s in ('short', 'longer', '1', ''): textfield.value(s) numfield.value('{:5.2f}'.format(random() / 1000)) countfield.value('{:1d}'.format(n)) n += 1 refresh(ssd) utime.sleep(2) textfield.value('Done', True) refresh(ssd)
def test(): def tickcb(f, c): if f > 0.8: return RED if f < -0.8: return BLUE return c def legendcb(f): return '{:2.0f}'.format(88 + ((f + 1) / 2) * (108 - 88)) refresh(ssd, True) # Initialise and clear display. CWriter.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False) wri.set_clip(True, True, False) scale1 = Scale(wri, 2, 2, width=124, legendcb=legendcb, pointercolor=RED, fontcolor=YELLOW) asyncio.create_task(radio(scale1)) lbl = Label(wri, ssd.height - wri.height - 2, 2, 50, bgcolor=DARKGREEN, bdcolor=RED, fgcolor=WHITE) # do_refresh is called with arg 4. In landscape mode this splits screen # into segments of 240/4=60 lines. Here we ensure a scale straddles # this boundary scale = Scale(wri, 55, 2, width=124, tickcb=tickcb, pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN) asyncio.run(default(scale, lbl))
async def default(scale, lbl): cv = -1.0 # Current val = 1.0 while True: v1, v2 = val, cv steps = 400 delta = (val - cv) / steps for _ in range(steps): cv += delta scale.value(cv) lbl.value('{:4.3f}'.format(cv)) if hasattr(ssd, 'do_refresh'): # Option to reduce uasyncio latency await ssd.do_refresh() else: # Normal synchronous call refresh(ssd) await asyncio.sleep_ms(250) val, cv = v2, v1
def aclock(): rtc = pyb.RTC() uv = lambda phi: cmath.rect(1, phi) # Return a unit vector of phase phi pi = cmath.pi days = ('Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun') months = ('Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec') # Instantiate Writer Writer.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = Writer(ssd, font_small, verbose=False) wri.set_clip(True, True, False) wri_tim = Writer(ssd, font_large, verbose=False) wri_tim.set_clip(True, True, False) # Instantiate displayable objects dial = Dial(wri, 2, 2, height=215, ticks=12, bdcolor=None, pip=True) lbltim = Label(wri_tim, 50, 230, '00.00.00') lbldat = Label(wri, 100, 230, 100) hrs = Pointer(dial) mins = Pointer(dial) hstart = 0 + 0.7j # Pointer lengths and position at top mstart = 0 + 0.92j while True: t = rtc.datetime( ) # (year, month, day, weekday, hours, minutes, seconds, subseconds) hang = -t[4] * pi / 6 - t[5] * pi / 360 # Angles of hands in radians mang = -t[5] * pi / 30 if abs(hang - mang) < pi / 360: # Avoid visually confusing overlap of hands hang += pi / 30 # by making hr hand lag slightly hrs.value(hstart * uv(hang)) mins.value(mstart * uv(mang)) lbltim.value('{:02d}.{:02d}'.format(t[4], t[5])) lbldat.value('{} {} {} {}'.format(days[t[3] - 1], t[2], months[t[1] - 1], t[0])) refresh(ssd) # Power saving: only refresh every 30s for _ in range(30): upower.lpdelay(1000) ssd.update() # Toggle VCOM
def lem(): print('Lemniscate of Bernoulli.') def populate(): t = -math.pi while t <= math.pi + 0.1: x = 0.5 * math.sqrt(2) * math.cos(t) / (math.sin(t)**2 + 1) y = math.sqrt(2) * math.cos(t) * math.sin(t) / (math.sin(t)**2 + 1) yield x, y t += 0.1 refresh(ssd, True) # Clear any prior image Label(wri, 82, 2, 'To infinity and beyond...') g = CartesianGraph(wri, 2, 2, height=75, fgcolor=WHITE, gridcolor=LIGHTGREEN) curve = Curve(g, YELLOW, populate()) refresh(ssd)
def multi_fields(t): print('multi_fields') refresh(ssd, True) # Clear any prior image nfields = [] dy = wri.height + 6 y = 2 col = 15 width = wri.stringlen('99.99') for txt in ('X:', 'Y:', 'Z:'): Label(wri, y, 0, txt) # Use wri default colors nfields.append(Label(wri, y, col, width, bdcolor=None)) # Specify a border, color TBD y += dy end = utime.ticks_add(utime.ticks_ms(), t * 1000) while utime.ticks_diff(end, utime.ticks_ms()) > 0: for field in nfields: value = int.from_bytes(uos.urandom(3), 'little') / 167772 overrange = None if value < 70 else YELLOW if value < 90 else RED field.value('{:5.2f}'.format(value), fgcolor=overrange, bdcolor=overrange) refresh(ssd) utime.sleep(1) Label(wri, 0, 64, ' OK ', True, fgcolor=RED) refresh(ssd) utime.sleep(1)
def test(): def tickcb(f, c): if f > 0.8: return RED if f < -0.8: return BLUE return c def legendcb(f): return '{:2.0f}'.format(88 + ((f + 1) / 2) * (108 - 88)) refresh(ssd) # Initialise and clear display. CWriter.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False) wri.set_clip(True, True, False) scale1 = Scale(wri, 2, 2, width=124, legendcb=legendcb, pointercolor=RED, fontcolor=YELLOW) asyncio.create_task(radio(scale1)) lbl = Label(wri, ssd.height - wri.height - 2, 2, 50, bgcolor=DARKGREEN, bdcolor=RED, fgcolor=WHITE) scale = Scale(wri, 45, 2, width=124, tickcb=tickcb, pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN) asyncio.run(default(scale, lbl))
def aclock(): uv = lambda phi : cmath.rect(1, phi) # Return a unit vector of phase phi pi = cmath.pi days = ('Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun') months = ('Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec') # Instantiate Writer Writer.set_textpos(ssd, 0, 0) # In case previous tests have altered it wri = Writer(ssd, font_small, verbose=False) wri.set_clip(True, True, False) wri_tim = Writer(ssd, font_large, verbose=False) wri_tim.set_clip(True, True, False) # Instantiate displayable objects dial = Dial(wri, 2, 2, height = 215, ticks = 12, bdcolor=None, pip=True) lbltim = Label(wri_tim, 50, 230, '00.00.00') lbldat = Label(wri, 100, 230, 100) 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 while True: t = utime.localtime() hang = -t[3]*pi/6 - t[4]*pi/360 # Angles of hour and minute hands mang = -t[4] * pi/30 sang = -t[5] * pi/30 if abs(hang - mang) < pi/360: # Avoid overlap of hr and min hands hang += pi/30 # which is visually confusing. Add slight lag to hrs hrs.value(hstart * uv(hang)) mins.value(mstart * uv(mang)) secs.value(sstart * uv(sang)) lbltim.value('{:02d}.{:02d}.{:02d}'.format(t[3], t[4], t[5])) lbldat.value('{} {} {} {}'.format(days[t[6]], t[2], months[t[1] - 1], t[0])) refresh(ssd) utime.sleep(1)
async def main(): print('Press Pyboard usr button to stop test.') # Asynchronously flash Pyboard LED's. Because we can. leds = [ asyncio.create_task(flash(1, 200)), asyncio.create_task(flash(2, 233)) ] # Task for each meter and GUI LED mtasks = [ MyMeter(2, 'left').task, MyMeter(50, 'right').task, MyMeter(98, 'bass').task ] k = Killer() while True: if await k.wait(800): # Switch was pressed break refresh(ssd) for task in mtasks + leds: task.cancel() await asyncio.sleep_ms(0) ssd.fill(0) # Clear display at end. refresh(ssd)