2
0

epd4in2b.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # /*****************************************************************************
  2. # * | File : epd4in2b.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 = epd4in2b.EPD()
  24. # epd.init(epd.lut_full_update)
  25. # image = Image.new('1', (epd4in2b.EPD_WIDTH, epd4in2b.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. # EPD4IN2B 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. GSST_SETTING = 0x65
  83. GET_STATUS = 0x71
  84. AUTO_MEASURE_VCOM = 0x80
  85. 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_PROGRAM = 0xA1
  92. READ_OTP_DATA = 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. # 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.dc_pin, GPIO.LOW)
  111. epdconfig.spi_writebyte([command])
  112. def send_data(self, data):
  113. epdconfig.digital_write(self.dc_pin, GPIO.HIGH)
  114. epdconfig.spi_writebyte([data])
  115. def wait_until_idle(self):
  116. print("e-Paper busy")
  117. while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
  118. epdconfig.delay_ms(100)
  119. print("e-Paper busy release")
  120. def init(self):
  121. if (epdconfig.module_init() != 0):
  122. return -1
  123. self.reset()
  124. self.send_command(BOOSTER_SOFT_START)
  125. self.send_data (0x17)
  126. self.send_data (0x17)
  127. self.send_data (0x17) # 07 0f 17 1f 27 2F 37 2f
  128. self.send_command(POWER_ON)
  129. self.wait_until_idle()
  130. self.send_command(PANEL_SETTING)
  131. self.send_data(0x0F) # LUT from OTP
  132. return 0
  133. def getbuffer(self, image):
  134. # print "bufsiz = ",(self.width/8) * self.height
  135. buf = [0xFF] * ((self.width/8) * self.height)
  136. image_monocolor = image.convert('1')
  137. imwidth, imheight = image_monocolor.size
  138. pixels = image_monocolor.load()
  139. # print "imwidth = %d, imheight = %d",imwidth,imheight
  140. if(imwidth == self.width and imheight == self.height):
  141. print("Horizontal")
  142. for y in range(imheight):
  143. for x in range(imwidth):
  144. # Set the bits for the column of pixels at the current position.
  145. if pixels[x, y] == 0:
  146. buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8))
  147. elif(imwidth == self.height and imheight == self.width):
  148. print("Vertical")
  149. for y in range(imheight):
  150. for x in range(imwidth):
  151. newx = y
  152. newy = self.height - x - 1
  153. if pixels[x, y] == 0:
  154. buf[(newx + newy*self.width) / 8] &= ~(0x80 >> (y % 8))
  155. return buf
  156. def display(self, imageblack, imagered):
  157. self.send_command(DATA_START_TRANSMISSION_1)
  158. for i in range(0, self.width * self.height / 8):
  159. self.send_data(imageblack[i])
  160. self.send_command(DATA_START_TRANSMISSION_2)
  161. for i in range(0, self.width * self.height / 8):
  162. self.send_data(imagered[i])
  163. self.send_command(DISPLAY_REFRESH)
  164. self.wait_until_idle()
  165. def Clear(self, color):
  166. self.send_command(DATA_START_TRANSMISSION_1)
  167. for i in range(0, self.width * self.height / 8):
  168. self.send_data(0xFF)
  169. self.send_command(DATA_START_TRANSMISSION_2)
  170. for i in range(0, self.width * self.height / 8):
  171. self.send_data(0xFF)
  172. self.send_command(DISPLAY_REFRESH)
  173. self.wait_until_idle()
  174. def sleep(self):
  175. self.send_command(VCOM_AND_DATA_INTERVAL_SETTING)
  176. self.send_data(0xF7) # border floating
  177. self.send_command(POWER_OFF)
  178. self.wait_until_idle()
  179. self.send_command(DEEP_SLEEP)
  180. self.send_data(0xA5) # check code
  181. ### END OF FILE ###