epd4in2.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. # *****************************************************************************
  2. # * | File : epd4in2.py
  3. # * | Author : Waveshare team
  4. # * | Function : Electronic paper driver
  5. # * | Info :
  6. # *----------------
  7. # * | This version: V4.0
  8. # * | Date : 2019-06-20
  9. # # | Info : python demo
  10. # -----------------------------------------------------------------------------
  11. # Permission is hereby granted, free of charge, to any person obtaining a copy
  12. # of this software and associated documnetation files (the "Software"), to deal
  13. # in the Software without restriction, including without limitation the rights
  14. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. # copies of the Software, and to permit persons to whom the Software is
  16. # furished to do so, subject to the following conditions:
  17. #
  18. # The above copyright notice and this permission notice shall be included in
  19. # all copies or substantial portions of the Software.
  20. #
  21. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. # THE SOFTWARE.
  28. #
  29. import logging
  30. from . import epdconfig
  31. from PIL import Image
  32. import RPi.GPIO as GPIO
  33. # Display resolution
  34. EPD_WIDTH = 400
  35. EPD_HEIGHT = 300
  36. GRAY1 = 0xff #white
  37. GRAY2 = 0xC0
  38. GRAY3 = 0x80 #gray
  39. GRAY4 = 0x00 #Blackest
  40. class EPD:
  41. def __init__(self):
  42. self.reset_pin = epdconfig.RST_PIN
  43. self.dc_pin = epdconfig.DC_PIN
  44. self.busy_pin = epdconfig.BUSY_PIN
  45. self.cs_pin = epdconfig.CS_PIN
  46. self.width = EPD_WIDTH
  47. self.height = EPD_HEIGHT
  48. self.GRAY1 = GRAY1 #white
  49. self.GRAY2 = GRAY2
  50. self.GRAY3 = GRAY3 #gray
  51. self.GRAY4 = GRAY4 #Blackest
  52. lut_vcom0 = [
  53. 0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
  54. 0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
  55. 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
  56. 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  57. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  58. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  60. ]
  61. lut_ww = [
  62. 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
  63. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  64. 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
  65. 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  66. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  68. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  69. ]
  70. lut_bw = [
  71. 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
  72. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  73. 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
  74. 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  75. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  76. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  77. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  78. ]
  79. lut_wb = [
  80. 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
  81. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  82. 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
  83. 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  84. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  85. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  86. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  87. ]
  88. lut_bb = [
  89. 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
  90. 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
  91. 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
  92. 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
  93. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  94. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  95. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  96. ]
  97. #******************************gray*********************************/
  98. #0~3 gray
  99. EPD_4IN2_4Gray_lut_vcom =[
  100. 0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
  101. 0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
  102. 0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,
  103. 0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,
  104. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  105. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  106. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
  107. ]
  108. #R21
  109. EPD_4IN2_4Gray_lut_ww =[
  110. 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
  111. 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
  112. 0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
  113. 0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
  114. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  115. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  116. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  117. ]
  118. #R22H r
  119. EPD_4IN2_4Gray_lut_bw =[
  120. 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
  121. 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
  122. 0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
  123. 0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,
  124. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  125. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  126. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  127. ]
  128. #R23H w
  129. EPD_4IN2_4Gray_lut_wb =[
  130. 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
  131. 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
  132. 0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
  133. 0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,
  134. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  135. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  136. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  137. ]
  138. #R24H b
  139. EPD_4IN2_4Gray_lut_bb =[
  140. 0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
  141. 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
  142. 0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
  143. 0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
  144. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  145. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  146. 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
  147. ]
  148. # Hardware reset
  149. def reset(self):
  150. epdconfig.digital_write(self.reset_pin, 1)
  151. epdconfig.delay_ms(200)
  152. epdconfig.digital_write(self.reset_pin, 0)
  153. epdconfig.delay_ms(10)
  154. epdconfig.digital_write(self.reset_pin, 1)
  155. epdconfig.delay_ms(200)
  156. def send_command(self, command):
  157. epdconfig.digital_write(self.dc_pin, 0)
  158. epdconfig.digital_write(self.cs_pin, 0)
  159. epdconfig.spi_writebyte([command])
  160. epdconfig.digital_write(self.cs_pin, 1)
  161. def send_data(self, data):
  162. epdconfig.digital_write(self.dc_pin, 1)
  163. epdconfig.digital_write(self.cs_pin, 0)
  164. epdconfig.spi_writebyte([data])
  165. epdconfig.digital_write(self.cs_pin, 1)
  166. def ReadBusy(self):
  167. self.send_command(0x71)
  168. while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
  169. self.send_command(0x71)
  170. epdconfig.delay_ms(100)
  171. def set_lut(self):
  172. self.send_command(0x20) # vcom
  173. for count in range(0, 44):
  174. self.send_data(self.lut_vcom0[count])
  175. self.send_command(0x21) # ww --
  176. for count in range(0, 42):
  177. self.send_data(self.lut_ww[count])
  178. self.send_command(0x22) # bw r
  179. for count in range(0, 42):
  180. self.send_data(self.lut_bw[count])
  181. self.send_command(0x23) # wb w
  182. for count in range(0, 42):
  183. self.send_data(self.lut_bb[count])
  184. self.send_command(0x24) # bb b
  185. for count in range(0, 42):
  186. self.send_data(self.lut_wb[count])
  187. def Gray_SetLut(self):
  188. self.send_command(0x20) #vcom
  189. for count in range(0, 42):
  190. self.send_data(self.EPD_4IN2_4Gray_lut_vcom[count])
  191. self.send_command(0x21) #red not use
  192. for count in range(0, 42):
  193. self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])
  194. self.send_command(0x22) #bw r
  195. for count in range(0, 42):
  196. self.send_data(self.EPD_4IN2_4Gray_lut_bw[count])
  197. self.send_command(0x23) #wb w
  198. for count in range(0, 42):
  199. self.send_data(self.EPD_4IN2_4Gray_lut_wb[count])
  200. self.send_command(0x24) #bb b
  201. for count in range(0, 42):
  202. self.send_data(self.EPD_4IN2_4Gray_lut_bb[count])
  203. self.send_command(0x25) #vcom
  204. for count in range(0, 42):
  205. self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])
  206. def init(self):
  207. if (epdconfig.module_init() != 0):
  208. return -1
  209. # EPD hardware init start
  210. self.reset()
  211. self.send_command(0x01) # POWER SETTING
  212. self.send_data(0x03) # VDS_EN, VDG_EN
  213. self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
  214. self.send_data(0x2b) # VDH
  215. self.send_data(0x2b) # VDL
  216. self.send_command(0x06) # boost soft start
  217. self.send_data(0x17)
  218. self.send_data(0x17)
  219. self.send_data(0x17)
  220. self.send_command(0x04) # POWER_ON
  221. self.ReadBusy()
  222. self.send_command(0x00) # panel setting
  223. self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f
  224. self.send_data(0x0d)
  225. self.send_command(0x30) # PLL setting
  226. self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
  227. self.send_command(0x61) # resolution setting
  228. self.send_data(0x01)
  229. self.send_data(0x90) # 128
  230. self.send_data(0x01)
  231. self.send_data(0x2c)
  232. self.send_command(0x82) # vcom_DC setting
  233. self.send_data(0x28)
  234. self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
  235. self.send_data(0x97) # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
  236. self.set_lut()
  237. # EPD hardware init end
  238. return 0
  239. def Init_4Gray(self):
  240. if (epdconfig.module_init() != 0):
  241. return -1
  242. # EPD hardware init start
  243. self.reset()
  244. self.send_command(0x01) #POWER SETTING
  245. self.send_data (0x03)
  246. self.send_data (0x00) #VGH=20V,VGL=-20V
  247. self.send_data (0x2b) #VDH=15V
  248. self.send_data (0x2b) #VDL=-15V
  249. self.send_data (0x13)
  250. self.send_command(0x06) #booster soft start
  251. self.send_data (0x17) #A
  252. self.send_data (0x17) #B
  253. self.send_data (0x17) #C
  254. self.send_command(0x04)
  255. self.ReadBusy()
  256. self.send_command(0x00) #panel setting
  257. self.send_data(0x3f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
  258. self.send_command(0x30) #PLL setting
  259. self.send_data (0x3c) #100hz
  260. self.send_command(0x61) #resolution setting
  261. self.send_data (0x01) #400
  262. self.send_data (0x90)
  263. self.send_data (0x01) #300
  264. self.send_data (0x2c)
  265. self.send_command(0x82) #vcom_DC setting
  266. self.send_data (0x12)
  267. self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
  268. self.send_data(0x97)
  269. def getbuffer(self, image):
  270. # logging.debug("bufsiz = ",int(self.width/8) * self.height)
  271. buf = [0xFF] * (int(self.width/8) * self.height)
  272. image_monocolor = image.convert('1')
  273. imwidth, imheight = image_monocolor.size
  274. pixels = image_monocolor.load()
  275. # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
  276. if(imwidth == self.width and imheight == self.height):
  277. logging.debug("Horizontal")
  278. for y in range(imheight):
  279. for x in range(imwidth):
  280. # Set the bits for the column of pixels at the current position.
  281. if pixels[x, y] == 0:
  282. buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
  283. elif(imwidth == self.height and imheight == self.width):
  284. logging.debug("Vertical")
  285. for y in range(imheight):
  286. for x in range(imwidth):
  287. newx = y
  288. newy = self.height - x - 1
  289. if pixels[x, y] == 0:
  290. buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
  291. return buf
  292. def getbuffer_4Gray(self, image):
  293. # logging.debug("bufsiz = ",int(self.width/8) * self.height)
  294. buf = [0xFF] * (int(self.width / 4) * self.height)
  295. image_monocolor = image.convert('L')
  296. imwidth, imheight = image_monocolor.size
  297. pixels = image_monocolor.load()
  298. i=0
  299. # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
  300. if(imwidth == self.width and imheight == self.height):
  301. logging.debug("Vertical")
  302. for y in range(imheight):
  303. for x in range(imwidth):
  304. # Set the bits for the column of pixels at the current position.
  305. if(pixels[x, y] == 0xC0):
  306. pixels[x, y] = 0x80
  307. elif (pixels[x, y] == 0x80):
  308. pixels[x, y] = 0x40
  309. i= i+1
  310. if(i%4 == 0):
  311. buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
  312. elif(imwidth == self.height and imheight == self.width):
  313. logging.debug("Horizontal")
  314. for x in range(imwidth):
  315. for y in range(imheight):
  316. newx = y
  317. newy = x
  318. if(pixels[x, y] == 0xC0):
  319. pixels[x, y] = 0x80
  320. elif (pixels[x, y] == 0x80):
  321. pixels[x, y] = 0x40
  322. i= i+1
  323. if(i%4 == 0):
  324. buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
  325. return buf
  326. def display(self, image):
  327. self.send_command(0x10)
  328. for i in range(0, int(self.width * self.height / 8)):
  329. self.send_data(0xFF)
  330. self.send_command(0x13)
  331. for i in range(0, int(self.width * self.height / 8)):
  332. self.send_data(image[i])
  333. self.send_command(0x12)
  334. self.ReadBusy()
  335. def display_4Gray(self, image):
  336. self.send_command(0x10)
  337. for i in range(0, EPD_WIDTH * EPD_HEIGHT / 8): # EPD_WIDTH * EPD_HEIGHT / 4
  338. temp3=0
  339. for j in range(0, 2):
  340. temp1 = image[i*2+j]
  341. for k in range(0, 2):
  342. temp2 = temp1&0xC0
  343. if(temp2 == 0xC0):
  344. temp3 |= 0x01#white
  345. elif(temp2 == 0x00):
  346. temp3 |= 0x00 #black
  347. elif(temp2 == 0x80):
  348. temp3 |= 0x01 #gray1
  349. else: #0x40
  350. temp3 |= 0x00 #gray2
  351. temp3 <<= 1
  352. temp1 <<= 2
  353. temp2 = temp1&0xC0
  354. if(temp2 == 0xC0): #white
  355. temp3 |= 0x01
  356. elif(temp2 == 0x00): #black
  357. temp3 |= 0x00
  358. elif(temp2 == 0x80):
  359. temp3 |= 0x01 #gray1
  360. else : #0x40
  361. temp3 |= 0x00 #gray2
  362. if(j!=1 or k!=1):
  363. temp3 <<= 1
  364. temp1 <<= 2
  365. self.send_data(temp3)
  366. self.send_command(0x13)
  367. for i in range(0, EPD_WIDTH * EPD_HEIGHT / 8): #5808*4 46464
  368. temp3=0
  369. for j in range(0, 2):
  370. temp1 = image[i*2+j]
  371. for k in range(0, 2):
  372. temp2 = temp1&0xC0
  373. if(temp2 == 0xC0):
  374. temp3 |= 0x01#white
  375. elif(temp2 == 0x00):
  376. temp3 |= 0x00 #black
  377. elif(temp2 == 0x80):
  378. temp3 |= 0x00 #gray1
  379. else: #0x40
  380. temp3 |= 0x01 #gray2
  381. temp3 <<= 1
  382. temp1 <<= 2
  383. temp2 = temp1&0xC0
  384. if(temp2 == 0xC0): #white
  385. temp3 |= 0x01
  386. elif(temp2 == 0x00): #black
  387. temp3 |= 0x00
  388. elif(temp2 == 0x80):
  389. temp3 |= 0x00 #gray1
  390. else: #0x40
  391. temp3 |= 0x01 #gray2
  392. if(j!=1 or k!=1):
  393. temp3 <<= 1
  394. temp1 <<= 2
  395. self.send_data(temp3)
  396. self.Gray_SetLut()
  397. self.send_command(0x12)
  398. epdconfig.delay_ms(200)
  399. self.ReadBusy()
  400. # pass
  401. def Clear(self):
  402. self.send_command(0x10)
  403. for i in range(0, int(self.width * self.height / 8)):
  404. self.send_data(0xFF)
  405. self.send_command(0x13)
  406. for i in range(0, int(self.width * self.height / 8)):
  407. self.send_data(0xFF)
  408. self.send_command(0x12)
  409. self.ReadBusy()
  410. def sleep(self):
  411. self.send_command(0x02) # POWER_OFF
  412. self.ReadBusy()
  413. self.send_command(0x07) # DEEP_SLEEP
  414. self.send_data(0XA5)
  415. epdconfig.module_exit()
  416. ### END OF FILE ###