epd2in13b.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # /*****************************************************************************
  2. # * | File : epd2in13b.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 = epd2in13b.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 = 104
  54. EPD_HEIGHT = 212
  55. # EPD2IN13B 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. VCOM_LUT = 0x20
  69. W2W_LUT = 0x21
  70. B2W_LUT = 0x22
  71. W2B_LUT = 0x23
  72. B2B_LUT = 0x24
  73. PLL_CONTROL = 0x30
  74. TEMPERATURE_SENSOR_CALIBRATION = 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. GET_STATUS = 0x71
  83. AUTO_MEASURE_VCOM = 0x80
  84. VCOM_VALUE = 0x81
  85. VCM_DC_SETTING = 0x82
  86. PARTIAL_WINDOW = 0x90
  87. PARTIAL_IN = 0x91
  88. PARTIAL_OUT = 0x92
  89. PROGRAM_MODE = 0xA0
  90. ACTIVE_PROGRAM = 0xA1
  91. READ_OTP_DATA = 0xA2
  92. POWER_SAVING = 0xE3
  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. # Hardware reset
  102. def reset(self):
  103. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  104. epdconfig.delay_ms(200)
  105. epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset
  106. epdconfig.delay_ms(200)
  107. epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
  108. epdconfig.delay_ms(200)
  109. def send_command(self, command):
  110. epdconfig.digital_write(self.cs_pin, GPIO.LOW)
  111. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  112. epdconfig.spi_writebyte([command])
  113. epdconfig.digital_write(self.cs_pin, GPIO.HIGH)
  114. def send_data(self, data):
  115. epdconfig.digital_write(self.cs_pin, GPIO.LOW)
  116. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  117. epdconfig.spi_writebyte([data])
  118. epdconfig.digital_write(self.cs_pin, GPIO.HIGH)
  119. def wait_until_idle(self):
  120. print "e-Paper busy"
  121. while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
  122. epdconfig.delay_ms(100)
  123. print "e-Paper busy release"
  124. def init(self):
  125. if (epdconfig.module_init() != 0):
  126. return -1
  127. self.reset()
  128. self.send_command(BOOSTER_SOFT_START)
  129. self.send_data(0x17)
  130. self.send_data(0x17)
  131. self.send_data(0x17)
  132. self.send_command(POWER_ON)
  133. self.wait_until_idle()
  134. self.send_command(PANEL_SETTING)
  135. self.send_data(0x8F)
  136. self.send_command(VCOM_AND_DATA_INTERVAL_SETTING)
  137. self.send_data(0xF0)
  138. self.send_command(RESOLUTION_SETTING)
  139. self.send_data(self.width & 0xff)
  140. self.send_data(self.height >> 8)
  141. self.send_data(self.height & 0xff)
  142. return 0
  143. def getbuffer(self, image):
  144. # print "bufsiz = ",(self.width/8) * self.height
  145. buf = [0xFF] * ((self.width/8) * self.height)
  146. image_monocolor = image.convert('1')
  147. imwidth, imheight = image_monocolor.size
  148. pixels = image_monocolor.load()
  149. # print "imwidth = %d, imheight = %d",imwidth,imheight
  150. if(imwidth == self.width and imheight == self.height):
  151. print "Vertical"
  152. for y in range(imheight):
  153. for x in range(imwidth):
  154. # Set the bits for the column of pixels at the current position.
  155. if pixels[x, y] == 0:
  156. buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8))
  157. elif(imwidth == self.height and imheight == self.width):
  158. print "Horizontal"
  159. for y in range(imheight):
  160. for x in range(imwidth):
  161. newx = y
  162. newy = self.height - x - 1
  163. if pixels[x, y] == 0:
  164. buf[(newx + newy*self.width) / 8] &= ~(0x80 >> (y % 8))
  165. return buf
  166. def display(self, imageblack, imagered):
  167. self.send_command(DATA_START_TRANSMISSION_1)
  168. for i in range(0, self.width * self.height / 8):
  169. self.send_data(imageblack[i])
  170. self.send_command(DATA_STOP)
  171. self.send_command(DATA_START_TRANSMISSION_2)
  172. for i in range(0, self.width * self.height / 8):
  173. self.send_data(imagered[i])
  174. self.send_command(DATA_STOP)
  175. self.send_command(DISPLAY_REFRESH)
  176. self.wait_until_idle()
  177. def Clear(self):
  178. self.send_command(DATA_START_TRANSMISSION_1)
  179. for i in range(0, self.width * self.height / 8):
  180. self.send_data(0xFF)
  181. self.send_command(DATA_STOP)
  182. self.send_command(DATA_START_TRANSMISSION_2)
  183. for i in range(0, self.width * self.height / 8):
  184. self.send_data(0xFF)
  185. self.send_command(DATA_STOP)
  186. self.send_command(DISPLAY_REFRESH)
  187. self.wait_until_idle()
  188. def sleep(self):
  189. self.send_command(POWER_OFF)
  190. self.wait_until_idle()
  191. self.send_command(DEEP_SLEEP)
  192. self.send_data(0xA5)
  193. ### END OF FILE ###