the public repo for the e-paper bulletin board. It's a bulletin board that syncs over scuttlebutt :)
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.

279 lines
11 KiB

5 months ago
  1. # /*****************************************************************************
  2. # * | File : EPD_1in54.py
  3. # * | Author : Waveshare team
  4. # * | Function : Electronic paper driver
  5. # * | Info :
  6. # *----------------
  7. # * | This version: V3.0
  8. # * | Date : 2018-11-06
  9. # * | Info : python2 demo
  10. # * 1.Remove:
  11. # digital_write(self, pin, value)
  12. # digital_read(self, pin)
  13. # delay_ms(self, delaytime)
  14. # set_lut(self, lut)
  15. # self.lut = self.lut_full_update
  16. # * 2.Change:
  17. # display_frame -> TurnOnDisplay
  18. # set_memory_area -> SetWindow
  19. # set_memory_pointer -> SetCursor
  20. # get_frame_buffer -> getbuffer
  21. # set_frame_memory -> display
  22. # * 3.How to use
  23. # epd = epd2in7.EPD()
  24. # epd.init(epd.lut_full_update)
  25. # image = Image.new('1', (epd1in54.EPD_WIDTH, epd1in54.EPD_HEIGHT), 255)
  26. # ...
  27. # drawing ......
  28. # ...
  29. # epd.display(getbuffer(image))
  30. # ******************************************************************************/
  31. # Permission is hereby granted, free of charge, to any person obtaining a copy
  32. # of this software and associated documnetation files (the "Software"), to deal
  33. # in the Software without restriction, including without limitation the rights
  34. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  35. # copies of the Software, and to permit persons to whom the Software is
  36. # furished to do so, subject to the following conditions:
  37. #
  38. # The above copyright notice and this permission notice shall be included in
  39. # all copies or substantial portions of the Software.
  40. #
  41. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  42. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  43. # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  44. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  45. # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  46. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  47. # THE SOFTWARE.
  48. #
  49. import epdconfig
  50. from PIL import Image
  51. import RPi.GPIO as GPIO
  52. # Display resolution
  53. EPD_WIDTH = 400
  54. EPD_HEIGHT = 300
  55. # GDEW042T2 commands
  56. PANEL_SETTING = 0x00
  57. POWER_SETTING = 0x01
  58. POWER_OFF = 0x02
  59. POWER_OFF_SEQUENCE_SETTING = 0x03
  60. POWER_ON = 0x04
  61. POWER_ON_MEASURE = 0x05
  62. BOOSTER_SOFT_START = 0x06
  63. DEEP_SLEEP = 0x07
  64. DATA_START_TRANSMISSION_1 = 0x10
  65. DATA_STOP = 0x11
  66. DISPLAY_REFRESH = 0x12
  67. DATA_START_TRANSMISSION_2 = 0x13
  68. LUT_FOR_VCOM = 0x20
  69. LUT_WHITE_TO_WHITE = 0x21
  70. LUT_BLACK_TO_WHITE = 0x22
  71. LUT_WHITE_TO_BLACK = 0x23
  72. LUT_BLACK_TO_BLACK = 0x24
  73. PLL_CONTROL = 0x30
  74. TEMPERATURE_SENSOR_COMMAND = 0x40
  75. TEMPERATURE_SENSOR_SELECTION = 0x41
  76. TEMPERATURE_SENSOR_WRITE = 0x42
  77. TEMPERATURE_SENSOR_READ = 0x43
  78. VCOM_AND_DATA_INTERVAL_SETTING = 0x50
  79. LOW_POWER_DETECTION = 0x51
  80. TCON_SETTING = 0x60
  81. RESOLUTION_SETTING = 0x61
  82. GSST_SETTING = 0x65
  83. GET_STATUS = 0x71
  84. AUTO_MEASUREMENT_VCOM = 0x80
  85. READ_VCOM_VALUE = 0x81
  86. VCM_DC_SETTING = 0x82
  87. PARTIAL_WINDOW = 0x90
  88. PARTIAL_IN = 0x91
  89. PARTIAL_OUT = 0x92
  90. PROGRAM_MODE = 0xA0
  91. ACTIVE_PROGRAMMING = 0xA1
  92. READ_OTP = 0xA2
  93. POWER_SAVING = 0xE3
  94. class EPD:
  95. def __init__(self):
  96. self.reset_pin = epdconfig.RST_PIN
  97. self.dc_pin = epdconfig.DC_PIN
  98. self.busy_pin = epdconfig.BUSY_PIN
  99. self.width = EPD_WIDTH
  100. self.height = EPD_HEIGHT
  101. lut_vcom0 = [
  102. 0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
  103. 0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
  104. 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
  105. 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  106. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  107. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  108. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  109. ]
  110. lut_ww = [
  111. 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
  112. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  113. 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
  114. 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  115. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  116. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  117. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  118. ]
  119. lut_bw = [
  120. 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
  121. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  122. 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
  123. 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  124. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  125. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  126. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  127. ]
  128. lut_wb = [
  129. 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
  130. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  131. 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
  132. 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  133. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  134. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  135. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  136. ]
  137. lut_bb = [
  138. 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
  139. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  140. 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
  141. 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  142. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  143. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  144. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  145. ]
  146. # Hardware reset
  147. def reset(self):
  148. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  149. epdconfig.delay_ms(200)
  150. epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset
  151. epdconfig.delay_ms(200)
  152. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  153. epdconfig.delay_ms(200)
  154. def send_command(self, command):
  155. epdconfig.digital_write(self.dc_pin, GPIO.LOW)
  156. epdconfig.spi_writebyte([command])
  157. def send_data(self, data):
  158. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  159. epdconfig.spi_writebyte([data])
  160. def wait_until_idle(self):
  161. while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
  162. epdconfig.delay_ms(100)
  163. def set_lut(self):
  164. self.send_command(LUT_FOR_VCOM) # vcom
  165. for count in range(0, 44):
  166. self.send_data(self.lut_vcom0[count])
  167. self.send_command(LUT_WHITE_TO_WHITE) # ww --
  168. for count in range(0, 42):
  169. self.send_data(self.lut_ww[count])
  170. self.send_command(LUT_BLACK_TO_WHITE) # bw r
  171. for count in range(0, 42):
  172. self.send_data(self.lut_bw[count])
  173. self.send_command(LUT_WHITE_TO_BLACK) # wb w
  174. for count in range(0, 42):
  175. self.send_data(self.lut_bb[count])
  176. self.send_command(LUT_BLACK_TO_BLACK) # bb b
  177. for count in range(0, 42):
  178. self.send_data(self.lut_wb[count])
  179. def init(self):
  180. if (epdconfig.module_init() != 0):
  181. return -1
  182. # EPD hardware init start
  183. self.reset()
  184. self.send_command(POWER_SETTING)
  185. self.send_data(0x03) # VDS_EN, VDG_EN
  186. self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
  187. self.send_data(0x2b) # VDH
  188. self.send_data(0x2b) # VDL
  189. self.send_command(BOOSTER_SOFT_START)
  190. self.send_data(0x17)
  191. self.send_data(0x17)
  192. self.send_data(0x17)
  193. self.send_command(POWER_ON)
  194. self.wait_until_idle()
  195. self.send_command(PANEL_SETTING)
  196. self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f
  197. self.send_data(0x0d)
  198. self.send_command(PLL_CONTROL)
  199. self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
  200. self.send_command(0x61); # resolution setting
  201. self.send_data(0x01);
  202. self.send_data(0x90); # 128
  203. self.send_data(0x01);
  204. self.send_data(0x2c);
  205. self.send_command(0x82); # vcom_DC setting
  206. self.send_data(0x28);
  207. self.send_command(0X50); # VCOM AND DATA INTERVAL SETTING
  208. self.send_data(0x97); # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
  209. self.set_lut()
  210. # EPD hardware init end
  211. return 0
  212. def getbuffer(self, image):
  213. # print "bufsiz = ",(self.width/8) * self.height
  214. buf = [0xFF] * ((self.width/8) * self.height)
  215. image_monocolor = image.convert('1')
  216. imwidth, imheight = image_monocolor.size
  217. pixels = image_monocolor.load()
  218. # print "imwidth = %d, imheight = %d",imwidth,imheight
  219. if(imwidth == self.width and imheight == self.height):
  220. print "Horizontal"
  221. for y in range(imheight):
  222. for x in range(imwidth):
  223. # Set the bits for the column of pixels at the current position.
  224. if pixels[x, y] == 0:
  225. buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8))
  226. elif(imwidth == self.height and imheight == self.width):
  227. print "Vertical"
  228. for y in range(imheight):
  229. for x in range(imwidth):
  230. newx = y
  231. newy = self.height - x - 1
  232. if pixels[x, y] == 0:
  233. buf[(newx + newy*self.width) / 8] &= ~(0x80 >> (y % 8))
  234. return buf
  235. def display(self, image):
  236. self.send_command(DATA_START_TRANSMISSION_1)
  237. for i in range(0, self.width * self.height / 8):
  238. self.send_data(0xFF)
  239. self.send_command(DATA_START_TRANSMISSION_2)
  240. for i in range(0, self.width * self.height / 8):
  241. self.send_data(image[i])
  242. self.send_command(DISPLAY_REFRESH)
  243. self.wait_until_idle()
  244. def Clear(self, color):
  245. self.send_command(DATA_START_TRANSMISSION_1)
  246. for i in range(0, self.width * self.height / 8):
  247. self.send_data(0xFF)
  248. self.send_command(DATA_START_TRANSMISSION_2)
  249. for i in range(0, self.width * self.height / 8):
  250. self.send_data(0xFF)
  251. self.send_command(DISPLAY_REFRESH)
  252. self.wait_until_idle()
  253. def sleep(self):
  254. self.send_command(POWER_OFF)
  255. self.wait_until_idle()
  256. self.send_command(DEEP_SLEEP)
  257. self.send_data(0XA5)
  258. ### END OF FILE ###