ePaper display driven by a Raspberry Pi Pico
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

145 lines
4.5 KiB

  1. import epaper
  2. import microbmp
  3. import time
  4. import random
  5. import os
  6. import gc
  7. gc.enable()
  8. epd_resolution = [600, 448]
  9. epd_colormap = [
  10. [0x00, 0x00, 0x00], # black
  11. [0xff, 0xff, 0xff], # white
  12. [0x00, 0x90, 0x10], # green
  13. [0x00, 0x00, 0xee], # blue
  14. [0xff, 0x00, 0x00], # red
  15. [0xff, 0xdd, 0x00], # yellow
  16. [0xff, 0x77, 0x00], # orange
  17. ]
  18. images = list(filter(lambda x : x.endswith(".bmp"), os.listdir()))
  19. max_free_height = 200
  20. def init_display():
  21. #print("ePaper init ", str(time.localtime()))
  22. epd = epaper.EPD_5in65()
  23. epd.fill(epd.White)
  24. return epd
  25. def draw_image(filename):
  26. global epd
  27. global epd_colormap
  28. global free_x, free_y, free_width, free_height
  29. offset_x = 0
  30. offset_y = 0
  31. free_x = 0
  32. free_y = 0
  33. free_width = 0
  34. free_height = 0
  35. color_map = {}
  36. def header_callback(header):
  37. #print("header callback: ", str(header))
  38. global epd_resolution
  39. global offset_x, offset_y
  40. global free_x, free_y, free_width, free_height
  41. global max_free_height
  42. w = header[0]
  43. h = header[1]
  44. rest_x = (epd_resolution[0] - w)
  45. rest_y = (epd_resolution[1] - h)
  46. free_x = 0
  47. free_y = max(h, epd_resolution[1] - max_free_height)
  48. free_width = epd_resolution[0]
  49. free_height = min(rest_y, max_free_height)
  50. offset_x = rest_x//2
  51. offset_y = max(0, rest_y - max_free_height)//2
  52. def pixel_callback(x, y, color):
  53. global epd
  54. global epd_colormap
  55. global offset_x, offset_y
  56. # translate color to color index
  57. color_index = 0
  58. color_key = color[0] + color[1] << 8 + color[2] << 16
  59. if color_key in color_map:
  60. color_index = color_map[color_key]
  61. else:
  62. # search for the best color
  63. best_index = 0
  64. best_score = 1000
  65. for index in range(len(epd_colormap)):
  66. c1 = epd_colormap[index]
  67. c2 = color
  68. score = abs(c1[0] - c2[0]) + abs(c1[1] - c2[1]) + abs(c1[2] - c2[2])
  69. if score < best_score:
  70. best_score = score
  71. best_index = index
  72. if score < 10:
  73. break
  74. color_index = best_index
  75. color_map[color_key] = color_index
  76. epd.pixel(offset_x + x, offset_y + y, color_index)
  77. def pixel_row_callback(x, y, colors):
  78. pass
  79. #global epd
  80. #print("PXL ", str([color, r,g,b, pixel]))
  81. #for i in range(len(colors)):
  82. # epd.pixel(offset_x + x + i, offset_y + y, color_to_index(colors[i]))
  83. #print(str(time.localtime()), " BMP ", filename, " loading")
  84. time_start = time.ticks_ms()
  85. epd.fill(epd.White)
  86. microbmp.MicroBMP(header_callback=header_callback, data_callback=pixel_callback).load(filename)
  87. time_loaded = time.ticks_ms()
  88. print(" time to load: ", (time_loaded - time_start) / 1000, " s")
  89. #print(str(time.localtime()), " BMP loaded")
  90. #epd.EPD_5IN65F_Display(epd.buffer)
  91. #print(str(time.localtime()), " ePaper printed")
  92. return [free_x, free_y, free_width, free_height]
  93. def draw_pattern():
  94. global epd
  95. global epd_resolution
  96. free_x = 0
  97. free_y = 400
  98. free_width = epd_resolution[0]
  99. free_height = epd_resolution[1] - free_y
  100. epd.fill_rect(0, 0, epd_resolution[0], free_y, random.randrange(2,7))
  101. return [free_x, free_y, free_width, free_height]
  102. def print_text(text, region):
  103. global epd
  104. epd.text(text, region[0]+5, region[1]+5, epd.Black)
  105. def draw_extra(region):
  106. fnt = 8
  107. if region[2] < fnt or region[3] < fnt:
  108. print("Not enough space for extra: ", str(region))
  109. return
  110. #epd.rect(region[0], region[1], region[2], region[3], epd.Black)
  111. #region[0] += random.randrange(50)
  112. print_text("Lorem ipsum: " + str(random.randrange(1000, 999999)), region)
  113. # MAIN
  114. epd = init_display()
  115. while True:
  116. epd.EPD_5IN65F_Init()
  117. epd.fill(epd.White)
  118. filename = random.choice(images)
  119. print("TV drawing image ", filename)
  120. free_space = draw_image(filename)
  121. #free_space = draw_pattern()
  122. draw_extra(free_space)
  123. time_render_start = time.ticks_ms()
  124. epd.EPD_5IN65F_Display(epd.buffer)
  125. time_render_stop = time.ticks_ms()
  126. print(" time to render: ", (time_render_stop - time_render_start) / 1000, " s")
  127. print("TV showing ", filename)
  128. epd.Sleep()
  129. print("")
  130. gc.collect()
  131. epd.delay_ms(60000 * 1)