2
0

epd2in7b.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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-08
  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 = epd2in7b.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 = 176
  54. EPD_HEIGHT = 264
  55. # EPD2IN7B 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. PARTIAL_DATA_START_TRANSMISSION_1 = 0x14
  69. PARTIAL_DATA_START_TRANSMISSION_2 = 0x15
  70. PARTIAL_DISPLAY_REFRESH = 0x16
  71. LUT_FOR_VCOM = 0x20
  72. LUT_WHITE_TO_WHITE = 0x21
  73. LUT_BLACK_TO_WHITE = 0x22
  74. LUT_WHITE_TO_BLACK = 0x23
  75. LUT_BLACK_TO_BLACK = 0x24
  76. PLL_CONTROL = 0x30
  77. TEMPERATURE_SENSOR_COMMAND = 0x40
  78. TEMPERATURE_SENSOR_CALIBRATION = 0x41
  79. TEMPERATURE_SENSOR_WRITE = 0x42
  80. TEMPERATURE_SENSOR_READ = 0x43
  81. VCOM_AND_DATA_INTERVAL_SETTING = 0x50
  82. LOW_POWER_DETECTION = 0x51
  83. TCON_SETTING = 0x60
  84. TCON_RESOLUTION = 0x61
  85. SOURCE_AND_GATE_START_SETTING = 0x62
  86. GET_STATUS = 0x71
  87. AUTO_MEASURE_VCOM = 0x80
  88. VCOM_VALUE = 0x81
  89. VCM_DC_SETTING_REGISTER = 0x82
  90. PROGRAM_MODE = 0xA0
  91. ACTIVE_PROGRAM = 0xA1
  92. READ_OTP_DATA = 0xA2
  93. class EPD:
  94. def __init__(self):
  95. self.reset_pin = epdconfig.RST_PIN
  96. self.dc_pin = epdconfig.DC_PIN
  97. self.busy_pin = epdconfig.BUSY_PIN
  98. self.cs_pin = epdconfig.CS_PIN
  99. self.width = EPD_WIDTH
  100. self.height = EPD_HEIGHT
  101. lut_vcom_dc = [
  102. 0x00, 0x00,
  103. 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01,
  104. 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  105. 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10,
  106. 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  107. 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
  108. 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
  109. 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
  110. ]
  111. lut_ww = [
  112. 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
  113. 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  114. 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
  115. 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  116. 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
  117. 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
  118. 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
  119. ]
  120. # R22H r
  121. lut_bw = [
  122. 0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01,
  123. 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  124. 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
  125. 0x90, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  126. 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05,
  127. 0xB0, 0x03, 0x0E, 0x00, 0x00, 0x0A,
  128. 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01
  129. ]
  130. # R23H w
  131. lut_bb = [
  132. 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
  133. 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  134. 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
  135. 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  136. 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
  137. 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
  138. 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
  139. ]
  140. # R24H b
  141. lut_wb = [
  142. 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
  143. 0x20, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  144. 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
  145. 0x10, 0x0A, 0x0A, 0x00, 0x00, 0x08,
  146. 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
  147. 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
  148. 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
  149. ]
  150. # Hardware reset
  151. def reset(self):
  152. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  153. epdconfig.delay_ms(200)
  154. epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset
  155. epdconfig.delay_ms(200)
  156. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  157. epdconfig.delay_ms(200)
  158. def send_command(self, command):
  159. epdconfig.digital_write(self.cs_pin, GPIO.LOW)
  160. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  161. epdconfig.spi_writebyte([command])
  162. epdconfig.digital_write(self.cs_pin, GPIO.HIGH)
  163. def send_data(self, data):
  164. epdconfig.digital_write(self.cs_pin, GPIO.LOW)
  165. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  166. epdconfig.spi_writebyte([data])
  167. epdconfig.digital_write(self.cs_pin, GPIO.HIGH)
  168. def wait_until_idle(self):
  169. print("e-Paper busy")
  170. while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
  171. epdconfig.delay_ms(100)
  172. print("e-Paper busy release")
  173. def set_lut(self):
  174. self.send_command(LUT_FOR_VCOM) # vcom
  175. for count in range(0, 44):
  176. self.send_data(self.lut_vcom_dc[count])
  177. self.send_command(LUT_WHITE_TO_WHITE) # ww --
  178. for count in range(0, 42):
  179. self.send_data(self.lut_ww[count])
  180. self.send_command(LUT_BLACK_TO_WHITE) # bw r
  181. for count in range(0, 42):
  182. self.send_data(self.lut_bw[count])
  183. self.send_command(LUT_WHITE_TO_BLACK) # wb w
  184. for count in range(0, 42):
  185. self.send_data(self.lut_bb[count])
  186. self.send_command(LUT_BLACK_TO_BLACK) # bb b
  187. for count in range(0, 42):
  188. self.send_data(self.lut_wb[count])
  189. def init(self):
  190. if (epdconfig.module_init() != 0):
  191. return -1
  192. self.reset()
  193. self.send_command(POWER_ON)
  194. self.wait_until_idle()
  195. self.send_command(PANEL_SETTING)
  196. self.send_data(0xaf) #KW-BF KWR-AF BWROTP 0f
  197. self.send_command(PLL_CONTROL)
  198. self.send_data(0x3a) #3A 100HZ 29 150Hz 39 200HZ 31 171HZ
  199. self.send_command(POWER_SETTING)
  200. self.send_data(0x03) # VDS_EN, VDG_EN
  201. self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
  202. self.send_data(0x2b) # VDH
  203. self.send_data(0x2b) # VDL
  204. self.send_data(0x09) # VDHR
  205. self.send_command(BOOSTER_SOFT_START)
  206. self.send_data(0x07)
  207. self.send_data(0x07)
  208. self.send_data(0x17)
  209. # Power optimization
  210. self.send_command(0xF8)
  211. self.send_data(0x60)
  212. self.send_data(0xA5)
  213. # Power optimization
  214. self.send_command(0xF8)
  215. self.send_data(0x89)
  216. self.send_data(0xA5)
  217. # Power optimization
  218. self.send_command(0xF8)
  219. self.send_data(0x90)
  220. self.send_data(0x00)
  221. # Power optimization
  222. self.send_command(0xF8)
  223. self.send_data(0x93)
  224. self.send_data(0x2A)
  225. # Power optimization
  226. self.send_command(0xF8)
  227. self.send_data(0x73)
  228. self.send_data(0x41)
  229. self.send_command(VCM_DC_SETTING_REGISTER)
  230. self.send_data(0x12)
  231. self.send_command(VCOM_AND_DATA_INTERVAL_SETTING)
  232. self.send_data(0x87) # define by OTP
  233. self.set_lut()
  234. self.send_command(PARTIAL_DISPLAY_REFRESH)
  235. self.send_data(0x00)
  236. return 0
  237. def getbuffer(self, image):
  238. # print "bufsiz = ",(self.width/8) * self.height
  239. buf = [0xFF] * ((self.width//8) * self.height)
  240. image_monocolor = image.convert('1')
  241. imwidth, imheight = image_monocolor.size
  242. pixels = image_monocolor.load()
  243. # print "imwidth = %d, imheight = %d",imwidth,imheight
  244. if(imwidth == self.width and imheight == self.height):
  245. print("Vertical")
  246. for y in range(imheight):
  247. for x in range(imwidth):
  248. # Set the bits for the column of pixels at the current position.
  249. if pixels[x, y] == 0:
  250. buf[(x + y * self.width) // 8] &= ~(0x80 >> (x % 8))
  251. elif(imwidth == self.height and imheight == self.width):
  252. print("Horizontal")
  253. for y in range(imheight):
  254. for x in range(imwidth):
  255. newx = y
  256. newy = self.height - x - 1
  257. if pixels[x, y] == 0:
  258. buf[(newx + newy*self.width) // 8] &= ~(0x80 >> (y % 8))
  259. return buf
  260. def display(self, imageblack, imagered):
  261. self.send_command(DATA_START_TRANSMISSION_1)
  262. for i in range(0, self.width * self.height // 8):
  263. self.send_data(~imageblack[i])
  264. self.send_command(DATA_STOP)
  265. self.send_command(DATA_START_TRANSMISSION_2)
  266. for i in range(0, self.width * self.height // 8):
  267. self.send_data(~imagered[i])
  268. self.send_command(DATA_STOP)
  269. self.send_command(DISPLAY_REFRESH)
  270. self.wait_until_idle()
  271. def Clear(self, color):
  272. self.send_command(DATA_START_TRANSMISSION_1)
  273. for i in range(0, self.width * self.height // 8):
  274. self.send_data(0x00)
  275. self.send_command(DATA_STOP)
  276. self.send_command(DATA_START_TRANSMISSION_2)
  277. for i in range(0, self.width * self.height // 8):
  278. self.send_data(0x00)
  279. self.send_command(DATA_STOP)
  280. self.send_command(DISPLAY_REFRESH)
  281. self.wait_until_idle()
  282. def sleep(self):
  283. self.send_command(0X50)
  284. self.send_data(0xf7)
  285. self.send_command(0X02)
  286. self.send_command(0X07)
  287. self.send_data(0xA5)
  288. ### END OF FILE ###