def show(self): wri = self.writer dev = self.device x0: int = self.x0 # Internal rectangle occupied by scale and text x1: int = self.x1 y0: int = self.y0 y1: int = self.y1 dev.fill_rect(x0, y0, x1 - x0, y1 - y0, self.bgcolor) super().show() # Scale is drawn using ints. Each division is 10 units. val: int = self._value # 0..ticks*10 # iv increments for each tick. Its value modulo N determines tick length iv: int # val / 10 at a tick position d: int # val % 10: offset relative to a tick position fx: int # X offset of current tick in value units if val >= 100: # Whole LHS of scale will be drawn iv, d = divmod(val - 100, 10) # Initial value fx = 10 - d iv += 1 else: # Scale will scroll right iv = 0 fx = 100 - val # Window shows 20 divisions, each of which corresponds to 10 units of value. # So pixels per unit value == win_width/200 win_width: int = x1 - x0 ticks: int = self.ticks # Total # of ticks visible and hidden while True: x: int = x0 + (fx * win_width) // 200 # Current X position ys: int # Start Y position for tick yl: int # tick length if x > x1 or iv > ticks: # Out of space or data (scroll left) break if not iv % 10: txt = self.legendcb(self._fvalue(iv * 10)) tlen = wri.stringlen(txt) Writer.set_textpos(dev, y0, min(x, x1 - tlen)) wri.setcolor(self.fontcolor, self.bgcolor) wri.printstring(txt) wri.setcolor() ys = self.ldy0 # Large tick yl = self.ldl elif not iv % 5: ys = self.mdy0 yl = self.mdl else: ys = self.sdy0 yl = self.sdl if self.tickcb is None: color = self.fgcolor else: color = self.tickcb(self._fvalue(iv * 10), self.fgcolor) dev.vline(x, ys, yl, color) # Draw tick fx += 10 iv += 1 dev.vline(x0 + (x1 - x0) // 2, y0, y1 - y0, self.ptrcolor) # Draw pointer
def show(self): txt = super().value() if txt is None: # No content to draw. Future use. return super().show() # Draw or erase border wri = self.writer dev = self.device Writer.set_textpos(dev, self.row, self.col) wri.setcolor(self.fgcolor, self.bgcolor) wri.printstring(txt, self.invert) wri.setcolor() # Restore defaults
async def meter(evt): wri = Writer(ssd, arial10, verbose=False) wri.set_clip(False, False, False) row = 10 col = 170 args = {'height': 80, 'width': 15, 'divisions': 4, 'style': Meter.BAR} m0 = Meter(wri, row, col, legends=('0.0', '0.5', '1.0'), **args) m1 = Meter(wri, row, col + 40, legends=('-1', '0', '+1'), **args) m2 = Meter(wri, row, col + 80, legends=('-1', '0', '+1'), **args) random = xorshift64star(2**24 - 1) while True: steps = 10 for n in range(steps + 1): m0.value(random() / 16777216) m1.value(n / steps) m2.value(1 - n / steps) await evt.wait()
def multi_fields(): ssd.fill(0) refresh(ssd) 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)
async def compass(evt): wri = Writer(ssd, arial10, verbose=False) wri.set_clip(False, False, False) v1 = 0 + 0.9j v2 = exp(0 - (pi / 6) * 1j) dial = Dial(wri, 5, 5, height=75, ticks=12, bdcolor=None, label='Direction', style=Dial.COMPASS) ptr = Pointer(dial) while True: ptr.value(v1) v1 *= v2 await evt.wait()
def _print_lines(self): if len(self.lines) == 0: return dev = self.device wri = self.writer col = self.col row = self.row left = col ht = wri.height wri.setcolor(self.fgcolor, self.bgcolor) # Print the first (or last?) lines that fit widget's height #for line in self.lines[-self.nlines : ]: for line in self.lines[self.start:self.start + self.nlines]: Writer.set_textpos(dev, row, col) wri.printstring(line) row += ht col = left wri.setcolor() # Restore defaults
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
async def multi_fields(evt): wri = Writer(ssd, small, verbose=False) wri.set_clip(False, False, False) nfields = [] dy = small.height() + 10 y = 80 col = 20 width = wri.stringlen('99.990') 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) while True: for _ in range(10): for field in nfields: value = random() / 167772 field.value('{:5.2f}'.format(value)) await evt.wait()
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)
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 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)
async def fields(evt): 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.990'), bdcolor=None) countfield = Label(wri, 0, 90, wri.stringlen('1')) n = 1 random = xorshift64star(65535) while True: for s in ('short', 'longer', '1', ''): textfield.value(s) numfield.value('{:5.2f}'.format(random() /1000)) countfield.value('{:1d}'.format(n)) n += 1 await evt.wait()
def test(): pcs = machine.Pin('Y5', machine.Pin.OUT_PP, value=0) # Active high spi = machine.SPI(2) ssd = SSD(spi, pcs) rhs = ssd.width - 1 ssd.line(rhs - 80, 0, rhs, 80, 1) square_side = 40 ssd.fill_rect(rhs - square_side, 0, square_side, square_side, 1) wri = Writer(ssd, freesans20) Writer.set_textpos(ssd, 0, 0) # verbose = False to suppress console output wri.printstring('Sunday\n') wri.printstring('12 Aug 2018\n') wri.printstring('10.30am') wri = Writer(ssd, arial_50) Writer.set_textpos(ssd, 0, 120) wri.printstring('10:30') ssd.show()
pon = machine.Pin('Y5', machine.Pin.OUT_PP, value=1) # Power on before instantiating display upower.lpdelay(1000) # Give the valves (tubes) time to warm up :) from color_setup import ssd # Instantiate from gui.core.writer import Writer from gui.core.nanogui import refresh from gui.core.fplot import CartesianGraph, Curve from gui.widgets.meter import Meter from gui.widgets.label import Label from gui.widgets.dial import Dial, Pointer # Fonts import gui.fonts.arial10 as arial10 import gui.fonts.freesans20 as large wri = Writer(ssd, arial10, verbose=False) wri.set_clip(False, False, False) wri_large = Writer(ssd, large, verbose=False) wri_large.set_clip(False, False, False) def graph(): row, col, ht, wd = 5, 140, 75, 150 def populate(): x = -0.998 while x < 1.01: z = 6 * pi * x y = sin(z) / z yield x, y
def test(): rhs = ssd.width - 1 ssd.line(rhs - 80, 0, rhs, 80, 1) square_side = 40 ssd.fill_rect(rhs - square_side, 0, square_side, square_side, 1) wri = Writer(ssd, freesans20) Writer.set_textpos(ssd, 0, 0) # verbose = False to suppress console output wri.printstring('Sunday\n') wri.printstring('12 Aug 2018\n') wri.printstring('10.30am') wri = Writer(ssd, arial_50) Writer.set_textpos(ssd, 0, 120) wri.printstring('10:30') ssd.show()