lcd160cr_test.py 4.9 KB

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