1# Driver test for official MicroPython LCD160CR display 2# MIT license; Copyright (c) 2017 Damien P. George 3 4import time, math, framebuf, lcd160cr 5 6 7def get_lcd(lcd): 8 if type(lcd) is str: 9 lcd = lcd160cr.LCD160CR(lcd) 10 return lcd 11 12 13def show_adc(lcd, adc): 14 data = [adc.read_core_temp(), adc.read_core_vbat(), 3.3] 15 try: 16 data[2] = adc.read_vref() 17 except: 18 pass 19 for i in range(3): 20 lcd.set_text_color((825, 1625, 1600)[i], 0) 21 if lcd.h == 160: 22 lcd.set_font(2) 23 lcd.set_pos(0, 100 + i * 16) 24 else: 25 lcd.set_font(2, trans=1) 26 lcd.set_pos(0, lcd.h - 60 + i * 16) 27 lcd.write("%4s: " % ("TEMP", "VBAT", "VREF")[i]) 28 if i > 0: 29 s = "%6.3fV" % data[i] 30 else: 31 s = "%5.1f°C" % data[i] 32 if lcd.h == 160: 33 lcd.set_font(1, bold=0, scale=1) 34 else: 35 lcd.set_font(1, bold=0, scale=1, trans=1) 36 lcd.set_pos(45, lcd.h - 60 + i * 16) 37 lcd.write(s) 38 39 40def test_features(lcd, orient=lcd160cr.PORTRAIT): 41 # if we run on pyboard then use ADC and RTC features 42 try: 43 import pyb 44 45 adc = pyb.ADCAll(12, 0xF0000) 46 rtc = pyb.RTC() 47 except: 48 adc = None 49 rtc = None 50 51 # set orientation and clear screen 52 lcd = get_lcd(lcd) 53 lcd.set_orient(orient) 54 lcd.set_pen(0, 0) 55 lcd.erase() 56 57 # create M-logo 58 mlogo = framebuf.FrameBuffer(bytearray(17 * 17 * 2), 17, 17, framebuf.RGB565) 59 mlogo.fill(0) 60 mlogo.fill_rect(1, 1, 15, 15, 0xFFFFFF) 61 mlogo.vline(4, 4, 12, 0) 62 mlogo.vline(8, 1, 12, 0) 63 mlogo.vline(12, 4, 12, 0) 64 mlogo.vline(14, 13, 2, 0) 65 66 # create inline framebuf 67 offx = 14 68 offy = 19 69 w = 100 70 h = 75 71 fbuf = framebuf.FrameBuffer(bytearray(w * h * 2), w, h, framebuf.RGB565) 72 lcd.set_spi_win(offx, offy, w, h) 73 74 # initialise loop parameters 75 tx = ty = 0 76 t0 = time.ticks_us() 77 78 for i in range(300): 79 # update position of cross-hair 80 t, tx2, ty2 = lcd.get_touch() 81 if t: 82 tx2 -= offx 83 ty2 -= offy 84 if tx2 >= 0 and ty2 >= 0 and tx2 < w and ty2 < h: 85 tx, ty = tx2, ty2 86 else: 87 tx = (tx + 1) % w 88 ty = (ty + 1) % h 89 90 # create and show the inline framebuf 91 fbuf.fill(lcd.rgb(128 + int(64 * math.cos(0.1 * i)), 128, 192)) 92 fbuf.line( 93 w // 2, 94 h // 2, 95 w // 2 + int(40 * math.cos(0.2 * i)), 96 h // 2 + int(40 * math.sin(0.2 * i)), 97 lcd.rgb(128, 255, 64), 98 ) 99 fbuf.hline(0, ty, w, lcd.rgb(64, 64, 64)) 100 fbuf.vline(tx, 0, h, lcd.rgb(64, 64, 64)) 101 fbuf.rect(tx - 3, ty - 3, 7, 7, lcd.rgb(64, 64, 64)) 102 for phase in (-0.2, 0, 0.2): 103 x = w // 2 - 8 + int(50 * math.cos(0.05 * i + phase)) 104 y = h // 2 - 8 + int(32 * math.sin(0.05 * i + phase)) 105 fbuf.blit(mlogo, x, y) 106 for j in range(-3, 3): 107 fbuf.text( 108 "MicroPython", 109 5, 110 h // 2 + 9 * j + int(20 * math.sin(0.1 * (i + j))), 111 lcd.rgb(128 + 10 * j, 0, 128 - 10 * j), 112 ) 113 lcd.show_framebuf(fbuf) 114 115 # show results from the ADC 116 if adc: 117 show_adc(lcd, adc) 118 119 # show the time 120 if rtc: 121 lcd.set_pos(2, 0) 122 lcd.set_font(1) 123 t = rtc.datetime() 124 lcd.write( 125 "%4d-%02d-%02d %2d:%02d:%02d.%01d" 126 % (t[0], t[1], t[2], t[4], t[5], t[6], t[7] // 100000) 127 ) 128 129 # compute the frame rate 130 t1 = time.ticks_us() 131 dt = time.ticks_diff(t1, t0) 132 t0 = t1 133 134 # show the frame rate 135 lcd.set_pos(2, 9) 136 lcd.write("%.2f fps" % (1000000 / dt)) 137 138 139def test_mandel(lcd, orient=lcd160cr.PORTRAIT): 140 # set orientation and clear screen 141 lcd = get_lcd(lcd) 142 lcd.set_orient(orient) 143 lcd.set_pen(0, 0xFFFF) 144 lcd.erase() 145 146 # function to compute Mandelbrot pixels 147 def in_set(c): 148 z = 0 149 for i in range(32): 150 z = z * z + c 151 if abs(z) > 100: 152 return i 153 return 0 154 155 # cache width and height of LCD 156 w = lcd.w 157 h = lcd.h 158 159 # create the buffer for each line and set SPI parameters 160 line = bytearray(w * 2) 161 lcd.set_spi_win(0, 0, w, h) 162 spi = lcd.fast_spi() 163 164 # draw the Mandelbrot set line-by-line 165 hh = (h - 1) / 3.2 166 ww = (w - 1) / 2.4 167 for v in range(h): 168 for u in range(w): 169 c = in_set((v / hh - 2.3) + (u / ww - 1.2) * 1j) 170 if c < 16: 171 rgb = c << 12 | c << 6 172 else: 173 rgb = 0xF800 | c << 6 174 line[2 * u] = rgb 175 line[2 * u + 1] = rgb >> 8 176 spi.write(line) 177 178 179def test_all(lcd, orient=lcd160cr.PORTRAIT): 180 lcd = get_lcd(lcd) 181 test_features(lcd, orient) 182 test_mandel(lcd, orient) 183 184 185print("To run all tests: test_all(<lcd>)") 186print("Individual tests are: test_features, test_mandel") 187print('<lcd> argument should be a connection, eg "X", or an LCD160CR object') 188