├── CAD └── frame.stp ├── Code ├── pic │ └── Font.ttc ├── sheet.sh ├── sheets │ └── lib │ │ └── waveshare_epd │ │ ├── epd1in02.py │ │ ├── epd1in54.py │ │ ├── epd1in54_V2.py │ │ ├── epd1in54b.py │ │ ├── epd1in54b_V2.py │ │ ├── epd1in54c.py │ │ ├── epd2in13.py │ │ ├── epd2in13_V2.py │ │ ├── epd2in13b_V2.py │ │ ├── epd2in13bc.py │ │ ├── epd2in13d.py │ │ ├── epd2in7.py │ │ ├── epd2in7b.py │ │ ├── epd2in9.py │ │ ├── epd2in9b_V2.py │ │ ├── epd2in9bc.py │ │ ├── epd2in9d.py │ │ ├── epd4in2.py │ │ ├── epd4in2bc.py │ │ ├── epd5in65f.py │ │ ├── epd5in83.py │ │ ├── epd5in83bc.py │ │ ├── epd7in5.py │ │ ├── epd7in5_HD.py │ │ ├── epd7in5_V2.py │ │ ├── epd7in5_V2.pyc │ │ ├── epd7in5b_HD.py │ │ ├── epd7in5b_V3.py │ │ ├── epd7in5bc.py │ │ ├── epd7in5bc_V2.py │ │ ├── epdconfig.py │ │ ├── epdconfig.pyc │ │ ├── sysfs_gpio.so │ │ └── sysfs_software_spi.so └── v1 │ ├── log.csv │ └── sheet02.txt ├── LICENSE └── README.md /Code/pic/Font.ttc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XRobots/IoT-Message-Board/98ee572cd799677eb5ede5da1426f78fb43144de/Code/pic/Font.ttc -------------------------------------------------------------------------------- /Code/sheet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd sheets/v1 3 | python3 sheet02.py 4 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in02.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54.py 3 | # * | Author : Waveshare team 4 | # * | Function : Electronic paper driver 5 | # * | Info : 6 | # *---------------- 7 | # * | This version: V1.0 8 | # * | Date : 2019-06-20 9 | # # | Info : python demo 10 | # ----------------------------------------------------------------------------- 11 | # ******************************************************************************/ 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documnetation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | # 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 80 36 | EPD_HEIGHT = 128 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | #full screen update LUT 48 | 49 | lut_w1 =[ 50 | 0x60, 0x5A, 0x5A, 0x00, 0x00, 0x01, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | ] 58 | 59 | lut_b1 =[ 60 | 0x90, 0x5A, 0x5A, 0x00, 0x00, 0x01, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | ] 68 | 69 | # partial screen update LUT 70 | lut_w = [ 71 | 0x60, 0x01, 0x01, 0x00, 0x00, 0x01, 72 | 0x80, 0x1f, 0x00, 0x00, 0x00, 0x01, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | ] 79 | 80 | lut_b = [ 81 | 0x90, 0x01, 0x01, 0x00, 0x00, 0x01, 82 | 0x40, 0x1f, 0x00, 0x00, 0x00, 0x01, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | ] 89 | 90 | # Hardware reset 91 | def reset(self): 92 | epdconfig.digital_write(self.reset_pin, 1) 93 | epdconfig.delay_ms(200) 94 | epdconfig.digital_write(self.reset_pin, 0) # module reset 95 | epdconfig.delay_ms(2) 96 | epdconfig.digital_write(self.reset_pin, 1) 97 | epdconfig.delay_ms(200) 98 | 99 | def send_command(self, command): 100 | epdconfig.digital_write(self.dc_pin, 0) 101 | epdconfig.digital_write(self.cs_pin, 0) 102 | epdconfig.spi_writebyte([command]) 103 | epdconfig.digital_write(self.cs_pin, 1) 104 | 105 | def send_data(self, data): 106 | epdconfig.digital_write(self.dc_pin, 1) 107 | epdconfig.digital_write(self.cs_pin, 0) 108 | epdconfig.spi_writebyte([data]) 109 | epdconfig.digital_write(self.cs_pin, 1) 110 | 111 | def ReadBusy(self): 112 | logging.debug("e-Paper busy") 113 | self.send_command(0x71) 114 | busy = epdconfig.digital_read(self.busy_pin) 115 | busy =not(busy & 0x01) 116 | while(busy): 117 | self.send_command(0x71) 118 | busy = epdconfig.digital_read(self.busy_pin) 119 | busy =not(busy & 0x01) 120 | epdconfig.delay_ms(800) 121 | logging.debug("e-Paper busy release") 122 | 123 | def TurnOnDisplay(self): 124 | self.send_command(0x12) 125 | epdconfig.delay_ms(10) 126 | self.ReadBusy() 127 | 128 | def SetFulltReg(self): 129 | self.send_command(0x23) 130 | for count in range(0, 42): 131 | self.send_data(self.lut_w1[count]) 132 | 133 | self.send_command(0x24) 134 | for count in range(0, 42): 135 | self.send_data(self.lut_b1[count]) 136 | 137 | def SetPartReg(self): 138 | self.send_command(0x23) 139 | for count in range(0, 42): 140 | self.send_data(self.lut_w[count]) 141 | 142 | self.send_command(0x24) 143 | for count in range(0, 42): 144 | self.send_data(self.lut_b[count]) 145 | 146 | def Init(self): 147 | if (epdconfig.module_init() != 0): 148 | return -1 149 | # EPD hardware init start 150 | self.reset() 151 | 152 | self.send_command(0xD2) 153 | self.send_data(0x3F) 154 | 155 | self.send_command(0x00) 156 | self.send_data (0x6F) #from outside 157 | 158 | self.send_command(0x01) #power setting 159 | self.send_data (0x03) 160 | self.send_data (0x00) 161 | self.send_data (0x2b) 162 | self.send_data (0x2b) 163 | 164 | self.send_command(0x06) #Configuring the charge pump 165 | self.send_data(0x3f) 166 | 167 | self.send_command(0x2A) #Setting XON and the options of LUT 168 | self.send_data(0x00) 169 | self.send_data(0x00) 170 | 171 | self.send_command(0x30) #Set the clock frequency 172 | self.send_data(0x17) #50Hz 173 | 174 | self.send_command(0x50) #Set VCOM and data output interval 175 | self.send_data(0x57) 176 | 177 | self.send_command(0x60) #Set The non-overlapping period of Gate and Source. 178 | self.send_data(0x22) 179 | 180 | self.send_command(0x61) #resolution setting 181 | self.send_data (0x50) #source 128 182 | self.send_data (0x80) 183 | 184 | self.send_command(0x82) #sets VCOM_DC value 185 | self.send_data(0x12) #-1v 186 | 187 | self.send_command(0xe3)#Set POWER SAVING 188 | self.send_data(0x33) 189 | self.SetFulltReg() 190 | self.send_command(0x04) #power on 191 | self.ReadBusy() 192 | # EPD hardware init end 193 | return 0 194 | 195 | def Partial_Init(self): 196 | self.reset() 197 | 198 | self.send_command(0xD2) 199 | self.send_data(0x3F) 200 | 201 | self.send_command(0x00) 202 | self.send_data (0x6F) #from outside 203 | 204 | self.send_command(0x01) #power setting 205 | self.send_data (0x03) 206 | self.send_data (0x00) 207 | self.send_data (0x2b) 208 | self.send_data (0x2b) 209 | 210 | self.send_command(0x06) #Configuring the charge pump 211 | self.send_data(0x3f) 212 | 213 | self.send_command(0x2A) #Setting XON and the options of LUT 214 | self.send_data(0x00) 215 | self.send_data(0x00) 216 | 217 | self.send_command(0x30) #Set the clock frequency 218 | self.send_data(0x17) 219 | 220 | self.send_command(0x50) #Set VCOM and data output interval 221 | self.send_data(0xf2) 222 | 223 | self.send_command(0x60) #Set The non-overlapping period of Gate and Source. 224 | self.send_data(0x22) 225 | 226 | self.send_command(0x82) #Set VCOM_DC value 227 | self.send_data(0x12)#-1v 228 | 229 | self.send_command(0xe3)#Set POWER SAVING 230 | self.send_data(0x33) 231 | 232 | self.SetPartReg() 233 | 234 | self.send_command(0x04)#Set POWER SAVING 235 | self.ReadBusy() 236 | # EPD hardware init end 237 | return 0 238 | 239 | def getbuffer(self, image): 240 | buf = [0xFF] * (int(self.width / 8) * self.height) 241 | image_monocolor = image.convert('1') 242 | imwidth, imheight = image_monocolor.size 243 | pixels = image_monocolor.load() 244 | if(imwidth == self.width and imheight == self.height): 245 | logging.debug("Horizontal") 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[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 251 | elif(imwidth == self.height and imheight == self.width): 252 | logging.debug("Vertical") 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[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 259 | return buf 260 | 261 | def Display(self, image): 262 | if (image == None): 263 | return 264 | # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) 265 | if(self.width % 8 == 0): 266 | Width = self.width / 8 267 | else: 268 | Width = self.width / 8 + 1 269 | 270 | self.send_command(0x10) 271 | for j in range(0, self.height): 272 | for i in range(0, int(Width)): 273 | self.send_data(0xff) 274 | 275 | self.send_command(0x13) 276 | for j in range(0, self.height): 277 | for i in range(0, int(Width)): 278 | self.send_data(image[i + j * int(Width)]) 279 | self.TurnOnDisplay() 280 | 281 | def Clear(self): 282 | # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) 283 | if(self.width % 8 == 0): 284 | Width = self.width / 8 285 | else: 286 | Width = self.width / 8 + 1 287 | 288 | Height = self.height 289 | 290 | self.send_command(0x10) 291 | for j in range(0, Height): 292 | for i in range(0, int(Width)): 293 | self.send_data(0x00) 294 | 295 | self.send_command(0x13) 296 | for j in range(0, Height): 297 | for i in range(0, int(Width)): 298 | self.send_data(0xff) 299 | self.TurnOnDisplay() 300 | 301 | def DisplayPartial(self, old_Image, Image): 302 | 303 | # Set partial Windows */ 304 | self.send_command(0x91) #This command makes the display enter partial mode 305 | self.send_command(0x90) #resolution setting 306 | self.send_data(0) #x-start 307 | self.send_data(79) #x-end 308 | 309 | self.send_data(0) 310 | self.send_data(127) #y-end 311 | self.send_data(0x00) 312 | 313 | # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) 314 | if(self.width % 8 == 0): 315 | Width = self.width / 8 316 | else: 317 | Width = self.width / 8 + 1 318 | 319 | Height = self.height 320 | # send data 321 | self.send_command(0x10) 322 | for j in range(0, Height): 323 | for i in range(0, int(Width)): 324 | self.send_data(old_Image[i + j * int(Width)]) 325 | 326 | self.send_command(0x13) 327 | for j in range(0, Height): 328 | for i in range(0, int(Width)): 329 | self.send_data(Image[i + j * int(Width)]) 330 | 331 | # Set partial refresh 332 | self.TurnOnDisplay() 333 | 334 | def Sleep(self): 335 | self.send_command(0x50) 336 | self.send_data(0xf7) 337 | self.send_command(0x02) 338 | self.ReadBusy() 339 | self.send_command(0x07) 340 | self.send_data(0xA5) 341 | epdconfig.delay_ms(200) 342 | epdconfig.module_exit() 343 | 344 | ### END OF FILE ### 345 | 346 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in54.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54.py 3 | # * | Author : Waveshare team 4 | # * | Function : Electronic paper driver 5 | # * | Info : 6 | # *---------------- 7 | # * | This version: V3.1 8 | # * | Date : 2019-06-20 9 | # # | Info : python demo 10 | # ----------------------------------------------------------------------------- 11 | # V3.1(2019-06-18): 12 | # 2.remove commands define: 13 | # #define PANEL_SETTING 0x00 14 | # #define POWER_SETTING 0x01 15 | # #define POWER_OFF 0x02 16 | # #define POWER_OFF_SEQUENCE_SETTING 0x03 17 | # #define POWER_ON 0x04 18 | # #define POWER_ON_MEASURE 0x05 19 | # #define BOOSTER_SOFT_START 0x06 20 | # #define DEEP_SLEEP 0x07 21 | # #define DATA_START_TRANSMISSION_1 0x10 22 | # #define DATA_STOP 0x11 23 | # #define DISPLAY_REFRESH 0x12 24 | # #define DATA_START_TRANSMISSION_2 0x13 25 | # #define PLL_CONTROL 0x30 26 | # #define TEMPERATURE_SENSOR_COMMAND 0x40 27 | # #define TEMPERATURE_SENSOR_CALIBRATION 0x41 28 | # #define TEMPERATURE_SENSOR_WRITE 0x42 29 | # #define TEMPERATURE_SENSOR_READ 0x43 30 | # #define VCOM_AND_DATA_INTERVAL_SETTING 0x50 31 | # #define LOW_POWER_DETECTION 0x51 32 | # #define TCON_SETTING 0x60 33 | # #define TCON_RESOLUTION 0x61 34 | # #define SOURCE_AND_GATE_START_SETTING 0x62 35 | # #define GET_STATUS 0x71 36 | # #define AUTO_MEASURE_VCOM 0x80 37 | # #define VCOM_VALUE 0x81 38 | # #define VCM_DC_SETTING_REGISTER 0x82 39 | # #define PROGRAM_MODE 0xA0 40 | # #define ACTIVE_PROGRAM 0xA1 41 | # #define READ_OTP_DATA 0xA2 42 | # ----------------------------------------------------------------------------- 43 | # V3.0(2018-11-01): 44 | # # 1.Remove: 45 | # digital_write(self, pin, value) 46 | # digital_read(self, pin) 47 | # delay_ms(self, delaytime) 48 | # set_lut(self, lut) 49 | # self.lut = self.lut_full_update 50 | # * 2.Change: 51 | # display_frame -> TurnOnDisplay 52 | # set_memory_area -> SetWindow 53 | # set_memory_pointer -> SetCursor 54 | # * 3.How to use 55 | # epd = epd1in54.EPD() 56 | # epd.init(epd.lut_full_update) 57 | # image = Image.new('1', (epd1in54.EPD_WIDTH, epd1in54.EPD_HEIGHT), 255) 58 | # ... 59 | # drawing ...... 60 | # ... 61 | # epd.display(getbuffer(image)) 62 | # ******************************************************************************/ 63 | # Permission is hereby granted, free of charge, to any person obtaining a copy 64 | # of this software and associated documnetation files (the "Software"), to deal 65 | # in the Software without restriction, including without limitation the rights 66 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 67 | # copies of the Software, and to permit persons to whom the Software is 68 | # furished to do so, subject to the following conditions: 69 | # 70 | # The above copyright notice and this permission notice shall be included in 71 | # all copies or substantial portions of the Software. 72 | # 73 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 74 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 75 | # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 76 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 77 | # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 78 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 79 | # THE SOFTWARE. 80 | # 81 | 82 | import logging 83 | from . import epdconfig 84 | 85 | # Display resolution 86 | EPD_WIDTH = 200 87 | EPD_HEIGHT = 200 88 | 89 | class EPD: 90 | def __init__(self): 91 | self.reset_pin = epdconfig.RST_PIN 92 | self.dc_pin = epdconfig.DC_PIN 93 | self.busy_pin = epdconfig.BUSY_PIN 94 | self.cs_pin = epdconfig.CS_PIN 95 | self.width = EPD_WIDTH 96 | self.height = EPD_HEIGHT 97 | 98 | lut_full_update = [ 99 | 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 100 | 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 101 | 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, 102 | 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 103 | ] 104 | 105 | lut_partial_update = [ 106 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 108 | 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 110 | ] 111 | 112 | # Hardware reset 113 | def reset(self): 114 | epdconfig.digital_write(self.reset_pin, 1) 115 | epdconfig.delay_ms(200) 116 | epdconfig.digital_write(self.reset_pin, 0) # module reset 117 | epdconfig.delay_ms(10) 118 | epdconfig.digital_write(self.reset_pin, 1) 119 | epdconfig.delay_ms(200) 120 | 121 | def send_command(self, command): 122 | epdconfig.digital_write(self.dc_pin, 0) 123 | epdconfig.digital_write(self.cs_pin, 0) 124 | epdconfig.spi_writebyte([command]) 125 | epdconfig.digital_write(self.cs_pin, 1) 126 | 127 | def send_data(self, data): 128 | epdconfig.digital_write(self.dc_pin, 1) 129 | epdconfig.digital_write(self.cs_pin, 0) 130 | epdconfig.spi_writebyte([data]) 131 | epdconfig.digital_write(self.cs_pin, 1) 132 | 133 | def ReadBusy(self): 134 | logging.debug("e-Paper busy") 135 | while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy 136 | epdconfig.delay_ms(100) 137 | logging.debug("e-Paper busy release") 138 | 139 | def TurnOnDisplay(self): 140 | self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 141 | self.send_data(0xC4) 142 | self.send_command(0x20) # MASTER_ACTIVATION 143 | self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE 144 | 145 | self.ReadBusy() 146 | 147 | def SetWindow(self, x_start, y_start, x_end, y_end): 148 | self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION 149 | # x point must be the multiple of 8 or the last 3 bits will be ignored 150 | self.send_data((x_start >> 3) & 0xFF) 151 | self.send_data((x_end >> 3) & 0xFF) 152 | self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION 153 | self.send_data(y_start & 0xFF) 154 | self.send_data((y_start >> 8) & 0xFF) 155 | self.send_data(y_end & 0xFF) 156 | self.send_data((y_end >> 8) & 0xFF) 157 | 158 | def SetCursor(self, x, y): 159 | self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER 160 | # x point must be the multiple of 8 or the last 3 bits will be ignored 161 | self.send_data((x >> 3) & 0xFF) 162 | 163 | self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER 164 | self.send_data(y & 0xFF) 165 | self.send_data((y >> 8) & 0xFF) 166 | # self.ReadBusy() 167 | 168 | def init(self, lut): 169 | if (epdconfig.module_init() != 0): 170 | return -1 171 | # EPD hardware init start 172 | self.reset() 173 | 174 | self.send_command(0x01) # DRIVER_OUTPUT_CONTROL 175 | self.send_data((EPD_HEIGHT - 1) & 0xFF) 176 | self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) 177 | self.send_data(0x00) # GD = 0 SM = 0 TB = 0 178 | 179 | self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL 180 | self.send_data(0xD7) 181 | self.send_data(0xD6) 182 | self.send_data(0x9D) 183 | 184 | self.send_command(0x2C) # WRITE_VCOM_REGISTER 185 | self.send_data(0xA8) # VCOM 7C 186 | 187 | self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD 188 | self.send_data(0x1A) # 4 dummy lines per gate 189 | 190 | self.send_command(0x3B) # SET_GATE_TIME 191 | self.send_data(0x08) # 2us per line 192 | 193 | self.send_command(0x11) # DATA_ENTRY_MODE_SETTING 194 | self.send_data(0x03) # X increment Y increment 195 | 196 | # set the look-up table register 197 | self.send_command(0x32) 198 | for i in range(0, len(lut)): 199 | self.send_data(lut[i]) 200 | # EPD hardware init end 201 | return 0 202 | 203 | def getbuffer(self, image): 204 | buf = [0xFF] * (int(self.width / 8) * self.height) 205 | image_monocolor = image.convert('1') 206 | imwidth, imheight = image_monocolor.size 207 | pixels = image_monocolor.load() 208 | if(imwidth == self.width and imheight == self.height): 209 | logging.debug("Horizontal") 210 | for y in range(imheight): 211 | for x in range(imwidth): 212 | # Set the bits for the column of pixels at the current position. 213 | if pixels[x, y] == 0: 214 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 215 | elif(imwidth == self.height and imheight == self.width): 216 | logging.debug("Vertical") 217 | for y in range(imheight): 218 | for x in range(imwidth): 219 | newx = y 220 | newy = self.height - x - 1 221 | if pixels[x, y] == 0: 222 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 223 | return buf 224 | 225 | def display(self, image): 226 | if (image == None): 227 | return 228 | 229 | self.SetWindow(0, 0, self.width, self.height) 230 | for j in range(0, self.height): 231 | self.SetCursor(0, j) 232 | self.send_command(0x24) 233 | for i in range(0, int(self.width / 8)): 234 | self.send_data(image[i + j * int(self.width / 8)]) 235 | self.TurnOnDisplay() 236 | 237 | def Clear(self, color): 238 | # self.SetWindow(0, 0, self.width - 1, self.height - 1) 239 | # send the color data 240 | self.SetWindow(0, 0, self.width, self.height) 241 | # epdconfig.digital_write(self.dc_pin, 1) 242 | # epdconfig.digital_write(self.cs_pin, 0) 243 | for j in range(0, self.height): 244 | self.SetCursor(0, j) 245 | self.send_command(0x24) 246 | for i in range(0, int(self.width / 8)): 247 | self.send_data(color) 248 | # epdconfig.digital_write(self.cs_pin, 1) 249 | self.TurnOnDisplay() 250 | 251 | def sleep(self): 252 | self.send_command(0x10) # DEEP_SLEEP_MODE 253 | self.send_data(0x01) 254 | 255 | epdconfig.module_exit() 256 | 257 | ### END OF FILE ### 258 | 259 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in54_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54_V2.py 3 | # * | Author : Waveshare team 4 | # * | Function : Electronic paper driver 5 | # * | Info : 6 | # *---------------- 7 | # * | This version: V1 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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 200 35 | EPD_HEIGHT = 200 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | # Hardware reset 47 | def reset(self): 48 | epdconfig.digital_write(self.reset_pin, 1) 49 | epdconfig.delay_ms(200) 50 | epdconfig.digital_write(self.reset_pin, 0) 51 | epdconfig.delay_ms(10) 52 | epdconfig.digital_write(self.reset_pin, 1) 53 | epdconfig.delay_ms(200) 54 | 55 | def send_command(self, command): 56 | epdconfig.digital_write(self.dc_pin, 0) 57 | epdconfig.digital_write(self.cs_pin, 0) 58 | epdconfig.spi_writebyte([command]) 59 | epdconfig.digital_write(self.cs_pin, 1) 60 | 61 | def send_data(self, data): 62 | epdconfig.digital_write(self.dc_pin, 1) 63 | epdconfig.digital_write(self.cs_pin, 0) 64 | epdconfig.spi_writebyte([data]) 65 | epdconfig.digital_write(self.cs_pin, 1) 66 | 67 | def ReadBusy(self): 68 | logging.debug("e-Paper busy") 69 | while(epdconfig.digital_read(self.busy_pin) == 1): 70 | epdconfig.delay_ms(100) 71 | logging.debug("e-Paper busy release") 72 | 73 | def TurnOnDisplay(self): 74 | self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 75 | self.send_data(0xF7) 76 | self.send_command(0x20) # MASTER_ACTIVATION 77 | 78 | self.ReadBusy() 79 | 80 | def TurnOnDisplayPart(self): 81 | self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 82 | self.send_data(0xFF) 83 | self.send_command(0x20) # MASTER_ACTIVATION 84 | 85 | self.ReadBusy() 86 | 87 | def init(self): 88 | if (epdconfig.module_init() != 0): 89 | return -1 90 | 91 | # EPD hardware init start 92 | self.reset() 93 | 94 | self.ReadBusy() 95 | self.send_command(0x12) # SWRESET 96 | self.ReadBusy() 97 | 98 | self.send_command(0x01) # DRIVER_OUTPUT_CONTROL 99 | self.send_data(0xC7) # (EPD_HEIGHT - 1) & 0xFF 100 | self.send_data(0x00) # ((EPD_HEIGHT - 1) >> 8) & 0xFF 101 | self.send_data(0x01) # GD = 0 SM = 0 TB = 0 102 | 103 | self.send_command(0x11) # data entry mode 104 | self.send_data(0x01) 105 | 106 | self.send_command(0x44) # set Ram-X address start/end position 107 | self.send_data(0x00) 108 | self.send_data(0x18) # 0x0C-->(18+1)*8=200 109 | 110 | self.send_command(0x45) # set Ram-Y address start/end position 111 | self.send_data(0xC7) # 0xC7-->(199+1)=200 112 | self.send_data(0x00) 113 | self.send_data(0x00) 114 | self.send_data(0x00) 115 | 116 | self.send_command(0x3C) # BorderWavefrom 117 | self.send_data(0x01) 118 | 119 | self.send_command(0x18) 120 | self.send_data(0x80) 121 | 122 | self.send_command(0x22) # #Load Temperature and waveform setting. 123 | self.send_data(0XB1) 124 | self.send_command(0x20) 125 | 126 | self.send_command(0x4E) # set RAM x address count to 0; 127 | self.send_data(0x00) 128 | self.send_command(0x4F) # set RAM y address count to 0X199; 129 | self.send_data(0xC7) 130 | self.send_data(0x00) 131 | 132 | self.ReadBusy() 133 | 134 | def Clear(self, color): 135 | self.send_command(0x24) 136 | for j in range(0, self.height): 137 | for i in range(0, int(self.width / 8)): 138 | self.send_data(color) 139 | self.TurnOnDisplay() 140 | 141 | def getbuffer(self, image): 142 | buf = [0xFF] * (int(self.width/8) * self.height) 143 | image_monocolor = image.convert('1') 144 | imwidth, imheight = image_monocolor.size 145 | pixels = image_monocolor.load() 146 | if(imwidth == self.width and imheight == self.height): 147 | logging.debug("Horizontal") 148 | for y in range(imheight): 149 | for x in range(imwidth): 150 | # Set the bits for the column of pixels at the current position. 151 | if pixels[x, y] == 0: 152 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 153 | elif(imwidth == self.height and imheight == self.width): 154 | logging.debug("Vertical") 155 | for y in range(imheight): 156 | for x in range(imwidth): 157 | newx = y 158 | newy = self.height - x - 1 159 | if pixels[x, y] == 0: 160 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 161 | return buf 162 | 163 | def display(self, image): 164 | if (image == None): 165 | return 166 | 167 | self.send_command(0x24) 168 | for j in range(0, self.height): 169 | for i in range(0, int(self.width / 8)): 170 | self.send_data(image[i + j * int(self.width / 8)]) 171 | self.TurnOnDisplay() 172 | 173 | def displayPartBaseImage(self, image): 174 | if (image == None): 175 | return 176 | 177 | self.send_command(0x24) 178 | for j in range(0, self.height): 179 | for i in range(0, int(self.width / 8)): 180 | self.send_data(image[i + j * int(self.width / 8)]) 181 | 182 | self.send_command(0x26) 183 | for j in range(0, self.height): 184 | for i in range(0, self.width / 8): 185 | self.send_data(image[i + j * int(self.width / 8)]) 186 | 187 | self.TurnOnDisplayPart() 188 | 189 | def displayPart(self, image): 190 | if (image == None): 191 | return 192 | 193 | self.send_command(0x24) 194 | for j in range(0, self.height): 195 | for i in range(0, int(self.width / 8)): 196 | self.send_data(image[i + j * int(self.width / 8)]) 197 | 198 | self.TurnOnDisplayPart() 199 | 200 | def sleep(self): 201 | self.send_command(0x10) # DEEP_SLEEP_MODE 202 | self.send_data(0x01) 203 | 204 | epdconfig.module_exit() 205 | 206 | ### END OF FILE ### 207 | 208 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in54b.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54b.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 200 35 | EPD_HEIGHT = 200 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | lut_vcom0 = [0x0E, 0x14, 0x01, 0x0A, 0x06, 0x04, 0x0A, 0x0A, 0x0F, 0x03, 0x03, 0x0C, 0x06, 0x0A, 0x00] 47 | lut_w = [0x0E, 0x14, 0x01, 0x0A, 0x46, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x86, 0x0A, 0x04] 48 | lut_b = [0x0E, 0x14, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x4A, 0x04] 49 | lut_g1 = [0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04] 50 | lut_g2 = [0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04] 51 | lut_vcom1 = [0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 52 | lut_red0 = [0x83, 0x5D, 0x01, 0x81, 0x48, 0x23, 0x77, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 53 | lut_red1 = [0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 54 | 55 | # Hardware reset 56 | def reset(self): 57 | epdconfig.digital_write(self.reset_pin, 1) 58 | epdconfig.delay_ms(200) 59 | epdconfig.digital_write(self.reset_pin, 0) # module reset 60 | epdconfig.delay_ms(10) 61 | epdconfig.digital_write(self.reset_pin, 1) 62 | epdconfig.delay_ms(200) 63 | 64 | def send_command(self, command): 65 | epdconfig.digital_write(self.dc_pin, 0) 66 | epdconfig.digital_write(self.cs_pin, 0) 67 | epdconfig.spi_writebyte([command]) 68 | epdconfig.digital_write(self.cs_pin, 1) 69 | 70 | def send_data(self, data): 71 | epdconfig.digital_write(self.dc_pin, 1) 72 | epdconfig.digital_write(self.cs_pin, 0) 73 | epdconfig.spi_writebyte([data]) 74 | epdconfig.digital_write(self.cs_pin, 1) 75 | 76 | def ReadBusy(self): 77 | logging.debug("e-Paper busy") 78 | while(epdconfig.digital_read(self.busy_pin) == 0): 79 | epdconfig.delay_ms(100) 80 | logging.debug("e-Paper busy release") 81 | 82 | def set_lut_bw(self): 83 | self.send_command(0x20) # vcom 84 | for count in range(0, 15): 85 | self.send_data(self.lut_vcom0[count]) 86 | self.send_command(0x21) # ww -- 87 | for count in range(0, 15): 88 | self.send_data(self.lut_w[count]) 89 | self.send_command(0x22) # bw r 90 | for count in range(0, 15): 91 | self.send_data(self.lut_b[count]) 92 | self.send_command(0x23) # wb w 93 | for count in range(0, 15): 94 | self.send_data(self.lut_g1[count]) 95 | self.send_command(0x24) # bb b 96 | for count in range(0, 15): 97 | self.send_data(self.lut_g2[count]) 98 | 99 | def set_lut_red(self): 100 | self.send_command(0x25) 101 | for count in range(0, 15): 102 | self.send_data(self.lut_vcom1[count]) 103 | self.send_command(0x26) 104 | for count in range(0, 15): 105 | self.send_data(self.lut_red0[count]) 106 | self.send_command(0x27) 107 | for count in range(0, 15): 108 | self.send_data(self.lut_red1[count]) 109 | 110 | def init(self): 111 | if (epdconfig.module_init() != 0): 112 | return -1 113 | # EPD hardware init start 114 | self.reset() 115 | 116 | self.send_command(0x01) # POWER_SETTING 117 | self.send_data(0x07) 118 | self.send_data(0x00) 119 | self.send_data(0x08) 120 | self.send_data(0x00) 121 | self.send_command(0x06) # BOOSTER_SOFT_START 122 | self.send_data(0x07) 123 | self.send_data(0x07) 124 | self.send_data(0x07) 125 | self.send_command(0x04) # POWER_ON 126 | 127 | self.ReadBusy() 128 | 129 | self.send_command(0X00) # PANEL_SETTING 130 | self.send_data(0xCF) 131 | self.send_command(0X50) # VCOM_AND_DATA_INTERVAL_SETTING 132 | self.send_data(0x17) 133 | self.send_command(0x30) # PLL_CONTROL 134 | self.send_data(0x39) 135 | self.send_command(0x61) # TCON_RESOLUTION set x and y 136 | self.send_data(0xC8) 137 | self.send_data(0x00) 138 | self.send_data(0xC8) 139 | self.send_command(0x82) # VCM_DC_SETTING_REGISTER 140 | self.send_data(0x0E) 141 | 142 | self.set_lut_bw() 143 | self.set_lut_red() 144 | return 0 145 | 146 | def getbuffer(self, image): 147 | buf = [0xFF] * int(self.width * self.height / 8) 148 | # Set buffer to value of Python Imaging Library image. 149 | # Image must be in mode 1. 150 | image_monocolor = image.convert('1') 151 | imwidth, imheight = image_monocolor.size 152 | if imwidth != self.width or imheight != self.height: 153 | raise ValueError('Image must be same dimensions as display \ 154 | ({0}x{1}).' .format(self.width, self.height)) 155 | 156 | pixels = image_monocolor.load() 157 | for y in range(self.height): 158 | for x in range(self.width): 159 | # Set the bits for the column of pixels at the current position. 160 | if pixels[x, y] == 0: 161 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 162 | return buf 163 | 164 | def display(self, blackimage, redimage): 165 | # send black data 166 | if (blackimage != None): 167 | self.send_command(0x10) # DATA_START_TRANSMISSION_1 168 | for i in range(0, int(self.width * self.height / 8)): 169 | temp = 0x00 170 | for bit in range(0, 4): 171 | if (blackimage[i] & (0x80 >> bit) != 0): 172 | temp |= 0xC0 >> (bit * 2) 173 | self.send_data(temp) 174 | temp = 0x00 175 | for bit in range(4, 8): 176 | if (blackimage[i] & (0x80 >> bit) != 0): 177 | temp |= 0xC0 >> ((bit - 4) * 2) 178 | self.send_data(temp) 179 | 180 | # send red data 181 | if (redimage != None): 182 | self.send_command(0x13) # DATA_START_TRANSMISSION_2 183 | for i in range(0, int(self.width * self.height / 8)): 184 | self.send_data(redimage[i]) 185 | 186 | self.send_command(0x12) # DISPLAY_REFRESH 187 | self.ReadBusy() 188 | 189 | def Clear(self): 190 | self.send_command(0x10) # DATA_START_TRANSMISSION_1 191 | for i in range(0, int(self.width * self.height / 8)): 192 | self.send_data(0xFF) 193 | self.send_data(0xFF) 194 | 195 | self.send_command(0x13) # DATA_START_TRANSMISSION_2 196 | for i in range(0, int(self.width * self.height / 8)): 197 | self.send_data(0xFF) 198 | 199 | self.send_command(0x12) # DISPLAY_REFRESH 200 | self.ReadBusy() 201 | 202 | def sleep(self): 203 | self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING 204 | self.send_data(0x17) 205 | self.send_command(0x82) # to solve Vcom drop 206 | self.send_data(0x00) 207 | self.send_command(0x01) # power setting 208 | self.send_data(0x02) # gate switch to external 209 | self.send_data(0x00) 210 | self.send_data(0x00) 211 | self.send_data(0x00) 212 | self.ReadBusy() 213 | 214 | self.send_command(0x02) # power off 215 | 216 | epdconfig.module_exit() 217 | 218 | ### END OF FILE ### 219 | 220 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in54b_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54b.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 200 35 | EPD_HEIGHT = 200 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) # module reset 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 1): 71 | epdconfig.delay_ms(100) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | # EPD hardware init start 78 | self.reset() 79 | 80 | self.ReadBusy() 81 | self.send_command(0x12) #SWRESET 82 | self.ReadBusy() 83 | 84 | self.send_command(0x01) #Driver output control 85 | self.send_data(0xC7) 86 | self.send_data(0x00) 87 | self.send_data(0x01) 88 | 89 | self.send_command(0x11) #data entry mode 90 | self.send_data(0x01) 91 | 92 | self.send_command(0x44) #set Ram-X address start/end position 93 | self.send_data(0x00) 94 | self.send_data(0x18) #0x18-->(24+1)*8=200 95 | 96 | self.send_command(0x45) #set Ram-Y address start/end position 97 | self.send_data(0xC7) #0xC7-->(199+1)=200 98 | self.send_data(0x00) 99 | self.send_data(0x00) 100 | self.send_data(0x00) 101 | 102 | self.send_command(0x3C) #BorderWavefrom 103 | self.send_data(0x05) 104 | 105 | self.send_command(0x18) #Read built-in temperature sensor 106 | self.send_data(0x80) 107 | 108 | self.send_command(0x4E) # set RAM x address count to 0 109 | self.send_data(0x00) 110 | self.send_command(0x4F) # set RAM y address count to 0X199 111 | self.send_data(0xC7) 112 | self.send_data(0x00) 113 | self.ReadBusy() 114 | return 0 115 | 116 | def getbuffer(self, image): 117 | buf = [0xFF] * int(self.width * self.height / 8) 118 | # Set buffer to value of Python Imaging Library image. 119 | # Image must be in mode 1. 120 | image_monocolor = image.convert('1') 121 | imwidth, imheight = image_monocolor.size 122 | if imwidth != self.width or imheight != self.height: 123 | raise ValueError('Image must be same dimensions as display \ 124 | ({0}x{1}).' .format(self.width, self.height)) 125 | 126 | pixels = image_monocolor.load() 127 | for y in range(self.height): 128 | for x in range(self.width): 129 | # Set the bits for the column of pixels at the current position. 130 | if pixels[x, y] == 0: 131 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 132 | return buf 133 | 134 | def display(self, blackimage, redimage): 135 | # send black data 136 | if (blackimage != None): 137 | self.send_command(0x24) # DATA_START_TRANSMISSION_1 138 | for i in range(0, int(self.width * self.height / 8)): 139 | self.send_data(blackimage[i]) 140 | 141 | # send red data 142 | if (redimage != None): 143 | self.send_command(0x26) # DATA_START_TRANSMISSION_2 144 | for i in range(0, int(self.width * self.height / 8)): 145 | self.send_data(~redimage[i]) 146 | 147 | self.send_command(0x22) # DISPLAY_REFRESH 148 | self.send_data(0xF7) 149 | self.send_command(0x20) # DISPLAY_REFRESH 150 | self.ReadBusy() 151 | 152 | def Clear(self): 153 | self.send_command(0x24) # DATA_START_TRANSMISSION_1 154 | for i in range(0, int(self.width * self.height / 8)): 155 | self.send_data(0xFF) 156 | 157 | self.send_command(0x26) # DATA_START_TRANSMISSION_2 158 | for i in range(0, int(self.width * self.height / 8)): 159 | self.send_data(0x00) 160 | 161 | self.send_command(0x22) # DISPLAY_REFRESH 162 | self.send_data(0xF7) 163 | self.send_command(0x20) # DISPLAY_REFRESH 164 | self.ReadBusy() 165 | 166 | 167 | def sleep(self): 168 | self.send_command(0x10) #enter deep sleep 169 | self.send_data(0x01) 170 | epdconfig.module_exit() 171 | 172 | ### END OF FILE ### 173 | 174 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd1in54c.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd1in54c.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 | 32 | # Display resolution 33 | EPD_WIDTH = 152 34 | EPD_HEIGHT = 152 35 | 36 | class EPD: 37 | def __init__(self): 38 | self.reset_pin = epdconfig.RST_PIN 39 | self.dc_pin = epdconfig.DC_PIN 40 | self.busy_pin = epdconfig.BUSY_PIN 41 | self.cs_pin = epdconfig.CS_PIN 42 | self.width = EPD_WIDTH 43 | self.height = EPD_HEIGHT 44 | 45 | # Hardware reset 46 | def reset(self): 47 | epdconfig.digital_write(self.reset_pin, 1) 48 | epdconfig.delay_ms(10) 49 | epdconfig.digital_write(self.reset_pin, 0) 50 | epdconfig.delay_ms(1) 51 | epdconfig.digital_write(self.reset_pin, 1) 52 | epdconfig.delay_ms(10) 53 | 54 | def send_command(self, command): 55 | epdconfig.digital_write(self.dc_pin, 0) 56 | epdconfig.digital_write(self.cs_pin, 0) 57 | epdconfig.spi_writebyte([command]) 58 | epdconfig.digital_write(self.cs_pin, 1) 59 | 60 | def send_data(self, data): 61 | epdconfig.digital_write(self.dc_pin, 1) 62 | epdconfig.digital_write(self.cs_pin, 0) 63 | epdconfig.spi_writebyte([data]) 64 | epdconfig.digital_write(self.cs_pin, 1) 65 | 66 | def ReadBusy(self): 67 | logging.debug("e-Paper busy") 68 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 69 | epdconfig.delay_ms(200) 70 | logging.debug("e-Paper busy release") 71 | 72 | def init(self): 73 | if (epdconfig.module_init() != 0): 74 | return -1 75 | # EPD hardware init start 76 | self.reset() 77 | 78 | self.send_command(0x06) # boost soft start 79 | self.send_data(0x17) 80 | self.send_data(0x17) 81 | self.send_data(0x17) 82 | self.send_command(0x04) # power on 83 | 84 | self.ReadBusy() 85 | 86 | self.send_command(0x00) # panel setting 87 | self.send_data(0x0f) # LUT from OTP,160x296 88 | self.send_data(0x0d) # VCOM to 0V fast 89 | 90 | self.send_command(0x61) # resolution setting 91 | self.send_data(0x98) 92 | self.send_data(0x00) 93 | self.send_data(0x98) 94 | 95 | self.send_command(0x50) 96 | self.send_data(0x77) 97 | 98 | def getbuffer(self, image): 99 | buf = [0xFF] * (int(self.width/8) * self.height) 100 | image_monocolor = image.convert('1') 101 | imwidth, imheight = image_monocolor.size 102 | pixels = image_monocolor.load() 103 | if(imwidth == self.width and imheight == self.height): 104 | logging.debug("Horizontal") 105 | for y in range(imheight): 106 | for x in range(imwidth): 107 | # Set the bits for the column of pixels at the current position. 108 | if pixels[x, y] == 0: 109 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 110 | elif(imwidth == self.height and imheight == self.width): 111 | logging.debug("Vertical") 112 | for y in range(imheight): 113 | for x in range(imwidth): 114 | newx = y 115 | newy = self.height - x - 1 116 | if pixels[x, y] == 0: 117 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 118 | return buf 119 | 120 | def display(self, blackimage, yellowimage): 121 | self.send_command(0x10) 122 | logging.debug("blackimage") 123 | for i in range(0, int(self.width * self.height / 8)): 124 | self.send_data(blackimage[i]) 125 | self.send_command(0x13) 126 | logging.debug("yellowimage") 127 | for i in range(0, int(self.width * self.height / 8)): 128 | self.send_data(yellowimage[i]) 129 | 130 | self.send_command(0x12) 131 | self.ReadBusy() 132 | 133 | def Clear(self): 134 | self.send_command(0x10) 135 | for i in range(0, int(self.width * self.height / 8)): 136 | self.send_data(0xFF) 137 | self.send_command(0x13) 138 | for i in range(0, int(self.width * self.height / 8)): 139 | self.send_data(0xFF) 140 | 141 | self.send_command(0x12) 142 | self.ReadBusy() 143 | 144 | # after this, call epd.init() to awaken the module 145 | def sleep(self): 146 | self.send_command(0X02) # power off 147 | self.ReadBusy() 148 | self.send_command(0X07) # deep sleep 149 | self.send_data(0xA5) 150 | 151 | epdconfig.module_exit() 152 | ### END OF FILE ### 153 | 154 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in13.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in13.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | import numpy as np 34 | 35 | # Display resolution 36 | EPD_WIDTH = 122 37 | EPD_HEIGHT = 250 38 | 39 | class EPD: 40 | def __init__(self): 41 | self.reset_pin = epdconfig.RST_PIN 42 | self.dc_pin = epdconfig.DC_PIN 43 | self.busy_pin = epdconfig.BUSY_PIN 44 | self.cs_pin = epdconfig.CS_PIN 45 | self.width = EPD_WIDTH 46 | self.height = EPD_HEIGHT 47 | 48 | lut_full_update = [ 49 | 0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 52 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 53 | ] 54 | 55 | lut_partial_update = [ 56 | 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 60 | ] 61 | 62 | # Hardware reset 63 | def reset(self): 64 | epdconfig.digital_write(self.reset_pin, 1) 65 | epdconfig.delay_ms(200) 66 | epdconfig.digital_write(self.reset_pin, 0) 67 | epdconfig.delay_ms(10) 68 | epdconfig.digital_write(self.reset_pin, 1) 69 | epdconfig.delay_ms(200) 70 | 71 | def send_command(self, command): 72 | epdconfig.digital_write(self.dc_pin, 0) 73 | epdconfig.digital_write(self.cs_pin, 0) 74 | epdconfig.spi_writebyte([command]) 75 | epdconfig.digital_write(self.cs_pin, 1) 76 | 77 | def send_data(self, data): 78 | epdconfig.digital_write(self.dc_pin, 1) 79 | epdconfig.digital_write(self.cs_pin, 0) 80 | epdconfig.spi_writebyte([data]) 81 | epdconfig.digital_write(self.cs_pin, 1) 82 | 83 | def ReadBusy(self): 84 | while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy 85 | epdconfig.delay_ms(100) 86 | 87 | def TurnOnDisplay(self): 88 | self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 89 | self.send_data(0xC4) 90 | self.send_command(0x20) # MASTER_ACTIVATION 91 | self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE 92 | 93 | logging.debug("e-Paper busy") 94 | self.ReadBusy() 95 | logging.debug("e-Paper busy release") 96 | 97 | def init(self, lut): 98 | if (epdconfig.module_init() != 0): 99 | return -1 100 | # EPD hardware init start 101 | self.reset() 102 | self.send_command(0x01) # DRIVER_OUTPUT_CONTROL 103 | self.send_data((EPD_HEIGHT - 1) & 0xFF) 104 | self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) 105 | self.send_data(0x00) # GD = 0 SM = 0 TB = 0 106 | 107 | self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL 108 | self.send_data(0xD7) 109 | self.send_data(0xD6) 110 | self.send_data(0x9D) 111 | 112 | self.send_command(0x2C) # WRITE_VCOM_REGISTER 113 | self.send_data(0xA8) # VCOM 7C 114 | 115 | self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD 116 | self.send_data(0x1A) # 4 dummy lines per gate 117 | 118 | self.send_command(0x3B) # SET_GATE_TIME 119 | self.send_data(0x08) # 2us per line 120 | 121 | self.send_command(0X3C) # BORDER_WAVEFORM_CONTROL 122 | self.send_data(0x03) 123 | 124 | self.send_command(0X11) # DATA_ENTRY_MODE_SETTING 125 | self.send_data(0x03) # X increment; Y increment 126 | 127 | # WRITE_LUT_REGISTER 128 | self.send_command(0x32) 129 | for count in range(30): 130 | self.send_data(lut[count]) 131 | 132 | return 0 133 | 134 | ## 135 | # @brief: specify the memory area for data R/W 136 | ## 137 | def SetWindows(self, x_start, y_start, x_end, y_end): 138 | self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION 139 | self.send_data((x_start >> 3) & 0xFF) 140 | self.send_data((x_end >> 3) & 0xFF) 141 | self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION 142 | self.send_data(y_start & 0xFF) 143 | self.send_data((y_start >> 8) & 0xFF) 144 | self.send_data(y_end & 0xFF) 145 | self.send_data((y_end >> 8) & 0xFF) 146 | 147 | ## 148 | # @brief: specify the start point for data R/W 149 | ## 150 | def SetCursor(self, x, y): 151 | self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER 152 | # x point must be the multiple of 8 or the last 3 bits will be ignored 153 | self.send_data((x >> 3) & 0xFF) 154 | self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER 155 | self.send_data(y & 0xFF) 156 | self.send_data((y >> 8) & 0xFF) 157 | self.ReadBusy() 158 | 159 | def getbuffer(self, image): 160 | if self.width%8 == 0: 161 | linewidth = int(self.width/8) 162 | else: 163 | linewidth = int(self.width/8) + 1 164 | 165 | buf = [0xFF] * (linewidth * self.height) 166 | image_monocolor = image.convert('1') 167 | imwidth, imheight = image_monocolor.size 168 | pixels = image_monocolor.load() 169 | 170 | if(imwidth == self.width and imheight == self.height): 171 | logging.debug("Vertical") 172 | for y in range(imheight): 173 | for x in range(imwidth): 174 | if pixels[x, y] == 0: 175 | # x = imwidth - x 176 | buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8)) 177 | elif(imwidth == self.height and imheight == self.width): 178 | logging.debug("Horizontal") 179 | for y in range(imheight): 180 | for x in range(imwidth): 181 | newx = y 182 | newy = self.height - x - 1 183 | if pixels[x, y] == 0: 184 | # newy = imwidth - newy - 1 185 | buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8)) 186 | return buf 187 | 188 | 189 | def display(self, image): 190 | if self.width%8 == 0: 191 | linewidth = int(self.width/8) 192 | else: 193 | linewidth = int(self.width/8) + 1 194 | 195 | self.SetWindows(0, 0, self.width, self.height); 196 | for j in range(0, self.height): 197 | self.SetCursor(0, j); 198 | self.send_command(0x24); 199 | for i in range(0, linewidth): 200 | self.send_data(image[i + j * linewidth]) 201 | self.TurnOnDisplay() 202 | 203 | def Clear(self, color): 204 | if self.width%8 == 0: 205 | linewidth = int(self.width/8) 206 | else: 207 | linewidth = int(self.width/8) + 1 208 | 209 | self.SetWindows(0, 0, self.width, self.height); 210 | for j in range(0, self.height): 211 | self.SetCursor(0, j); 212 | self.send_command(0x24); 213 | for i in range(0, linewidth): 214 | self.send_data(color) 215 | self.TurnOnDisplay() 216 | 217 | def sleep(self): 218 | self.send_command(0x10) #enter deep sleep 219 | self.send_data(0x01) 220 | epdconfig.delay_ms(100) 221 | 222 | epdconfig.module_exit() 223 | 224 | ### END OF FILE ### 225 | 226 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in13_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in13_V2.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | import numpy as np 34 | 35 | # Display resolution 36 | EPD_WIDTH = 122 37 | EPD_HEIGHT = 250 38 | 39 | class EPD: 40 | def __init__(self): 41 | self.reset_pin = epdconfig.RST_PIN 42 | self.dc_pin = epdconfig.DC_PIN 43 | self.busy_pin = epdconfig.BUSY_PIN 44 | self.cs_pin = epdconfig.CS_PIN 45 | self.width = EPD_WIDTH 46 | self.height = EPD_HEIGHT 47 | 48 | FULL_UPDATE = 0 49 | PART_UPDATE = 1 50 | lut_full_update= [ 51 | 0x80,0x60,0x40,0x00,0x00,0x00,0x00, #LUT0: BB: VS 0 ~7 52 | 0x10,0x60,0x20,0x00,0x00,0x00,0x00, #LUT1: BW: VS 0 ~7 53 | 0x80,0x60,0x40,0x00,0x00,0x00,0x00, #LUT2: WB: VS 0 ~7 54 | 0x10,0x60,0x20,0x00,0x00,0x00,0x00, #LUT3: WW: VS 0 ~7 55 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT4: VCOM: VS 0 ~7 56 | 57 | 0x03,0x03,0x00,0x00,0x02, # TP0 A~D RP0 58 | 0x09,0x09,0x00,0x00,0x02, # TP1 A~D RP1 59 | 0x03,0x03,0x00,0x00,0x02, # TP2 A~D RP2 60 | 0x00,0x00,0x00,0x00,0x00, # TP3 A~D RP3 61 | 0x00,0x00,0x00,0x00,0x00, # TP4 A~D RP4 62 | 0x00,0x00,0x00,0x00,0x00, # TP5 A~D RP5 63 | 0x00,0x00,0x00,0x00,0x00, # TP6 A~D RP6 64 | 65 | 0x15,0x41,0xA8,0x32,0x30,0x0A, 66 | ] 67 | 68 | lut_partial_update = [ #20 bytes 69 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT0: BB: VS 0 ~7 70 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00, #LUT1: BW: VS 0 ~7 71 | 0x40,0x00,0x00,0x00,0x00,0x00,0x00, #LUT2: WB: VS 0 ~7 72 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT3: WW: VS 0 ~7 73 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT4: VCOM: VS 0 ~7 74 | 75 | 0x0A,0x00,0x00,0x00,0x00, # TP0 A~D RP0 76 | 0x00,0x00,0x00,0x00,0x00, # TP1 A~D RP1 77 | 0x00,0x00,0x00,0x00,0x00, # TP2 A~D RP2 78 | 0x00,0x00,0x00,0x00,0x00, # TP3 A~D RP3 79 | 0x00,0x00,0x00,0x00,0x00, # TP4 A~D RP4 80 | 0x00,0x00,0x00,0x00,0x00, # TP5 A~D RP5 81 | 0x00,0x00,0x00,0x00,0x00, # TP6 A~D RP6 82 | 83 | 0x15,0x41,0xA8,0x32,0x30,0x0A, 84 | ] 85 | 86 | # Hardware reset 87 | def reset(self): 88 | epdconfig.digital_write(self.reset_pin, 1) 89 | epdconfig.delay_ms(200) 90 | epdconfig.digital_write(self.reset_pin, 0) 91 | epdconfig.delay_ms(10) 92 | epdconfig.digital_write(self.reset_pin, 1) 93 | epdconfig.delay_ms(200) 94 | 95 | def send_command(self, command): 96 | epdconfig.digital_write(self.dc_pin, 0) 97 | epdconfig.digital_write(self.cs_pin, 0) 98 | epdconfig.spi_writebyte([command]) 99 | epdconfig.digital_write(self.cs_pin, 1) 100 | 101 | def send_data(self, data): 102 | epdconfig.digital_write(self.dc_pin, 1) 103 | epdconfig.digital_write(self.cs_pin, 0) 104 | epdconfig.spi_writebyte([data]) 105 | epdconfig.digital_write(self.cs_pin, 1) 106 | 107 | def ReadBusy(self): 108 | while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy 109 | epdconfig.delay_ms(100) 110 | 111 | def TurnOnDisplay(self): 112 | self.send_command(0x22) 113 | self.send_data(0xC7) 114 | self.send_command(0x20) 115 | self.ReadBusy() 116 | 117 | def TurnOnDisplayPart(self): 118 | self.send_command(0x22) 119 | self.send_data(0x0c) 120 | self.send_command(0x20) 121 | self.ReadBusy() 122 | 123 | def init(self, update): 124 | if (epdconfig.module_init() != 0): 125 | return -1 126 | # EPD hardware init start 127 | self.reset() 128 | if(update == self.FULL_UPDATE): 129 | self.ReadBusy() 130 | self.send_command(0x12) # soft reset 131 | self.ReadBusy() 132 | 133 | self.send_command(0x74) #set analog block control 134 | self.send_data(0x54) 135 | self.send_command(0x7E) #set digital block control 136 | self.send_data(0x3B) 137 | 138 | self.send_command(0x01) #Driver output control 139 | self.send_data(0xF9) 140 | self.send_data(0x00) 141 | self.send_data(0x00) 142 | 143 | self.send_command(0x11) #data entry mode 144 | self.send_data(0x01) 145 | 146 | self.send_command(0x44) #set Ram-X address start/end position 147 | self.send_data(0x00) 148 | self.send_data(0x0F) #0x0C-->(15+1)*8=128 149 | 150 | self.send_command(0x45) #set Ram-Y address start/end position 151 | self.send_data(0xF9) #0xF9-->(249+1)=250 152 | self.send_data(0x00) 153 | self.send_data(0x00) 154 | self.send_data(0x00) 155 | 156 | self.send_command(0x3C) #BorderWavefrom 157 | self.send_data(0x03) 158 | 159 | self.send_command(0x2C) #VCOM Voltage 160 | self.send_data(0x55) # 161 | 162 | self.send_command(0x03) 163 | self.send_data(self.lut_full_update[70]) 164 | 165 | self.send_command(0x04) # 166 | self.send_data(self.lut_full_update[71]) 167 | self.send_data(self.lut_full_update[72]) 168 | self.send_data(self.lut_full_update[73]) 169 | 170 | self.send_command(0x3A) #Dummy Line 171 | self.send_data(self.lut_full_update[74]) 172 | self.send_command(0x3B) #Gate time 173 | self.send_data(self.lut_full_update[75]) 174 | 175 | self.send_command(0x32) 176 | for count in range(70): 177 | self.send_data(self.lut_full_update[count]) 178 | 179 | self.send_command(0x4E) # set RAM x address count to 0 180 | self.send_data(0x00) 181 | self.send_command(0x4F) # set RAM y address count to 0X127 182 | self.send_data(0xF9) 183 | self.send_data(0x00) 184 | self.ReadBusy() 185 | else: 186 | self.send_command(0x2C) #VCOM Voltage 187 | self.send_data(0x26) 188 | 189 | self.ReadBusy() 190 | 191 | self.send_command(0x32) 192 | for count in range(70): 193 | self.send_data(self.lut_partial_update[count]) 194 | 195 | self.send_command(0x37) 196 | self.send_data(0x00) 197 | self.send_data(0x00) 198 | self.send_data(0x00) 199 | self.send_data(0x00) 200 | self.send_data(0x40) 201 | self.send_data(0x00) 202 | self.send_data(0x00) 203 | 204 | self.send_command(0x22) 205 | self.send_data(0xC0) 206 | self.send_command(0x20) 207 | self.ReadBusy() 208 | 209 | self.send_command(0x3C) #BorderWavefrom 210 | self.send_data(0x01) 211 | return 0 212 | 213 | def getbuffer(self, image): 214 | if self.width%8 == 0: 215 | linewidth = int(self.width/8) 216 | else: 217 | linewidth = int(self.width/8) + 1 218 | 219 | buf = [0xFF] * (linewidth * self.height) 220 | image_monocolor = image.convert('1') 221 | imwidth, imheight = image_monocolor.size 222 | pixels = image_monocolor.load() 223 | 224 | if(imwidth == self.width and imheight == self.height): 225 | logging.debug("Vertical") 226 | for y in range(imheight): 227 | for x in range(imwidth): 228 | if pixels[x, y] == 0: 229 | x = imwidth - x 230 | buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8)) 231 | elif(imwidth == self.height and imheight == self.width): 232 | logging.debug("Horizontal") 233 | for y in range(imheight): 234 | for x in range(imwidth): 235 | newx = y 236 | newy = self.height - x - 1 237 | if pixels[x, y] == 0: 238 | newy = imwidth - newy - 1 239 | buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8)) 240 | return buf 241 | 242 | 243 | def display(self, image): 244 | if self.width%8 == 0: 245 | linewidth = int(self.width/8) 246 | else: 247 | linewidth = int(self.width/8) + 1 248 | 249 | self.send_command(0x24) 250 | for j in range(0, self.height): 251 | for i in range(0, linewidth): 252 | self.send_data(image[i + j * linewidth]) 253 | self.TurnOnDisplay() 254 | 255 | def displayPartial(self, image): 256 | if self.width%8 == 0: 257 | linewidth = int(self.width/8) 258 | else: 259 | linewidth = int(self.width/8) + 1 260 | 261 | self.send_command(0x24) 262 | for j in range(0, self.height): 263 | for i in range(0, linewidth): 264 | self.send_data(image[i + j * linewidth]) 265 | 266 | 267 | # self.send_command(0x26) 268 | # for j in range(0, self.height): 269 | # for i in range(0, linewidth): 270 | # self.send_data(~image[i + j * linewidth]) 271 | self.TurnOnDisplayPart() 272 | 273 | def displayPartBaseImage(self, image): 274 | if self.width%8 == 0: 275 | linewidth = int(self.width/8) 276 | else: 277 | linewidth = int(self.width/8) + 1 278 | 279 | self.send_command(0x24) 280 | for j in range(0, self.height): 281 | for i in range(0, linewidth): 282 | self.send_data(image[i + j * linewidth]) 283 | 284 | 285 | self.send_command(0x26) 286 | for j in range(0, self.height): 287 | for i in range(0, linewidth): 288 | self.send_data(image[i + j * linewidth]) 289 | self.TurnOnDisplay() 290 | 291 | def Clear(self, color): 292 | if self.width%8 == 0: 293 | linewidth = int(self.width/8) 294 | else: 295 | linewidth = int(self.width/8) + 1 296 | # logging.debug(linewidth) 297 | 298 | self.send_command(0x24) 299 | for j in range(0, self.height): 300 | for i in range(0, linewidth): 301 | self.send_data(color) 302 | self.TurnOnDisplay() 303 | 304 | def sleep(self): 305 | self.send_command(0x22) #POWER OFF 306 | self.send_data(0xC3) 307 | self.send_command(0x20) 308 | 309 | self.send_command(0x10) #enter deep sleep 310 | self.send_data(0x01) 311 | epdconfig.delay_ms(100) 312 | 313 | epdconfig.module_exit() 314 | 315 | ### END OF FILE ### 316 | 317 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in13b_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in13bc.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 104 35 | EPD_HEIGHT = 212 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | # Hardware reset 47 | def reset(self): 48 | epdconfig.digital_write(self.reset_pin, 1) 49 | epdconfig.delay_ms(200) 50 | epdconfig.digital_write(self.reset_pin, 0) 51 | epdconfig.delay_ms(10) 52 | epdconfig.digital_write(self.reset_pin, 1) 53 | epdconfig.delay_ms(200) 54 | 55 | def send_command(self, command): 56 | epdconfig.digital_write(self.dc_pin, 0) 57 | epdconfig.digital_write(self.cs_pin, 0) 58 | epdconfig.spi_writebyte([command]) 59 | epdconfig.digital_write(self.cs_pin, 1) 60 | 61 | def send_data(self, data): 62 | epdconfig.digital_write(self.dc_pin, 1) 63 | epdconfig.digital_write(self.cs_pin, 0) 64 | epdconfig.spi_writebyte([data]) 65 | epdconfig.digital_write(self.cs_pin, 1) 66 | 67 | def ReadBusy(self): 68 | logging.debug("e-Paper busy") 69 | self.send_command(0x71); 70 | while(epdconfig.digital_read(self.busy_pin) == 0): 71 | self.send_command(0x71); 72 | epdconfig.delay_ms(100) 73 | logging.debug("e-Paper busy release") 74 | 75 | def init(self): 76 | if (epdconfig.module_init() != 0): 77 | return -1 78 | 79 | self.reset() 80 | self.send_command(0x04); 81 | self.ReadBusy();#waiting for the electronic paper IC to release the idle signal 82 | 83 | self.send_command(0x00); #panel setting 84 | self.send_data(0x0f); #LUT from OTP,128x296 85 | self.send_data(0x89); #Temperature sensor, boost and other related timing settings 86 | 87 | self.send_command(0x61); #resolution setting 88 | self.send_data (0x68); 89 | self.send_data (0x00); 90 | self.send_data (0xD4); 91 | 92 | self.send_command(0X50); #VCOM AND DATA INTERVAL SETTING 93 | self.send_data(0x77); #WBmode:VBDF 17|D7 VBDW 97 VBDB 57 94 | # WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7 95 | 96 | return 0 97 | 98 | def getbuffer(self, image): 99 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 100 | buf = [0xFF] * (int(self.width/8) * self.height) 101 | image_monocolor = image.convert('1') 102 | imwidth, imheight = image_monocolor.size 103 | pixels = image_monocolor.load() 104 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 105 | if(imwidth == self.width and imheight == self.height): 106 | logging.debug("Vertical") 107 | for y in range(imheight): 108 | for x in range(imwidth): 109 | # Set the bits for the column of pixels at the current position. 110 | if pixels[x, y] == 0: 111 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 112 | elif(imwidth == self.height and imheight == self.width): 113 | logging.debug("Horizontal") 114 | for y in range(imheight): 115 | for x in range(imwidth): 116 | newx = y 117 | newy = self.height - x - 1 118 | if pixels[x, y] == 0: 119 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 120 | return buf 121 | 122 | def display(self, imageblack, imagered): 123 | self.send_command(0x10) 124 | for i in range(0, int(self.width * self.height / 8)): 125 | self.send_data(imageblack[i]) 126 | 127 | self.send_command(0x13) 128 | for i in range(0, int(self.width * self.height / 8)): 129 | self.send_data(imagered[i]) 130 | 131 | self.send_command(0x12) # REFRESH 132 | epdconfig.delay_ms(100) 133 | self.ReadBusy() 134 | 135 | def Clear(self): 136 | self.send_command(0x10) 137 | for i in range(0, int(self.width * self.height / 8)): 138 | self.send_data(0xFF) 139 | 140 | self.send_command(0x13) 141 | for i in range(0, int(self.width * self.height / 8)): 142 | self.send_data(0xFF) 143 | 144 | self.send_command(0x12) # REFRESH 145 | epdconfig.delay_ms(100) 146 | self.ReadBusy() 147 | 148 | def sleep(self): 149 | self.send_command(0X50) 150 | self.send_data(0xf7) 151 | self.send_command(0X02) 152 | self.ReadBusy() 153 | self.send_command(0x07) # DEEP_SLEEP 154 | self.send_data(0xA5) # check code 155 | 156 | epdconfig.module_exit() 157 | ### END OF FILE ### 158 | 159 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in13bc.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in13bc.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 104 35 | EPD_HEIGHT = 212 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | # Hardware reset 47 | def reset(self): 48 | epdconfig.digital_write(self.reset_pin, 1) 49 | epdconfig.delay_ms(200) 50 | epdconfig.digital_write(self.reset_pin, 0) 51 | epdconfig.delay_ms(10) 52 | epdconfig.digital_write(self.reset_pin, 1) 53 | epdconfig.delay_ms(200) 54 | 55 | def send_command(self, command): 56 | epdconfig.digital_write(self.dc_pin, 0) 57 | epdconfig.digital_write(self.cs_pin, 0) 58 | epdconfig.spi_writebyte([command]) 59 | epdconfig.digital_write(self.cs_pin, 1) 60 | 61 | def send_data(self, data): 62 | epdconfig.digital_write(self.dc_pin, 1) 63 | epdconfig.digital_write(self.cs_pin, 0) 64 | epdconfig.spi_writebyte([data]) 65 | epdconfig.digital_write(self.cs_pin, 1) 66 | 67 | def ReadBusy(self): 68 | logging.debug("e-Paper busy") 69 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 70 | epdconfig.delay_ms(100) 71 | logging.debug("e-Paper busy release") 72 | 73 | def init(self): 74 | if (epdconfig.module_init() != 0): 75 | return -1 76 | 77 | self.reset() 78 | 79 | self.send_command(0x06) # BOOSTER_SOFT_START 80 | self.send_data(0x17) 81 | self.send_data(0x17) 82 | self.send_data(0x17) 83 | 84 | self.send_command(0x04) # POWER_ON 85 | self.ReadBusy() 86 | 87 | self.send_command(0x00) # PANEL_SETTING 88 | self.send_data(0x8F) 89 | 90 | self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING 91 | self.send_data(0xF0) 92 | 93 | self.send_command(0x61) # RESOLUTION_SETTING 94 | self.send_data(self.width & 0xff) 95 | self.send_data(self.height >> 8) 96 | self.send_data(self.height & 0xff) 97 | return 0 98 | 99 | def getbuffer(self, image): 100 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 101 | buf = [0xFF] * (int(self.width/8) * self.height) 102 | image_monocolor = image.convert('1') 103 | imwidth, imheight = image_monocolor.size 104 | pixels = image_monocolor.load() 105 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 106 | if(imwidth == self.width and imheight == self.height): 107 | logging.debug("Vertical") 108 | for y in range(imheight): 109 | for x in range(imwidth): 110 | # Set the bits for the column of pixels at the current position. 111 | if pixels[x, y] == 0: 112 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 113 | elif(imwidth == self.height and imheight == self.width): 114 | logging.debug("Horizontal") 115 | for y in range(imheight): 116 | for x in range(imwidth): 117 | newx = y 118 | newy = self.height - x - 1 119 | if pixels[x, y] == 0: 120 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 121 | return buf 122 | 123 | def display(self, imageblack, imagered): 124 | self.send_command(0x10) 125 | for i in range(0, int(self.width * self.height / 8)): 126 | self.send_data(imageblack[i]) 127 | self.send_command(0x92) 128 | 129 | self.send_command(0x13) 130 | for i in range(0, int(self.width * self.height / 8)): 131 | self.send_data(imagered[i]) 132 | self.send_command(0x92) 133 | 134 | self.send_command(0x12) # REFRESH 135 | self.ReadBusy() 136 | 137 | def Clear(self): 138 | self.send_command(0x10) 139 | for i in range(0, int(self.width * self.height / 8)): 140 | self.send_data(0xFF) 141 | self.send_command(0x92) 142 | 143 | self.send_command(0x13) 144 | for i in range(0, int(self.width * self.height / 8)): 145 | self.send_data(0xFF) 146 | self.send_command(0x92) 147 | 148 | self.send_command(0x12) # REFRESH 149 | self.ReadBusy() 150 | 151 | def sleep(self): 152 | self.send_command(0x02) # POWER_OFF 153 | self.ReadBusy() 154 | self.send_command(0x07) # DEEP_SLEEP 155 | self.send_data(0xA5) # check code 156 | 157 | epdconfig.module_exit() 158 | ### END OF FILE ### 159 | 160 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in7b.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in7b.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 176 36 | EPD_HEIGHT = 264 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | lut_vcom_dc = [ 48 | 0x00, 0x00, 49 | 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01, 50 | 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08, 51 | 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10, 52 | 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08, 53 | 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 54 | 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 55 | 0x00, 0x23, 0x00, 0x00, 0x00, 0x01 56 | ] 57 | 58 | lut_ww = [ 59 | 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 60 | 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08, 61 | 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 62 | 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08, 63 | 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 64 | 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 65 | 0x00, 0x23, 0x00, 0x00, 0x00, 0x01 66 | ] 67 | 68 | # R22H r 69 | lut_bw = [ 70 | 0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01, 71 | 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08, 72 | 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 73 | 0x90, 0x0A, 0x0A, 0x00, 0x00, 0x08, 74 | 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05, 75 | 0xB0, 0x03, 0x0E, 0x00, 0x00, 0x0A, 76 | 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01 77 | ] 78 | 79 | # R23H w 80 | lut_bb = [ 81 | 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 82 | 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08, 83 | 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 84 | 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08, 85 | 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 86 | 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 87 | 0x00, 0x23, 0x00, 0x00, 0x00, 0x01 88 | ] 89 | # R24H b 90 | lut_wb = [ 91 | 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 92 | 0x20, 0x0A, 0x0A, 0x00, 0x00, 0x08, 93 | 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 94 | 0x10, 0x0A, 0x0A, 0x00, 0x00, 0x08, 95 | 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 96 | 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 97 | 0x00, 0x23, 0x00, 0x00, 0x00, 0x01 98 | ] 99 | 100 | # Hardware reset 101 | def reset(self): 102 | epdconfig.digital_write(self.reset_pin, 1) 103 | epdconfig.delay_ms(200) 104 | epdconfig.digital_write(self.reset_pin, 0) 105 | epdconfig.delay_ms(10) 106 | epdconfig.digital_write(self.reset_pin, 1) 107 | epdconfig.delay_ms(200) 108 | 109 | def send_command(self, command): 110 | epdconfig.digital_write(self.dc_pin, 0) 111 | epdconfig.digital_write(self.cs_pin, 0) 112 | epdconfig.spi_writebyte([command]) 113 | epdconfig.digital_write(self.cs_pin, 1) 114 | 115 | def send_data(self, data): 116 | epdconfig.digital_write(self.dc_pin, 1) 117 | epdconfig.digital_write(self.cs_pin, 0) 118 | epdconfig.spi_writebyte([data]) 119 | epdconfig.digital_write(self.cs_pin, 1) 120 | 121 | def ReadBusy(self): 122 | logging.debug("e-Paper busy") 123 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 124 | epdconfig.delay_ms(100) 125 | logging.debug("e-Paper busy release") 126 | 127 | def set_lut(self): 128 | self.send_command(0x20) # vcom 129 | for count in range(0, 44): 130 | self.send_data(self.lut_vcom_dc[count]) 131 | self.send_command(0x21) # ww -- 132 | for count in range(0, 42): 133 | self.send_data(self.lut_ww[count]) 134 | self.send_command(0x22) # bw r 135 | for count in range(0, 42): 136 | self.send_data(self.lut_bw[count]) 137 | self.send_command(0x23) # wb w 138 | for count in range(0, 42): 139 | self.send_data(self.lut_bb[count]) 140 | self.send_command(0x24) # bb b 141 | for count in range(0, 42): 142 | self.send_data(self.lut_wb[count]) 143 | 144 | def init(self): 145 | if (epdconfig.module_init() != 0): 146 | return -1 147 | 148 | self.reset() 149 | 150 | self.send_command(0x04) # POWER_ON 151 | self.ReadBusy() 152 | 153 | self.send_command(0x00) # PANEL_SETTING 154 | self.send_data(0xaf) #KW-BF KWR-AF BWROTP 0f 155 | 156 | self.send_command(0x30) # PLL_CONTROL 157 | self.send_data(0x3a) #3A 100HZ 29 150Hz 39 200HZ 31 171HZ 158 | 159 | self.send_command(0x01) # POWER_SETTING 160 | self.send_data(0x03) # VDS_EN, VDG_EN 161 | self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0] 162 | self.send_data(0x2b) # VDH 163 | self.send_data(0x2b) # VDL 164 | self.send_data(0x09) # VDHR 165 | 166 | self.send_command(0x06) # BOOSTER_SOFT_START 167 | self.send_data(0x07) 168 | self.send_data(0x07) 169 | self.send_data(0x17) 170 | 171 | # Power optimization 172 | self.send_command(0xF8) 173 | self.send_data(0x60) 174 | self.send_data(0xA5) 175 | 176 | # Power optimization 177 | self.send_command(0xF8) 178 | self.send_data(0x89) 179 | self.send_data(0xA5) 180 | 181 | # Power optimization 182 | self.send_command(0xF8) 183 | self.send_data(0x90) 184 | self.send_data(0x00) 185 | 186 | # Power optimization 187 | self.send_command(0xF8) 188 | self.send_data(0x93) 189 | self.send_data(0x2A) 190 | 191 | # Power optimization 192 | self.send_command(0xF8) 193 | self.send_data(0x73) 194 | self.send_data(0x41) 195 | 196 | self.send_command(0x82) # VCM_DC_SETTING_REGISTER 197 | self.send_data(0x12) 198 | self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING 199 | self.send_data(0x87) # define by OTP 200 | 201 | self.set_lut() 202 | 203 | self.send_command(0x16) # PARTIAL_DISPLAY_REFRESH 204 | self.send_data(0x00) 205 | 206 | return 0 207 | 208 | def getbuffer(self, image): 209 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 210 | buf = [0xFF] * (int(self.width/8) * self.height) 211 | image_monocolor = image.convert('1') 212 | imwidth, imheight = image_monocolor.size 213 | pixels = image_monocolor.load() 214 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 215 | if(imwidth == self.width and imheight == self.height): 216 | logging.debug("Vertical") 217 | for y in range(imheight): 218 | for x in range(imwidth): 219 | # Set the bits for the column of pixels at the current position. 220 | if pixels[x, y] == 0: 221 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 222 | elif(imwidth == self.height and imheight == self.width): 223 | logging.debug("Horizontal") 224 | for y in range(imheight): 225 | for x in range(imwidth): 226 | newx = y 227 | newy = self.height - x - 1 228 | if pixels[x, y] == 0: 229 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 230 | return buf 231 | 232 | def display(self, imageblack, imagered): 233 | self.send_command(0x10) 234 | for i in range(0, int(self.width * self.height / 8)): 235 | self.send_data(~imageblack[i]) 236 | self.send_command(0x11) 237 | 238 | self.send_command(0x13) 239 | for i in range(0, int(self.width * self.height / 8)): 240 | self.send_data(~imagered[i]) 241 | self.send_command(0x11) 242 | 243 | self.send_command(0x12) 244 | self.ReadBusy() 245 | 246 | def Clear(self): 247 | self.send_command(0x10) 248 | for i in range(0, int(self.width * self.height / 8)): 249 | self.send_data(0x00) 250 | self.send_command(0x11) 251 | 252 | self.send_command(0x13) 253 | for i in range(0, int(self.width * self.height / 8)): 254 | self.send_data(0x00) 255 | self.send_command(0x11) 256 | 257 | self.send_command(0x12) 258 | self.ReadBusy() 259 | 260 | def sleep(self): 261 | self.send_command(0X50) 262 | self.send_data(0xf7) 263 | self.send_command(0X02) 264 | self.send_command(0X07) 265 | self.send_data(0xA5) 266 | 267 | epdconfig.module_exit() 268 | ### END OF FILE ### 269 | 270 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in9.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in9.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 128 35 | EPD_HEIGHT = 296 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | lut_full_update = [ 47 | 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 52 | ] 53 | 54 | lut_partial_update = [ 55 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 56 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 60 | ] 61 | 62 | # Hardware reset 63 | def reset(self): 64 | epdconfig.digital_write(self.reset_pin, 1) 65 | epdconfig.delay_ms(200) 66 | epdconfig.digital_write(self.reset_pin, 0) 67 | epdconfig.delay_ms(10) 68 | epdconfig.digital_write(self.reset_pin, 1) 69 | epdconfig.delay_ms(200) 70 | 71 | def send_command(self, command): 72 | epdconfig.digital_write(self.dc_pin, 0) 73 | epdconfig.digital_write(self.cs_pin, 0) 74 | epdconfig.spi_writebyte([command]) 75 | epdconfig.digital_write(self.cs_pin, 1) 76 | 77 | def send_data(self, data): 78 | epdconfig.digital_write(self.dc_pin, 1) 79 | epdconfig.digital_write(self.cs_pin, 0) 80 | epdconfig.spi_writebyte([data]) 81 | epdconfig.digital_write(self.cs_pin, 1) 82 | 83 | def ReadBusy(self): 84 | while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy 85 | epdconfig.delay_ms(200) 86 | 87 | def TurnOnDisplay(self): 88 | self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 89 | self.send_data(0xC4) 90 | self.send_command(0x20) # MASTER_ACTIVATION 91 | self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE 92 | 93 | logging.debug("e-Paper busy") 94 | self.ReadBusy() 95 | logging.debug("e-Paper busy release") 96 | 97 | def SetWindow(self, x_start, y_start, x_end, y_end): 98 | self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION 99 | # x point must be the multiple of 8 or the last 3 bits will be ignored 100 | self.send_data((x_start >> 3) & 0xFF) 101 | self.send_data((x_end >> 3) & 0xFF) 102 | self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION 103 | self.send_data(y_start & 0xFF) 104 | self.send_data((y_start >> 8) & 0xFF) 105 | self.send_data(y_end & 0xFF) 106 | self.send_data((y_end >> 8) & 0xFF) 107 | 108 | def SetCursor(self, x, y): 109 | self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER 110 | # x point must be the multiple of 8 or the last 3 bits will be ignored 111 | self.send_data((x >> 3) & 0xFF) 112 | self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER 113 | self.send_data(y & 0xFF) 114 | self.send_data((y >> 8) & 0xFF) 115 | self.ReadBusy() 116 | 117 | def init(self, lut): 118 | if (epdconfig.module_init() != 0): 119 | return -1 120 | # EPD hardware init start 121 | self.reset() 122 | 123 | self.send_command(0x01) # DRIVER_OUTPUT_CONTROL 124 | self.send_data((EPD_HEIGHT - 1) & 0xFF) 125 | self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) 126 | self.send_data(0x00) # GD = 0 SM = 0 TB = 0 127 | 128 | self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL 129 | self.send_data(0xD7) 130 | self.send_data(0xD6) 131 | self.send_data(0x9D) 132 | 133 | self.send_command(0x2C) # WRITE_VCOM_REGISTER 134 | self.send_data(0xA8) # VCOM 7C 135 | 136 | self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD 137 | self.send_data(0x1A) # 4 dummy lines per gate 138 | 139 | self.send_command(0x3B) # SET_GATE_TIME 140 | self.send_data(0x08) # 2us per line 141 | 142 | self.send_command(0x11) # DATA_ENTRY_MODE_SETTING 143 | self.send_data(0x03) # X increment Y increment 144 | 145 | self.send_command(0x32) # WRITE_LUT_REGISTER 146 | for i in range(0, len(lut)): 147 | self.send_data(lut[i]) 148 | # EPD hardware init end 149 | return 0 150 | 151 | def getbuffer(self, image): 152 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 153 | buf = [0xFF] * (int(self.width/8) * self.height) 154 | image_monocolor = image.convert('1') 155 | imwidth, imheight = image_monocolor.size 156 | pixels = image_monocolor.load() 157 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 158 | if(imwidth == self.width and imheight == self.height): 159 | logging.debug("Vertical") 160 | for y in range(imheight): 161 | for x in range(imwidth): 162 | # Set the bits for the column of pixels at the current position. 163 | if pixels[x, y] == 0: 164 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 165 | elif(imwidth == self.height and imheight == self.width): 166 | logging.debug("Horizontal") 167 | for y in range(imheight): 168 | for x in range(imwidth): 169 | newx = y 170 | newy = self.height - x - 1 171 | if pixels[x, y] == 0: 172 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 173 | return buf 174 | 175 | def display(self, image): 176 | if (image == None): 177 | return 178 | self.SetWindow(0, 0, self.width - 1, self.height - 1) 179 | for j in range(0, self.height): 180 | self.SetCursor(0, j) 181 | self.send_command(0x24) # WRITE_RAM 182 | for i in range(0, int(self.width / 8)): 183 | self.send_data(image[i + j * int(self.width / 8)]) 184 | self.TurnOnDisplay() 185 | 186 | def Clear(self, color): 187 | self.SetWindow(0, 0, self.width - 1, self.height - 1) 188 | for j in range(0, self.height): 189 | self.SetCursor(0, j) 190 | self.send_command(0x24) # WRITE_RAM 191 | for i in range(0, int(self.width / 8)): 192 | self.send_data(color) 193 | self.TurnOnDisplay() 194 | 195 | def sleep(self): 196 | self.send_command(0x10) # DEEP_SLEEP_MODE 197 | self.send_data(0x01) 198 | 199 | epdconfig.module_exit() 200 | ### END OF FILE ### 201 | 202 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in9b_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in9bc.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 128 36 | EPD_HEIGHT = 296 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | self.send_command(0X71) 71 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 72 | self.send_command(0X71) 73 | epdconfig.delay_ms(200) 74 | logging.debug("e-Paper busy release") 75 | 76 | def init(self): 77 | if (epdconfig.module_init() != 0): 78 | return -1 79 | # EPD hardware init start 80 | self.reset() 81 | 82 | self.send_command(0x04) 83 | self.ReadBusy()#waiting for the electronic paper IC to release the idle signal 84 | 85 | self.send_command(0x00) #panel setting 86 | self.send_data(0x0f) #LUT from OTP,128x296 87 | self.send_data(0x89) #Temperature sensor, boost and other related timing settings 88 | 89 | self.send_command(0x61) #resolution setting 90 | self.send_data (0x80) 91 | self.send_data (0x01) 92 | self.send_data (0x28) 93 | 94 | self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING 95 | self.send_data(0x77) #WBmode:VBDF 17|D7 VBDW 97 VBDB 57 96 | # WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7 97 | 98 | return 0 99 | 100 | def getbuffer(self, image): 101 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 102 | buf = [0xFF] * (int(self.width/8) * self.height) 103 | image_monocolor = image.convert('1') 104 | imwidth, imheight = image_monocolor.size 105 | pixels = image_monocolor.load() 106 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 107 | if(imwidth == self.width and imheight == self.height): 108 | logging.debug("Vertical") 109 | for y in range(imheight): 110 | for x in range(imwidth): 111 | # Set the bits for the column of pixels at the current position. 112 | if pixels[x, y] == 0: 113 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 114 | elif(imwidth == self.height and imheight == self.width): 115 | logging.debug("Horizontal") 116 | for y in range(imheight): 117 | for x in range(imwidth): 118 | newx = y 119 | newy = self.height - x - 1 120 | if pixels[x, y] == 0: 121 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 122 | return buf 123 | 124 | def display(self, blackimage, ryimage): # ryimage: red or yellow image 125 | if (blackimage != None): 126 | self.send_command(0X10) 127 | for i in range(0, int(self.width * self.height / 8)): 128 | self.send_data(blackimage[i]) 129 | if (ryimage != None): 130 | self.send_command(0X13) 131 | for i in range(0, int(self.width * self.height / 8)): 132 | self.send_data(ryimage[i]) 133 | 134 | self.send_command(0x12) 135 | epdconfig.delay_ms(200) 136 | self.ReadBusy() 137 | 138 | def Clear(self): 139 | self.send_command(0X10) 140 | for i in range(0, int(self.width * self.height / 8)): 141 | self.send_data(0xff) 142 | self.send_command(0X13) 143 | for i in range(0, int(self.width * self.height / 8)): 144 | self.send_data(0xff) 145 | 146 | self.send_command(0x12) 147 | epdconfig.delay_ms(200) 148 | self.ReadBusy() 149 | 150 | def sleep(self): 151 | self.send_command(0X02) # power off 152 | self.ReadBusy() 153 | self.send_command(0X07) # deep sleep 154 | self.send_data(0xA5) 155 | 156 | epdconfig.module_exit() 157 | ### END OF FILE ### 158 | 159 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd2in9bc.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd2in9bc.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 128 36 | EPD_HEIGHT = 296 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 71 | epdconfig.delay_ms(200) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | # EPD hardware init start 78 | self.reset() 79 | 80 | self.send_command(0x06) # boost 81 | self.send_data (0x17) 82 | self.send_data (0x17) 83 | self.send_data (0x17) 84 | self.send_command(0x04) # POWER_ON 85 | self.ReadBusy() 86 | self.send_command(0X00) # PANEL_SETTING 87 | self.send_data(0x8F) 88 | self.send_command(0X50) # VCOM_AND_DATA_INTERVAL_SETTING 89 | self.send_data(0x77) 90 | self.send_command(0x61) # TCON_RESOLUTION 91 | self.send_data (0x80) 92 | self.send_data (0x01) 93 | self.send_data (0x28) 94 | # self.send_command(VCM_DC_SETTING_REGISTER) 95 | # self.send_data (0x0A) 96 | 97 | return 0 98 | 99 | def getbuffer(self, image): 100 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 101 | buf = [0xFF] * (int(self.width/8) * self.height) 102 | image_monocolor = image.convert('1') 103 | imwidth, imheight = image_monocolor.size 104 | pixels = image_monocolor.load() 105 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 106 | if(imwidth == self.width and imheight == self.height): 107 | logging.debug("Vertical") 108 | for y in range(imheight): 109 | for x in range(imwidth): 110 | # Set the bits for the column of pixels at the current position. 111 | if pixels[x, y] == 0: 112 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 113 | elif(imwidth == self.height and imheight == self.width): 114 | logging.debug("Horizontal") 115 | for y in range(imheight): 116 | for x in range(imwidth): 117 | newx = y 118 | newy = self.height - x - 1 119 | if pixels[x, y] == 0: 120 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 121 | return buf 122 | 123 | def display(self, blackimage, ryimage): # ryimage: red or yellow image 124 | if (blackimage != None): 125 | self.send_command(0X10) 126 | for i in range(0, int(self.width * self.height / 8)): 127 | self.send_data(blackimage[i]) 128 | if (ryimage != None): 129 | self.send_command(0X13) 130 | for i in range(0, int(self.width * self.height / 8)): 131 | self.send_data(ryimage[i]) 132 | 133 | self.send_command(0x12) 134 | self.ReadBusy() 135 | 136 | def Clear(self): 137 | self.send_command(0X10) 138 | for i in range(0, int(self.width * self.height / 8)): 139 | self.send_data(0xff) 140 | self.send_command(0X13) 141 | for i in range(0, int(self.width * self.height / 8)): 142 | self.send_data(0xff) 143 | 144 | self.send_command(0x12) 145 | self.ReadBusy() 146 | 147 | def sleep(self): 148 | self.send_command(0X02) # power off 149 | self.ReadBusy() 150 | self.send_command(0X07) # deep sleep 151 | self.send_data(0xA5) 152 | 153 | epdconfig.module_exit() 154 | ### END OF FILE ### 155 | 156 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd4in2bc.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd4in2bc.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 | 30 | import logging 31 | from . import epdconfig 32 | 33 | # Display resolution 34 | EPD_WIDTH = 400 35 | EPD_HEIGHT = 300 36 | 37 | class EPD: 38 | def __init__(self): 39 | self.reset_pin = epdconfig.RST_PIN 40 | self.dc_pin = epdconfig.DC_PIN 41 | self.busy_pin = epdconfig.BUSY_PIN 42 | self.cs_pin = epdconfig.CS_PIN 43 | self.width = EPD_WIDTH 44 | self.height = EPD_HEIGHT 45 | 46 | # Hardware reset 47 | def reset(self): 48 | epdconfig.digital_write(self.reset_pin, 1) 49 | epdconfig.delay_ms(200) 50 | epdconfig.digital_write(self.reset_pin, 0) 51 | epdconfig.delay_ms(10) 52 | epdconfig.digital_write(self.reset_pin, 1) 53 | epdconfig.delay_ms(200) 54 | 55 | def send_command(self, command): 56 | epdconfig.digital_write(self.dc_pin, 0) 57 | epdconfig.digital_write(self.cs_pin, 0) 58 | epdconfig.spi_writebyte([command]) 59 | epdconfig.digital_write(self.cs_pin, 1) 60 | 61 | def send_data(self, data): 62 | epdconfig.digital_write(self.dc_pin, 1) 63 | epdconfig.digital_write(self.cs_pin, 0) 64 | epdconfig.spi_writebyte([data]) 65 | epdconfig.digital_write(self.cs_pin, 1) 66 | 67 | def ReadBusy(self): 68 | logging.debug("e-Paper busy") 69 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 70 | epdconfig.delay_ms(100) 71 | logging.debug("e-Paper busy release") 72 | 73 | def init(self): 74 | if (epdconfig.module_init() != 0): 75 | return -1 76 | 77 | self.reset() 78 | 79 | self.send_command(0x06) # BOOSTER_SOFT_START 80 | self.send_data (0x17) 81 | self.send_data (0x17) 82 | self.send_data (0x17) # 07 0f 17 1f 27 2F 37 2f 83 | 84 | self.send_command(0x04) # POWER_ON 85 | self.ReadBusy() 86 | 87 | self.send_command(0x00) # PANEL_SETTING 88 | self.send_data(0x0F) # LUT from OTP 89 | 90 | return 0 91 | 92 | def getbuffer(self, image): 93 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 94 | buf = [0xFF] * (int(self.width/8) * self.height) 95 | image_monocolor = image.convert('1') 96 | imwidth, imheight = image_monocolor.size 97 | pixels = image_monocolor.load() 98 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 99 | if(imwidth == self.width and imheight == self.height): 100 | logging.debug("Horizontal") 101 | for y in range(imheight): 102 | for x in range(imwidth): 103 | # Set the bits for the column of pixels at the current position. 104 | if pixels[x, y] == 0: 105 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 106 | elif(imwidth == self.height and imheight == self.width): 107 | logging.debug("Vertical") 108 | for y in range(imheight): 109 | for x in range(imwidth): 110 | newx = y 111 | newy = self.height - x - 1 112 | if pixels[x, y] == 0: 113 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 114 | return buf 115 | 116 | def display(self, imageblack, imagered): 117 | self.send_command(0x10) 118 | for i in range(0, int(self.width * self.height / 8)): 119 | self.send_data(imageblack[i]) 120 | 121 | self.send_command(0x13) 122 | for i in range(0, int(self.width * self.height / 8)): 123 | self.send_data(imagered[i]) 124 | 125 | self.send_command(0x12) 126 | self.ReadBusy() 127 | 128 | def Clear(self): 129 | self.send_command(0x10) 130 | for i in range(0, int(self.width * self.height / 8)): 131 | self.send_data(0xFF) 132 | 133 | self.send_command(0x13) 134 | for i in range(0, int(self.width * self.height / 8)): 135 | self.send_data(0xFF) 136 | 137 | self.send_command(0x12) 138 | self.ReadBusy() 139 | 140 | def sleep(self): 141 | self.send_command(0x02) # POWER_OFF 142 | self.ReadBusy() 143 | self.send_command(0x07) # DEEP_SLEEP 144 | self.send_data(0xA5) # check code 145 | 146 | epdconfig.module_exit() 147 | ### END OF FILE ### 148 | 149 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd5in65f.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding:utf-8 -*- 3 | # ***************************************************************************** 4 | # * | File : epd5in65f.py 5 | # * | Author : Waveshare team 6 | # * | Function : Electronic paper driver 7 | # * | Info : 8 | # *---------------- 9 | # * | This version: V1.0 10 | # * | Date : 2020-03-02 11 | # # | Info : python demo 12 | # ----------------------------------------------------------------------------- 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documnetation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # 31 | 32 | import logging 33 | from . import epdconfig 34 | 35 | # Display resolution 36 | EPD_WIDTH = 600 37 | EPD_HEIGHT = 448 38 | 39 | class EPD: 40 | def __init__(self): 41 | self.reset_pin = epdconfig.RST_PIN 42 | self.dc_pin = epdconfig.DC_PIN 43 | self.busy_pin = epdconfig.BUSY_PIN 44 | self.cs_pin = epdconfig.CS_PIN 45 | self.width = EPD_WIDTH 46 | self.height = EPD_HEIGHT 47 | self.BLACK = 0x000000 # 0000 BGR 48 | self.WHITE = 0xffffff # 0001 49 | self.GREEN = 0x00ff00 # 0010 50 | self.BLUE = 0xff0000 # 0011 51 | self.RED = 0x0000ff # 0100 52 | self.YELLOW = 0x00ffff # 0101 53 | self.ORANGE = 0x0080ff # 0110 54 | 55 | 56 | # Hardware reset 57 | def reset(self): 58 | epdconfig.digital_write(self.reset_pin, 1) 59 | epdconfig.delay_ms(600) 60 | epdconfig.digital_write(self.reset_pin, 0) 61 | epdconfig.delay_ms(2) 62 | epdconfig.digital_write(self.reset_pin, 1) 63 | epdconfig.delay_ms(200) 64 | 65 | def send_command(self, command): 66 | epdconfig.digital_write(self.dc_pin, 0) 67 | epdconfig.digital_write(self.cs_pin, 0) 68 | epdconfig.spi_writebyte([command]) 69 | epdconfig.digital_write(self.cs_pin, 1) 70 | 71 | def send_data(self, data): 72 | epdconfig.digital_write(self.dc_pin, 1) 73 | epdconfig.digital_write(self.cs_pin, 0) 74 | epdconfig.spi_writebyte([data]) 75 | epdconfig.digital_write(self.cs_pin, 1) 76 | 77 | def ReadBusyHigh(self): 78 | logging.debug("e-Paper busy") 79 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 80 | epdconfig.delay_ms(100) 81 | logging.debug("e-Paper busy release") 82 | 83 | def ReadBusyLow(self): 84 | logging.debug("e-Paper busy") 85 | while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy 86 | epdconfig.delay_ms(100) 87 | logging.debug("e-Paper busy release") 88 | 89 | def init(self): 90 | if (epdconfig.module_init() != 0): 91 | return -1 92 | # EPD hardware init start 93 | self.reset() 94 | 95 | self.ReadBusyHigh() 96 | self.send_command(0x00) 97 | self.send_data(0xEF) 98 | self.send_data(0x08) 99 | self.send_command(0x01) 100 | self.send_data(0x37) 101 | self.send_data(0x00) 102 | self.send_data(0x23) 103 | self.send_data(0x23) 104 | self.send_command(0x03) 105 | self.send_data(0x00) 106 | self.send_command(0x06) 107 | self.send_data(0xC7) 108 | self.send_data(0xC7) 109 | self.send_data(0x1D) 110 | self.send_command(0x30) 111 | self.send_data(0x3C) 112 | self.send_command(0x40) 113 | self.send_data(0x00) 114 | self.send_command(0x50) 115 | self.send_data(0x37) 116 | self.send_command(0x60) 117 | self.send_data(0x22) 118 | self.send_command(0x61) 119 | self.send_data(0x02) 120 | self.send_data(0x58) 121 | self.send_data(0x01) 122 | self.send_data(0xC0) 123 | self.send_command(0xE3) 124 | self.send_data(0xAA) 125 | 126 | epdconfig.delay_ms(100) 127 | self.send_command(0x50) 128 | self.send_data(0x37) 129 | 130 | # EPD hardware init end 131 | return 0 132 | 133 | def getbuffer(self, image): 134 | buf = [0x00] * int(self.width * self.height / 2) 135 | image_monocolor = image.convert('RGB')#Picture mode conversion 136 | imwidth, imheight = image_monocolor.size 137 | pixels = image_monocolor.load() 138 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 139 | if(imwidth == self.width and imheight == self.height): 140 | for y in range(imheight): 141 | for x in range(imwidth): 142 | # Set the bits for the column of pixels at the current position. 143 | Add = int((x + y * self.width) / 2) 144 | Color = 0; 145 | if (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0): 146 | Color = 0 147 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 255): 148 | Color = 1 149 | elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0): 150 | Color = 2 151 | elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 255): 152 | Color = 3 153 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0): 154 | Color = 4 155 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0): 156 | Color = 5 157 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 128 and pixels[x, y][2] == 0): 158 | Color = 6 159 | 160 | data_t = buf[Add]&(~(0xF0 >> ((x % 2)*4))) 161 | buf[Add] = data_t | ((Color << 4) >> ((x % 2)*4)); 162 | 163 | elif(imwidth == self.height and imheight == self.width): 164 | for y in range(imheight): 165 | for x in range(imwidth): 166 | newx = y 167 | newy = self.height - x - 1 168 | Add = int((newx + newy*self.width) / 2) 169 | Color = 0; 170 | if (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0): 171 | Color = 0 172 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 255): 173 | Color = 1 174 | elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0): 175 | Color = 2 176 | elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 255): 177 | Color = 3 178 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0): 179 | Color = 4 180 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0): 181 | Color = 5 182 | elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 128 and pixels[x, y][2] == 0): 183 | Color = 6 184 | 185 | data_t = buf[Add]&(~(0xF0 >> ((newx % 2)*4))) 186 | buf[Add] = data_t | ((Color << 4) >> ((newx % 2)*4)); 187 | return buf 188 | 189 | def display(self,image): 190 | self.send_command(0x61)#Set Resolution setting 191 | self.send_data(0x02) 192 | self.send_data(0x58) 193 | self.send_data(0x01) 194 | self.send_data(0xC0) 195 | self.send_command(0x10) 196 | for i in range(0, int(EPD_HEIGHT)): 197 | for j in range(0, int(EPD_WIDTH/2)): 198 | self.send_data((image[j+(int(EPD_WIDTH/2)*i)])) 199 | self.send_command(0x04)#0x04 200 | self.ReadBusyHigh() 201 | self.send_command(0x12)#0x12 202 | self.ReadBusyHigh() 203 | self.send_command(0x02) #0x02 204 | self.ReadBusyLow() 205 | epdconfig.delay_ms(500) 206 | 207 | def Clear(self): 208 | self.send_command(0x61)#Set Resolution setting 209 | self.send_data(0x02) 210 | self.send_data(0x58) 211 | self.send_data(0x01) 212 | self.send_data(0xC0) 213 | self.send_command(0x10) 214 | for i in range(0, int(EPD_HEIGHT)): 215 | for j in range(0, int(EPD_WIDTH/2)): 216 | self.send_data(0x11) 217 | #BLACK 0x00 /// 0000 218 | #WHITE 0x11 /// 0001 219 | #GREEN 0x22 /// 0010 220 | #BLUE 0x33 /// 0011 221 | #RED 0x44 /// 0100 222 | #YELLOW 0x55 /// 0101 223 | #ORANGE 0x66 /// 0110 224 | #CLEAN 0x77 /// 0111 unavailable Afterimage 225 | self.send_command(0x04)#0x04 226 | self.ReadBusyHigh() 227 | self.send_command(0x12)#0x12 228 | self.ReadBusyHigh() 229 | self.send_command(0x02) #0x02 230 | self.ReadBusyLow() 231 | epdconfig.delay_ms(500) 232 | 233 | def sleep(self): 234 | epdconfig.delay_ms(500) 235 | self.send_command(0x07) # DEEP_SLEEP 236 | self.send_data(0XA5) 237 | epdconfig.digital_write(self.reset_pin, 0) 238 | epdconfig.module_exit() 239 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd5in83.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd5in83.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 600 36 | EPD_HEIGHT = 448 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 71 | epdconfig.delay_ms(100) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | # EPD hardware init start 78 | self.reset() 79 | 80 | self.send_command(0x01) # POWER_SETTING 81 | self.send_data(0x37) 82 | self.send_data(0x00) 83 | 84 | self.send_command(0x00) # PANEL_SETTING 85 | self.send_data(0xCF) 86 | self.send_data(0x08) 87 | 88 | self.send_command(0x06) # BOOSTER_SOFT_START 89 | self.send_data(0xc7) 90 | self.send_data(0xcc) 91 | self.send_data(0x28) 92 | 93 | self.send_command(0x04) # POWER_ON 94 | self.ReadBusy() 95 | 96 | self.send_command(0x30) # PLL_CONTROL 97 | self.send_data(0x3c) 98 | 99 | self.send_command(0x41) # TEMPERATURE_CALIBRATION 100 | self.send_data(0x00) 101 | 102 | self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING 103 | self.send_data(0x77) 104 | 105 | self.send_command(0x60) # TCON_SETTING 106 | self.send_data(0x22) 107 | 108 | self.send_command(0x61) # TCON_RESOLUTION 109 | self.send_data(0x02) # source 600 110 | self.send_data(0x58) 111 | self.send_data(0x01) # gate 448 112 | self.send_data(0xC0) 113 | 114 | self.send_command(0x82) # VCM_DC_SETTING 115 | self.send_data(0x1E) # decide by LUT file 116 | 117 | self.send_command(0xe5) # FLASH MODE 118 | self.send_data(0x03) 119 | 120 | # EPD hardware init end 121 | return 0 122 | 123 | def getbuffer(self, image): 124 | buf = [0x00] * int(self.width * self.height / 4) 125 | image_monocolor = image.convert('1') 126 | imwidth, imheight = image_monocolor.size 127 | pixels = image_monocolor.load() 128 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 129 | if(imwidth == self.width and imheight == self.height): 130 | for y in range(imheight): 131 | for x in range(imwidth): 132 | # Set the bits for the column of pixels at the current position. 133 | if pixels[x, y] < 64: # black 134 | buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2)) 135 | elif pixels[x, y] < 192: # convert gray to red 136 | buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2)) 137 | buf[int((x + y * self.width) / 4)] |= 0x40 >> (x % 4 * 2) 138 | else: # white 139 | buf[int((x + y * self.width) / 4)] |= 0xC0 >> (x % 4 * 2) 140 | elif(imwidth == self.height and imheight == self.width): 141 | for y in range(imheight): 142 | for x in range(imwidth): 143 | newx = y 144 | newy = self.height - x - 1 145 | if pixels[x, y] < 64: # black 146 | buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2)) 147 | elif pixels[x, y] < 192: # convert gray to red 148 | buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2)) 149 | buf[int((newx + newy*self.width) / 4)] |= 0x40 >> (y % 4 * 2) 150 | else: # white 151 | buf[int((newx + newy*self.width) / 4)] |= 0xC0 >> (y % 4 * 2) 152 | return buf 153 | 154 | def display(self, image): 155 | self.send_command(0x10) 156 | for i in range(0, int(self.width / 4 * self.height)): 157 | temp1 = image[i] 158 | j = 0 159 | while (j < 4): 160 | if ((temp1 & 0xC0) == 0xC0): 161 | temp2 = 0x03 162 | elif ((temp1 & 0xC0) == 0x00): 163 | temp2 = 0x00 164 | else: 165 | temp2 = 0x04 166 | temp2 = (temp2 << 4) & 0xFF 167 | temp1 = (temp1 << 2) & 0xFF 168 | j += 1 169 | if((temp1 & 0xC0) == 0xC0): 170 | temp2 |= 0x03 171 | elif ((temp1 & 0xC0) == 0x00): 172 | temp2 |= 0x00 173 | else: 174 | temp2 |= 0x04 175 | temp1 = (temp1 << 2) & 0xFF 176 | self.send_data(temp2) 177 | j += 1 178 | 179 | self.send_command(0x12) 180 | epdconfig.delay_ms(100) 181 | self.ReadBusy() 182 | 183 | def Clear(self): 184 | self.send_command(0x10) 185 | for i in range(0, int(self.width / 4 * self.height)): 186 | for j in range(0, 4): 187 | self.send_data(0x33) 188 | self.send_command(0x12) 189 | self.ReadBusy() 190 | 191 | def sleep(self): 192 | self.send_command(0x02) # POWER_OFF 193 | self.ReadBusy() 194 | self.send_command(0x07) # DEEP_SLEEP 195 | self.send_data(0XA5) 196 | 197 | epdconfig.module_exit() 198 | 199 | ### END OF FILE ### 200 | 201 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd5in83bc.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd5in83b.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 600 36 | EPD_HEIGHT = 448 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 71 | epdconfig.delay_ms(100) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | 78 | self.reset() 79 | 80 | self.send_command(0x01) # POWER_SETTING 81 | self.send_data(0x37) 82 | self.send_data(0x00) 83 | 84 | self.send_command(0x00) # PANEL_SETTING 85 | self.send_data(0xCF) 86 | self.send_data(0x08) 87 | 88 | self.send_command(0x30) # PLL_CONTROL 89 | self.send_data(0x3A) # PLL: 0-15:0x3C, 15+:0x3A 90 | self.send_command(0X82) # VCOM VOLTAGE SETTING 91 | self.send_data(0x28) # all temperature range 92 | 93 | self.send_command(0x06) # boost 94 | self.send_data(0xc7) 95 | self.send_data(0xcc) 96 | self.send_data(0x15) 97 | 98 | self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING 99 | self.send_data(0x77) 100 | 101 | self.send_command(0X60) # TCON SETTING 102 | self.send_data(0x22) 103 | 104 | self.send_command(0X65) # FLASH CONTROL 105 | self.send_data(0x00) 106 | 107 | self.send_command(0x61) # tres 108 | self.send_data(0x02) # source 600 109 | self.send_data(0x58) 110 | self.send_data(0x01) # gate 448 111 | self.send_data(0xc0) 112 | 113 | self.send_command(0xe5) # FLASH MODE 114 | self.send_data(0x03) 115 | self.send_data(0x03) 116 | 117 | return 0 118 | 119 | def getbuffer(self, image): 120 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 121 | buf = [0xFF] * (int(self.width/8) * self.height) 122 | image_monocolor = image.convert('1') 123 | imwidth, imheight = image_monocolor.size 124 | pixels = image_monocolor.load() 125 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 126 | if(imwidth == self.width and imheight == self.height): 127 | logging.debug("Horizontal") 128 | for y in range(imheight): 129 | for x in range(imwidth): 130 | # Set the bits for the column of pixels at the current position. 131 | if pixels[x, y] == 0: 132 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 133 | elif(imwidth == self.height and imheight == self.width): 134 | logging.debug("Vertical") 135 | for y in range(imheight): 136 | for x in range(imwidth): 137 | newx = y 138 | newy = self.height - x - 1 139 | if pixels[x, y] == 0: 140 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 141 | return buf 142 | 143 | def display(self, imageblack, imagered): 144 | self.send_command(0x10) 145 | for i in range(0, int(self.width / 8 * self.height)): 146 | temp1 = imageblack[i] 147 | temp2 = imagered[i] 148 | j = 0 149 | while (j < 8): 150 | if ((temp2 & 0x80) == 0x00): 151 | temp3 = 0x04 #red 152 | elif ((temp1 & 0x80) == 0x00): 153 | temp3 = 0x00 #black 154 | else: 155 | temp3 = 0x03 #white 156 | 157 | temp3 = (temp3 << 4) & 0xFF 158 | temp1 = (temp1 << 1) & 0xFF 159 | temp2 = (temp2 << 1) & 0xFF 160 | j += 1 161 | if((temp2 & 0x80) == 0x00): 162 | temp3 |= 0x04 #red 163 | elif ((temp1 & 0x80) == 0x00): 164 | temp3 |= 0x00 #black 165 | else: 166 | temp3 |= 0x03 #white 167 | temp1 = (temp1 << 1) & 0xFF 168 | temp2 = (temp2 << 1) & 0xFF 169 | self.send_data(temp3) 170 | j += 1 171 | 172 | self.send_command(0x04) # POWER ON 173 | self.ReadBusy() 174 | self.send_command(0x12) # display refresh 175 | epdconfig.delay_ms(100) 176 | self.ReadBusy() 177 | 178 | def Clear(self): 179 | self.send_command(0x10) 180 | for i in range(0, int(self.width / 8 * self.height)): 181 | self.send_data(0x33) 182 | self.send_data(0x33) 183 | self.send_data(0x33) 184 | self.send_data(0x33) 185 | 186 | self.send_command(0x04) # POWER ON 187 | self.ReadBusy() 188 | self.send_command(0x12) # display refresh 189 | epdconfig.delay_ms(100) 190 | self.ReadBusy() 191 | 192 | def sleep(self): 193 | self.send_command(0x02) # POWER_OFF 194 | self.ReadBusy() 195 | self.send_command(0x07) # DEEP_SLEEP 196 | self.send_data(0xA5) # check code 197 | 198 | epdconfig.module_exit() 199 | ### END OF FILE ### 200 | 201 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 640 36 | EPD_HEIGHT = 384 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 71 | epdconfig.delay_ms(100) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | # EPD hardware init start 78 | self.reset() 79 | 80 | self.send_command(0x01) # POWER_SETTING 81 | self.send_data(0x37) 82 | self.send_data(0x00) 83 | 84 | self.send_command(0x00) # PANEL_SETTING 85 | self.send_data(0xCF) 86 | self.send_data(0x08) 87 | 88 | self.send_command(0x06) # BOOSTER_SOFT_START 89 | self.send_data(0xc7) 90 | self.send_data(0xcc) 91 | self.send_data(0x28) 92 | 93 | self.send_command(0x04) # POWER_ON 94 | self.ReadBusy() 95 | 96 | self.send_command(0x30) # PLL_CONTROL 97 | self.send_data(0x3c) 98 | 99 | self.send_command(0x41) # TEMPERATURE_CALIBRATION 100 | self.send_data(0x00) 101 | 102 | self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING 103 | self.send_data(0x77) 104 | 105 | self.send_command(0x60) # TCON_SETTING 106 | self.send_data(0x22) 107 | 108 | self.send_command(0x61) # TCON_RESOLUTION 109 | self.send_data(EPD_WIDTH >> 8) #source 640 110 | self.send_data(EPD_WIDTH & 0xff) 111 | self.send_data(EPD_HEIGHT >> 8) #gate 384 112 | self.send_data(EPD_HEIGHT & 0xff) 113 | 114 | self.send_command(0x82) # VCM_DC_SETTING 115 | self.send_data(0x1E) # decide by LUT file 116 | 117 | self.send_command(0xe5) # FLASH MODE 118 | self.send_data(0x03) 119 | 120 | # EPD hardware init end 121 | return 0 122 | 123 | def getbuffer(self, image): 124 | logging.debug("1234") 125 | buf = [0x00] * int(self.width * self.height / 4) 126 | image_monocolor = image.convert('1') 127 | imwidth, imheight = image_monocolor.size 128 | pixels = image_monocolor.load() 129 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 130 | if(imwidth == self.width and imheight == self.height): 131 | for y in range(imheight): 132 | for x in range(imwidth): 133 | # Set the bits for the column of pixels at the current position. 134 | if pixels[x, y] < 64: # black 135 | buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2)) 136 | elif pixels[x, y] < 192: # convert gray to red 137 | buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2)) 138 | buf[int((x + y * self.width) / 4)] |= 0x40 >> (x % 4 * 2) 139 | else: # white 140 | buf[int((x + y * self.width) / 4)] |= 0xC0 >> (x % 4 * 2) 141 | elif(imwidth == self.height and imheight == self.width): 142 | for y in range(imheight): 143 | for x in range(imwidth): 144 | newx = y 145 | newy = self.height - x - 1 146 | if pixels[x, y] < 64: # black 147 | buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2)) 148 | elif pixels[x, y] < 192: # convert gray to red 149 | buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2)) 150 | buf[int((newx + newy*self.width) / 4)] |= 0x40 >> (y % 4 * 2) 151 | else: # white 152 | buf[int((newx + newy*self.width) / 4)] |= 0xC0 >> (y % 4 * 2) 153 | return buf 154 | 155 | def display(self, image): 156 | self.send_command(0x10) 157 | for i in range(0, int(self.width / 4 * self.height)): 158 | temp1 = image[i] 159 | j = 0 160 | while (j < 4): 161 | if ((temp1 & 0xC0) == 0xC0): 162 | temp2 = 0x03 163 | elif ((temp1 & 0xC0) == 0x00): 164 | temp2 = 0x00 165 | else: 166 | temp2 = 0x04 167 | temp2 = (temp2 << 4) & 0xFF 168 | temp1 = (temp1 << 2) & 0xFF 169 | j += 1 170 | if((temp1 & 0xC0) == 0xC0): 171 | temp2 |= 0x03 172 | elif ((temp1 & 0xC0) == 0x00): 173 | temp2 |= 0x00 174 | else: 175 | temp2 |= 0x04 176 | temp1 = (temp1 << 2) & 0xFF 177 | self.send_data(temp2) 178 | j += 1 179 | 180 | self.send_command(0x12) 181 | epdconfig.delay_ms(100) 182 | self.ReadBusy() 183 | 184 | def Clear(self): 185 | self.send_command(0x10) 186 | for i in range(0, int(self.width / 4 * self.height)): 187 | for j in range(0, 4): 188 | self.send_data(0x33) 189 | 190 | self.send_command(0x12) 191 | self.ReadBusy() 192 | 193 | def sleep(self): 194 | self.send_command(0x02) # POWER_OFF 195 | self.ReadBusy() 196 | 197 | self.send_command(0x07) # DEEP_SLEEP 198 | self.send_data(0XA5) 199 | 200 | epdconfig.module_exit() 201 | ### END OF FILE ### 202 | 203 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5_HD.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 880 36 | EPD_HEIGHT = 528 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(2) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | busy = epdconfig.digital_read(self.busy_pin) 71 | while(busy == 1): 72 | busy = epdconfig.digital_read(self.busy_pin) 73 | epdconfig.delay_ms(200) 74 | 75 | def init(self): 76 | if (epdconfig.module_init() != 0): 77 | return -1 78 | # EPD hardware init start 79 | self.reset() 80 | 81 | self.ReadBusy(); 82 | self.send_command(0x12); #SWRESET 83 | self.ReadBusy(); 84 | 85 | self.send_command(0x46); # Auto Write Red RAM 86 | self.send_data(0xf7); 87 | self.ReadBusy(); 88 | self.send_command(0x47); # Auto Write B/W RAM 89 | self.send_data(0xf7); 90 | self.ReadBusy(); 91 | 92 | self.send_command(0x0C); # Soft start setting 93 | self.send_data(0xAE); 94 | self.send_data(0xC7); 95 | self.send_data(0xC3); 96 | self.send_data(0xC0); 97 | self.send_data(0x40); 98 | 99 | 100 | self.send_command(0x01); # Set MUX as 527 101 | self.send_data(0xAF); 102 | self.send_data(0x02); 103 | self.send_data(0x01);#0x01 104 | 105 | self.send_command(0x11); # Data entry mode 106 | self.send_data(0x01); 107 | 108 | self.send_command(0x44); 109 | self.send_data(0x00); # RAM x address start at 0 110 | self.send_data(0x00); 111 | self.send_data(0x6F); 112 | self.send_data(0x03); 113 | self.send_command(0x45); 114 | self.send_data(0xAF); 115 | self.send_data(0x02); 116 | self.send_data(0x00); 117 | self.send_data(0x00); 118 | 119 | self.send_command(0x3C); # VBD 120 | self.send_data(0x05); # LUT1, for white 121 | 122 | self.send_command(0x18); 123 | self.send_data(0X80); 124 | 125 | 126 | self.send_command(0x22); 127 | self.send_data(0XB1); #Load Temperature and waveform setting. 128 | self.send_command(0x20); 129 | self.ReadBusy(); 130 | 131 | self.send_command(0x4E); # set RAM x address count to 0; 132 | self.send_data(0x00); 133 | self.send_data(0x00); 134 | self.send_command(0x4F); 135 | self.send_data(0x00); 136 | self.send_data(0x00); 137 | # EPD hardware init end 138 | return 0 139 | 140 | def getbuffer(self, image): 141 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 142 | buf = [0xFF] * (int(self.width/8) * self.height) 143 | image_monocolor = image.convert('1') 144 | imwidth, imheight = image_monocolor.size 145 | pixels = image_monocolor.load() 146 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 147 | if(imwidth == self.width and imheight == self.height): 148 | logging.debug("Vertical") 149 | for y in range(imheight): 150 | for x in range(imwidth): 151 | # Set the bits for the column of pixels at the current position. 152 | if pixels[x, y] == 0: 153 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 154 | elif(imwidth == self.height and imheight == self.width): 155 | logging.debug("Horizontal") 156 | for y in range(imheight): 157 | for x in range(imwidth): 158 | newx = y 159 | newy = self.height - x - 1 160 | if pixels[x, y] == 0: 161 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 162 | return buf 163 | 164 | def display(self, image): 165 | self.send_command(0x4F); 166 | self.send_data(0x00); 167 | self.send_data(0x00); 168 | self.send_command(0x24); 169 | for i in range(0, int(self.width * self.height / 8)): 170 | self.send_data(image[i]); 171 | 172 | self.send_command(0x22); 173 | self.send_data(0xF7);#Load LUT from MCU(0x32) 174 | self.send_command(0x20); 175 | epdconfig.delay_ms(10); 176 | self.ReadBusy(); 177 | 178 | def Clear(self): 179 | self.send_command(0x4F); 180 | self.send_data(0x00); 181 | self.send_data(0x00); 182 | self.send_command(0x24) 183 | for i in range(0, int(self.width * self.height / 8)): 184 | self.send_data(0xff) 185 | 186 | self.send_command(0x26) 187 | for i in range(0, int(self.width * self.height / 8)): 188 | self.send_data(0xff) 189 | 190 | self.send_command(0x22); 191 | self.send_data(0xF7);#Load LUT from MCU(0x32) 192 | self.send_command(0x20); 193 | epdconfig.delay_ms(10); 194 | self.ReadBusy(); 195 | 196 | def sleep(self): 197 | self.send_command(0x10); 198 | self.send_data(0x01); 199 | 200 | epdconfig.module_exit() 201 | ### END OF FILE ### 202 | 203 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 800 36 | EPD_HEIGHT = 480 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(2) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | self.send_command(0x71) 71 | busy = epdconfig.digital_read(self.busy_pin) 72 | while(busy == 0): 73 | self.send_command(0x71) 74 | busy = epdconfig.digital_read(self.busy_pin) 75 | epdconfig.delay_ms(200) 76 | 77 | def init(self): 78 | if (epdconfig.module_init() != 0): 79 | return -1 80 | # EPD hardware init start 81 | self.reset() 82 | 83 | self.send_command(0x01) #POWER SETTING 84 | self.send_data(0x07) 85 | self.send_data(0x07) #VGH=20V,VGL=-20V 86 | self.send_data(0x3f) #VDH=15V 87 | self.send_data(0x3f) #VDL=-15V 88 | 89 | self.send_command(0x04) #POWER ON 90 | epdconfig.delay_ms(100) 91 | self.ReadBusy() 92 | 93 | self.send_command(0X00) #PANNEL SETTING 94 | self.send_data(0x1F) #KW-3f KWR-2F BWROTP 0f BWOTP 1f 95 | 96 | self.send_command(0x61) #tres 97 | self.send_data(0x03) #source 800 98 | self.send_data(0x20) 99 | self.send_data(0x01) #gate 480 100 | self.send_data(0xE0) 101 | 102 | self.send_command(0X15) 103 | self.send_data(0x00) 104 | 105 | self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING 106 | self.send_data(0x10) 107 | self.send_data(0x07) 108 | 109 | self.send_command(0X60) #TCON SETTING 110 | self.send_data(0x22) 111 | 112 | # EPD hardware init end 113 | return 0 114 | 115 | def getbuffer(self, image): 116 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 117 | buf = [0xFF] * (int(self.width/8) * self.height) 118 | image_monocolor = image.convert('1') 119 | imwidth, imheight = image_monocolor.size 120 | pixels = image_monocolor.load() 121 | # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) 122 | if(imwidth == self.width and imheight == self.height): 123 | logging.debug("Vertical") 124 | for y in range(imheight): 125 | for x in range(imwidth): 126 | # Set the bits for the column of pixels at the current position. 127 | if pixels[x, y] == 0: 128 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 129 | elif(imwidth == self.height and imheight == self.width): 130 | logging.debug("Horizontal") 131 | for y in range(imheight): 132 | for x in range(imwidth): 133 | newx = y 134 | newy = self.height - x - 1 135 | if pixels[x, y] == 0: 136 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 137 | return buf 138 | 139 | def display(self, image): 140 | self.send_command(0x13) 141 | for i in range(0, int(self.width * self.height / 8)): 142 | self.send_data(~image[i]); 143 | 144 | self.send_command(0x12) 145 | epdconfig.delay_ms(100) 146 | self.ReadBusy() 147 | 148 | def Clear(self): 149 | self.send_command(0x10) 150 | for i in range(0, int(self.width * self.height / 8)): 151 | self.send_data(0x00) 152 | 153 | self.send_command(0x13) 154 | for i in range(0, int(self.width * self.height / 8)): 155 | self.send_data(0x00) 156 | 157 | self.send_command(0x12) 158 | epdconfig.delay_ms(100) 159 | self.ReadBusy() 160 | 161 | def sleep(self): 162 | self.send_command(0x02) # POWER_OFF 163 | self.ReadBusy() 164 | 165 | self.send_command(0x07) # DEEP_SLEEP 166 | self.send_data(0XA5) 167 | 168 | epdconfig.module_exit() 169 | ### END OF FILE ### 170 | 171 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5_V2.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XRobots/IoT-Message-Board/98ee572cd799677eb5ede5da1426f78fb43144de/Code/sheets/lib/waveshare_epd/epd7in5_V2.pyc -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5b_HD.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5bc_HD.py 3 | # * | Author : Waveshare team 4 | # * | Function : Electronic paper driver 5 | # * | Info : 6 | # *---------------- 7 | # * | This version: V1.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 880 36 | EPD_HEIGHT = 528 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(4) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | busy = epdconfig.digital_read(self.busy_pin) 71 | while(busy == 1): 72 | busy = epdconfig.digital_read(self.busy_pin) 73 | epdconfig.delay_ms(200) 74 | 75 | def init(self): 76 | if (epdconfig.module_init() != 0): 77 | return -1 78 | 79 | self.reset() 80 | 81 | self.send_command(0x12); #SWRESET 82 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 83 | 84 | self.send_command(0x46); # Auto Write RAM 85 | self.send_data(0xF7); 86 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 87 | 88 | self.send_command(0x47); # Auto Write RAM 89 | self.send_data(0xF7); 90 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 91 | 92 | self.send_command(0x0C); # Soft start setting 93 | self.send_data(0xAE); 94 | self.send_data(0xC7); 95 | self.send_data(0xC3); 96 | self.send_data(0xC0); 97 | self.send_data(0x40); 98 | 99 | self.send_command(0x01); # Set MUX as 527 100 | self.send_data(0xAF); 101 | self.send_data(0x02); 102 | self.send_data(0x01); 103 | 104 | self.send_command(0x11); # Data entry mode 105 | self.send_data(0x01); 106 | 107 | self.send_command(0x44); 108 | self.send_data(0x00); # RAM x address start at 0 109 | self.send_data(0x00); 110 | self.send_data(0x6F); # RAM x address end at 36Fh -> 879 111 | self.send_data(0x03); 112 | self.send_command(0x45); 113 | self.send_data(0xAF); # RAM y address start at 20Fh; 114 | self.send_data(0x02); 115 | self.send_data(0x00); # RAM y address end at 00h; 116 | self.send_data(0x00); 117 | 118 | self.send_command(0x3C); # VBD 119 | self.send_data(0x01); # LUT1, for white 120 | 121 | self.send_command(0x18); 122 | self.send_data(0X80); 123 | self.send_command(0x22); 124 | self.send_data(0XB1); #Load Temperature and waveform setting. 125 | self.send_command(0x20); 126 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 127 | 128 | self.send_command(0x4E); 129 | self.send_data(0x00); 130 | self.send_data(0x00); 131 | self.send_command(0x4F); 132 | self.send_data(0xAF); 133 | self.send_data(0x02); 134 | 135 | return 0 136 | 137 | def getbuffer(self, image): 138 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 139 | buf = [0xFF] * (int(self.width/8) * self.height) 140 | image_monocolor = image.convert('1') 141 | imwidth, imheight = image_monocolor.size 142 | pixels = image_monocolor.load() 143 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 144 | if(imwidth == self.width and imheight == self.height): 145 | logging.debug("Horizontal") 146 | for y in range(imheight): 147 | for x in range(imwidth): 148 | # Set the bits for the column of pixels at the current position. 149 | if pixels[x, y] == 0: 150 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 151 | elif(imwidth == self.height and imheight == self.width): 152 | logging.debug("Vertical") 153 | for y in range(imheight): 154 | for x in range(imwidth): 155 | newx = y 156 | newy = self.height - x - 1 157 | if pixels[x, y] == 0: 158 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 159 | return buf 160 | 161 | def display(self, imageblack, imagered): 162 | self.send_command(0x4F); 163 | self.send_data(0xAf); 164 | 165 | self.send_command(0x24) 166 | for i in range(0, int(self.width * self.height / 8)): 167 | self.send_data(imageblack[i]); 168 | 169 | 170 | self.send_command(0x26) 171 | for i in range(0, int(self.width * self.height / 8)): 172 | self.send_data(~imagered[i]); 173 | 174 | self.send_command(0x22); 175 | self.send_data(0xC7); #Load LUT from MCU(0x32) 176 | self.send_command(0x20); 177 | epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!! 178 | self.ReadBusy(); 179 | 180 | def Clear(self): 181 | self.send_command(0x4F); 182 | self.send_data(0xAf); 183 | 184 | self.send_command(0x24) 185 | for i in range(0, int(self.width * self.height / 8)): 186 | self.send_data(0xff); 187 | 188 | 189 | self.send_command(0x26) 190 | for i in range(0, int(self.width * self.height / 8)): 191 | self.send_data(0x00); 192 | 193 | self.send_command(0x22); 194 | self.send_data(0xC7); #Load LUT from MCU(0x32) 195 | self.send_command(0x20); 196 | epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!! 197 | self.ReadBusy(); 198 | 199 | def sleep(self): 200 | self.send_command(0x10); #deep sleep 201 | self.send_data(0x01); 202 | 203 | epdconfig.module_exit() 204 | ### END OF FILE ### 205 | 206 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5b_V3.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5bc.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 880 36 | EPD_HEIGHT = 528 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(4) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | busy = epdconfig.digital_read(self.busy_pin) 71 | while(busy == 1): 72 | busy = epdconfig.digital_read(self.busy_pin) 73 | epdconfig.delay_ms(200) 74 | 75 | def init(self): 76 | if (epdconfig.module_init() != 0): 77 | return -1 78 | 79 | self.reset() 80 | 81 | self.send_command(0x12); #SWRESET 82 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 83 | 84 | self.send_command(0x46); # Auto Write RAM 85 | self.send_data(0xF7); 86 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 87 | 88 | self.send_command(0x47); # Auto Write RAM 89 | self.send_data(0xF7); 90 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 91 | 92 | self.send_command(0x0C); # Soft start setting 93 | self.send_data(0xAE); 94 | self.send_data(0xC7); 95 | self.send_data(0xC3); 96 | self.send_data(0xC0); 97 | self.send_data(0x40); 98 | 99 | self.send_command(0x01); # Set MUX as 527 100 | self.send_data(0xAF); 101 | self.send_data(0x02); 102 | self.send_data(0x01); 103 | 104 | self.send_command(0x11); # Data entry mode 105 | self.send_data(0x01); 106 | 107 | self.send_command(0x44); 108 | self.send_data(0x00); # RAM x address start at 0 109 | self.send_data(0x00); 110 | self.send_data(0x6F); # RAM x address end at 36Fh -> 879 111 | self.send_data(0x03); 112 | self.send_command(0x45); 113 | self.send_data(0xAF); # RAM y address start at 20Fh; 114 | self.send_data(0x02); 115 | self.send_data(0x00); # RAM y address end at 00h; 116 | self.send_data(0x00); 117 | 118 | self.send_command(0x3C); # VBD 119 | self.send_data(0x01); # LUT1, for white 120 | 121 | self.send_command(0x18); 122 | self.send_data(0X80); 123 | self.send_command(0x22); 124 | self.send_data(0XB1); #Load Temperature and waveform setting. 125 | self.send_command(0x20); 126 | self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal 127 | 128 | self.send_command(0x4E); 129 | self.send_data(0x00); 130 | self.send_data(0x00); 131 | self.send_command(0x4F); 132 | self.send_data(0xAF); 133 | self.send_data(0x02); 134 | 135 | return 0 136 | 137 | def getbuffer(self, image): 138 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 139 | buf = [0xFF] * (int(self.width/8) * self.height) 140 | image_monocolor = image.convert('1') 141 | imwidth, imheight = image_monocolor.size 142 | pixels = image_monocolor.load() 143 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 144 | if(imwidth == self.width and imheight == self.height): 145 | logging.debug("Horizontal") 146 | for y in range(imheight): 147 | for x in range(imwidth): 148 | # Set the bits for the column of pixels at the current position. 149 | if pixels[x, y] == 0: 150 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 151 | elif(imwidth == self.height and imheight == self.width): 152 | logging.debug("Vertical") 153 | for y in range(imheight): 154 | for x in range(imwidth): 155 | newx = y 156 | newy = self.height - x - 1 157 | if pixels[x, y] == 0: 158 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 159 | return buf 160 | 161 | def display(self, imageblack, imagered): 162 | self.send_command(0x4F); 163 | self.send_data(0xAf); 164 | 165 | self.send_command(0x24) 166 | for i in range(0, int(self.width * self.height / 8)): 167 | self.send_data(imageblack[i]); 168 | 169 | 170 | self.send_command(0x26) 171 | for i in range(0, int(self.width * self.height / 8)): 172 | self.send_data(~imagered[i]); 173 | 174 | self.send_command(0x22); 175 | self.send_data(0xC7); #Load LUT from MCU(0x32) 176 | self.send_command(0x20); 177 | epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!! 178 | self.ReadBusy(); 179 | 180 | def Clear(self): 181 | self.send_command(0x4F); 182 | self.send_data(0xAf); 183 | 184 | self.send_command(0x24) 185 | for i in range(0, int(self.width * self.height / 8)): 186 | self.send_data(0xff); 187 | 188 | 189 | self.send_command(0x26) 190 | for i in range(0, int(self.width * self.height / 8)): 191 | self.send_data(0x00); 192 | 193 | self.send_command(0x22); 194 | self.send_data(0xC7); #Load LUT from MCU(0x32) 195 | self.send_command(0x20); 196 | epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!! 197 | self.ReadBusy(); 198 | 199 | def sleep(self): 200 | self.send_command(0x10); #deep sleep 201 | self.send_data(0x01); 202 | 203 | epdconfig.module_exit() 204 | ### END OF FILE ### 205 | 206 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5bc.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5bc.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 640 36 | EPD_HEIGHT = 384 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(10) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy 71 | epdconfig.delay_ms(100) 72 | logging.debug("e-Paper busy release") 73 | 74 | def init(self): 75 | if (epdconfig.module_init() != 0): 76 | return -1 77 | 78 | self.reset() 79 | 80 | self.send_command(0x01) # POWER_SETTING 81 | self.send_data(0x37) 82 | self.send_data(0x00) 83 | 84 | self.send_command(0x00) # PANEL_SETTING 85 | self.send_data(0xCF) 86 | self.send_data(0x08) 87 | 88 | self.send_command(0x30) # PLL_CONTROL 89 | self.send_data(0x3A) # PLL: 0-15:0x3C, 15+:0x3A 90 | 91 | self.send_command(0x82) # VCM_DC_SETTING 92 | self.send_data(0x28) #all temperature range 93 | 94 | self.send_command(0x06) # BOOSTER_SOFT_START 95 | self.send_data(0xc7) 96 | self.send_data(0xcc) 97 | self.send_data(0x15) 98 | 99 | self.send_command(0x50) # VCOM AND DATA INTERVAL SETTING 100 | self.send_data(0x77) 101 | 102 | self.send_command(0x60) # TCON_SETTING 103 | self.send_data(0x22) 104 | 105 | self.send_command(0x65) # FLASH CONTROL 106 | self.send_data(0x00) 107 | 108 | self.send_command(0x61) # TCON_RESOLUTION 109 | self.send_data(self.width >> 8) # source 640 110 | self.send_data(self.width & 0xff) 111 | self.send_data(self.height >> 8) # gate 384 112 | self.send_data(self.height & 0xff) 113 | 114 | self.send_command(0xe5) # FLASH MODE 115 | self.send_data(0x03) 116 | 117 | return 0 118 | 119 | def getbuffer(self, image): 120 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 121 | buf = [0xFF] * (int(self.width/8) * self.height) 122 | image_monocolor = image.convert('1') 123 | imwidth, imheight = image_monocolor.size 124 | pixels = image_monocolor.load() 125 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 126 | if(imwidth == self.width and imheight == self.height): 127 | logging.debug("Horizontal") 128 | for y in range(imheight): 129 | for x in range(imwidth): 130 | # Set the bits for the column of pixels at the current position. 131 | if pixels[x, y] == 0: 132 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 133 | elif(imwidth == self.height and imheight == self.width): 134 | logging.debug("Vertical") 135 | for y in range(imheight): 136 | for x in range(imwidth): 137 | newx = y 138 | newy = self.height - x - 1 139 | if pixels[x, y] == 0: 140 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 141 | return buf 142 | 143 | def display(self, imageblack, imagered): 144 | self.send_command(0x10) 145 | for i in range(0, int(self.width / 8 * self.height)): 146 | temp1 = imageblack[i] 147 | temp2 = imagered[i] 148 | j = 0 149 | while (j < 8): 150 | if ((temp2 & 0x80) == 0x00): 151 | temp3 = 0x04 #red 152 | elif ((temp1 & 0x80) == 0x00): 153 | temp3 = 0x00 #black 154 | else: 155 | temp3 = 0x03 #white 156 | 157 | temp3 = (temp3 << 4) & 0xFF 158 | temp1 = (temp1 << 1) & 0xFF 159 | temp2 = (temp2 << 1) & 0xFF 160 | j += 1 161 | if((temp2 & 0x80) == 0x00): 162 | temp3 |= 0x04 #red 163 | elif ((temp1 & 0x80) == 0x00): 164 | temp3 |= 0x00 #black 165 | else: 166 | temp3 |= 0x03 #white 167 | temp1 = (temp1 << 1) & 0xFF 168 | temp2 = (temp2 << 1) & 0xFF 169 | self.send_data(temp3) 170 | j += 1 171 | 172 | self.send_command(0x04) # POWER ON 173 | self.ReadBusy() 174 | self.send_command(0x12) # display refresh 175 | epdconfig.delay_ms(100) 176 | self.ReadBusy() 177 | 178 | def Clear(self): 179 | self.send_command(0x10) 180 | for i in range(0, int(self.width / 8 * self.height)): 181 | self.send_data(0x33) 182 | self.send_data(0x33) 183 | self.send_data(0x33) 184 | self.send_data(0x33) 185 | 186 | self.send_command(0x04) # POWER ON 187 | self.ReadBusy() 188 | self.send_command(0x12) # display refresh 189 | epdconfig.delay_ms(100) 190 | self.ReadBusy() 191 | 192 | def sleep(self): 193 | self.send_command(0x02) # POWER_OFF 194 | self.ReadBusy() 195 | 196 | self.send_command(0x07) # DEEP_SLEEP 197 | self.send_data(0XA5) 198 | 199 | epdconfig.module_exit() 200 | ### END OF FILE ### 201 | 202 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epd7in5bc_V2.py: -------------------------------------------------------------------------------- 1 | # ***************************************************************************** 2 | # * | File : epd7in5bc.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 | 30 | 31 | import logging 32 | from . import epdconfig 33 | 34 | # Display resolution 35 | EPD_WIDTH = 800 36 | EPD_HEIGHT = 480 37 | 38 | class EPD: 39 | def __init__(self): 40 | self.reset_pin = epdconfig.RST_PIN 41 | self.dc_pin = epdconfig.DC_PIN 42 | self.busy_pin = epdconfig.BUSY_PIN 43 | self.cs_pin = epdconfig.CS_PIN 44 | self.width = EPD_WIDTH 45 | self.height = EPD_HEIGHT 46 | 47 | # Hardware reset 48 | def reset(self): 49 | epdconfig.digital_write(self.reset_pin, 1) 50 | epdconfig.delay_ms(200) 51 | epdconfig.digital_write(self.reset_pin, 0) 52 | epdconfig.delay_ms(4) 53 | epdconfig.digital_write(self.reset_pin, 1) 54 | epdconfig.delay_ms(200) 55 | 56 | def send_command(self, command): 57 | epdconfig.digital_write(self.dc_pin, 0) 58 | epdconfig.digital_write(self.cs_pin, 0) 59 | epdconfig.spi_writebyte([command]) 60 | epdconfig.digital_write(self.cs_pin, 1) 61 | 62 | def send_data(self, data): 63 | epdconfig.digital_write(self.dc_pin, 1) 64 | epdconfig.digital_write(self.cs_pin, 0) 65 | epdconfig.spi_writebyte([data]) 66 | epdconfig.digital_write(self.cs_pin, 1) 67 | 68 | def ReadBusy(self): 69 | logging.debug("e-Paper busy") 70 | self.send_command(0x71) 71 | busy = epdconfig.digital_read(self.busy_pin) 72 | while(busy == 0): 73 | self.send_command(0x71) 74 | busy = epdconfig.digital_read(self.busy_pin) 75 | epdconfig.delay_ms(200) 76 | 77 | def init(self): 78 | if (epdconfig.module_init() != 0): 79 | return -1 80 | 81 | self.reset() 82 | 83 | self.send_command(0x01); #POWER SETTING 84 | self.send_data(0x07); 85 | self.send_data(0x07); #VGH=20V,VGL=-20V 86 | self.send_data(0x3f); #VDH=15V 87 | self.send_data(0x3f); #VDL=-15V 88 | 89 | self.send_command(0x04); #POWER ON 90 | epdconfig.delay_ms(100); 91 | self.ReadBusy(); 92 | 93 | self.send_command(0X00); #PANNEL SETTING 94 | self.send_data(0x0F); #KW-3f KWR-2F BWROTP 0f BWOTP 1f 95 | 96 | self.send_command(0x61); #tres 97 | self.send_data(0x03); #source 800 98 | self.send_data(0x20); 99 | self.send_data(0x01); #gate 480 100 | self.send_data(0xE0); 101 | 102 | self.send_command(0X15); 103 | self.send_data(0x00); 104 | 105 | self.send_command(0X50); #VCOM AND DATA INTERVAL SETTING 106 | self.send_data(0x11); 107 | self.send_data(0x07); 108 | 109 | self.send_command(0X60); #TCON SETTING 110 | self.send_data(0x22); 111 | 112 | return 0 113 | 114 | def getbuffer(self, image): 115 | # logging.debug("bufsiz = ",int(self.width/8) * self.height) 116 | buf = [0xFF] * (int(self.width/8) * self.height) 117 | image_monocolor = image.convert('1') 118 | imwidth, imheight = image_monocolor.size 119 | pixels = image_monocolor.load() 120 | logging.debug('imwidth = %d imheight = %d ',imwidth, imheight) 121 | if(imwidth == self.width and imheight == self.height): 122 | logging.debug("Horizontal") 123 | for y in range(imheight): 124 | for x in range(imwidth): 125 | # Set the bits for the column of pixels at the current position. 126 | if pixels[x, y] == 0: 127 | buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) 128 | elif(imwidth == self.height and imheight == self.width): 129 | logging.debug("Vertical") 130 | for y in range(imheight): 131 | for x in range(imwidth): 132 | newx = y 133 | newy = self.height - x - 1 134 | if pixels[x, y] == 0: 135 | buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) 136 | return buf 137 | 138 | def display(self, imageblack, imagered): 139 | self.send_command(0x10) 140 | for i in range(0, int(self.width * self.height / 8)): 141 | self.send_data(imageblack[i]); 142 | 143 | self.send_command(0x13) 144 | for i in range(0, int(self.width * self.height / 8)): 145 | self.send_data(~imagered[i]); 146 | 147 | self.send_command(0x12) 148 | epdconfig.delay_ms(100) 149 | self.ReadBusy() 150 | 151 | def Clear(self): 152 | self.send_command(0x10) 153 | for i in range(0, int(self.width * self.height / 8)): 154 | self.send_data(0xff) 155 | 156 | self.send_command(0x13) 157 | for i in range(0, int(self.width * self.height / 8)): 158 | self.send_data(0x00) 159 | 160 | self.send_command(0x12) 161 | epdconfig.delay_ms(100) 162 | self.ReadBusy() 163 | 164 | def sleep(self): 165 | self.send_command(0x02) # POWER_OFF 166 | self.ReadBusy() 167 | 168 | self.send_command(0x07) # DEEP_SLEEP 169 | self.send_data(0XA5) 170 | 171 | epdconfig.module_exit() 172 | ### END OF FILE ### 173 | 174 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epdconfig.py: -------------------------------------------------------------------------------- 1 | # /***************************************************************************** 2 | # * | File : epdconfig.py 3 | # * | Author : Waveshare team 4 | # * | Function : Hardware underlying interface 5 | # * | Info : 6 | # *---------------- 7 | # * | This version: V1.0 8 | # * | Date : 2019-06-21 9 | # * | Info : 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 | 30 | import os 31 | import logging 32 | import sys 33 | import time 34 | 35 | 36 | class RaspberryPi: 37 | # Pin definition 38 | RST_PIN = 17 39 | DC_PIN = 25 40 | CS_PIN = 8 41 | BUSY_PIN = 24 42 | 43 | def __init__(self): 44 | import spidev 45 | import RPi.GPIO 46 | 47 | self.GPIO = RPi.GPIO 48 | 49 | # SPI device, bus = 0, device = 0 50 | self.SPI = spidev.SpiDev(0, 0) 51 | 52 | def digital_write(self, pin, value): 53 | self.GPIO.output(pin, value) 54 | 55 | def digital_read(self, pin): 56 | return self.GPIO.input(pin) 57 | 58 | def delay_ms(self, delaytime): 59 | time.sleep(delaytime / 1000.0) 60 | 61 | def spi_writebyte(self, data): 62 | self.SPI.writebytes(data) 63 | 64 | def module_init(self): 65 | self.GPIO.setmode(self.GPIO.BCM) 66 | self.GPIO.setwarnings(False) 67 | self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) 68 | self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) 69 | self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) 70 | self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) 71 | self.SPI.max_speed_hz = 4000000 72 | self.SPI.mode = 0b00 73 | return 0 74 | 75 | def module_exit(self): 76 | logging.debug("spi end") 77 | self.SPI.close() 78 | 79 | logging.debug("close 5V, Module enters 0 power consumption ...") 80 | self.GPIO.output(self.RST_PIN, 0) 81 | self.GPIO.output(self.DC_PIN, 0) 82 | 83 | self.GPIO.cleanup() 84 | 85 | 86 | class JetsonNano: 87 | # Pin definition 88 | RST_PIN = 17 89 | DC_PIN = 25 90 | CS_PIN = 8 91 | BUSY_PIN = 24 92 | 93 | def __init__(self): 94 | import ctypes 95 | find_dirs = [ 96 | os.path.dirname(os.path.realpath(__file__)), 97 | '/usr/local/lib', 98 | '/usr/lib', 99 | ] 100 | self.SPI = None 101 | for find_dir in find_dirs: 102 | so_filename = os.path.join(find_dir, 'sysfs_software_spi.so') 103 | if os.path.exists(so_filename): 104 | self.SPI = ctypes.cdll.LoadLibrary(so_filename) 105 | break 106 | if self.SPI is None: 107 | raise RuntimeError('Cannot find sysfs_software_spi.so') 108 | 109 | import Jetson.GPIO 110 | self.GPIO = Jetson.GPIO 111 | 112 | def digital_write(self, pin, value): 113 | self.GPIO.output(pin, value) 114 | 115 | def digital_read(self, pin): 116 | return self.GPIO.input(self.BUSY_PIN) 117 | 118 | def delay_ms(self, delaytime): 119 | time.sleep(delaytime / 1000.0) 120 | 121 | def spi_writebyte(self, data): 122 | self.SPI.SYSFS_software_spi_transfer(data[0]) 123 | 124 | def module_init(self): 125 | self.GPIO.setmode(self.GPIO.BCM) 126 | self.GPIO.setwarnings(False) 127 | self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) 128 | self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) 129 | self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) 130 | self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) 131 | self.SPI.SYSFS_software_spi_begin() 132 | return 0 133 | 134 | def module_exit(self): 135 | logging.debug("spi end") 136 | self.SPI.SYSFS_software_spi_end() 137 | 138 | logging.debug("close 5V, Module enters 0 power consumption ...") 139 | self.GPIO.output(self.RST_PIN, 0) 140 | self.GPIO.output(self.DC_PIN, 0) 141 | 142 | self.GPIO.cleanup() 143 | 144 | 145 | if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'): 146 | implementation = RaspberryPi() 147 | else: 148 | implementation = JetsonNano() 149 | 150 | for func in [x for x in dir(implementation) if not x.startswith('_')]: 151 | setattr(sys.modules[__name__], func, getattr(implementation, func)) 152 | 153 | 154 | ### END OF FILE ### 155 | -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/epdconfig.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XRobots/IoT-Message-Board/98ee572cd799677eb5ede5da1426f78fb43144de/Code/sheets/lib/waveshare_epd/epdconfig.pyc -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/sysfs_gpio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XRobots/IoT-Message-Board/98ee572cd799677eb5ede5da1426f78fb43144de/Code/sheets/lib/waveshare_epd/sysfs_gpio.so -------------------------------------------------------------------------------- /Code/sheets/lib/waveshare_epd/sysfs_software_spi.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XRobots/IoT-Message-Board/98ee572cd799677eb5ede5da1426f78fb43144de/Code/sheets/lib/waveshare_epd/sysfs_software_spi.so -------------------------------------------------------------------------------- /Code/v1/log.csv: -------------------------------------------------------------------------------- 1 | khkhkhkhkh,llllllllllllllllll,jjjjjjjjjjjjjjjjjjjjjjj,pooooooooooooooooooo,doggy,,,test8,,cheese,weeeeee,test12,ghghghghhghhghghghghgh,test14,soup, -------------------------------------------------------------------------------- /Code/v1/sheet02.txt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding:utf-8 -*- 3 | 4 | # importing the required libraries 5 | 6 | import sys 7 | import os 8 | import csv 9 | picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic') 10 | libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib') 11 | if os.path.exists(libdir): 12 | sys.path.append(libdir) 13 | 14 | from waveshare_epd import epd7in5_V2 15 | import time 16 | from PIL import Image,ImageDraw,ImageFont 17 | #import traceback 18 | 19 | font35 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 35) 20 | 21 | import gspread 22 | from oauth2client.service_account import ServiceAccountCredentials 23 | 24 | # define the scope 25 | scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'] 26 | 27 | # add credentials to the account 28 | creds = ServiceAccountCredentials.from_json_keyfile_name('key.json', scope) 29 | 30 | # authorize the clientsheet 31 | client = gspread.authorize(creds) 32 | 33 | 34 | # get the instance of the Spreadsheet 35 | sheet = client.open('Messageboard') 36 | 37 | # read old vaues from last tme 38 | 39 | filename = "log.csv" # log file to check previous data 40 | 41 | f = open(filename, 'r') 42 | csv_f = csv.reader(f) 43 | 44 | for row in csv_f: 45 | A1old = row[0] 46 | A2old = row[1] 47 | A3old = row[2] 48 | A4old = row[3] 49 | A5old = row[4] 50 | A6old = row[5] 51 | A7old = row[6] 52 | A8old = row[7] 53 | A9old = row[8] 54 | A10old = row[9] 55 | A11old = row[10] 56 | A12old = row[11] 57 | A13old = row[12] 58 | A14old = row[13] 59 | A15old = row[14] 60 | 61 | print("getting data from sheet") 62 | 63 | # get the first sheet of the Spreadsheet 64 | sheet_instance = sheet.get_worksheet(0) 65 | 66 | # get the cells in the first column 67 | 68 | A1 = (sheet_instance.acell('A1').value) 69 | A2 = (sheet_instance.acell('A2').value) 70 | A3 = (sheet_instance.acell('A3').value) 71 | A4 = (sheet_instance.acell('A4').value) 72 | A5 = (sheet_instance.acell('A5').value) 73 | A6 = (sheet_instance.acell('A6').value) 74 | A7 = (sheet_instance.acell('A7').value) 75 | A8 = (sheet_instance.acell('A8').value) 76 | A9 = (sheet_instance.acell('A9').value) 77 | A10 = (sheet_instance.acell('A10').value) 78 | A11 = (sheet_instance.acell('A11').value) 79 | A12 = (sheet_instance.acell('A12').value) 80 | A13 = (sheet_instance.acell('A13').value) 81 | A14 = (sheet_instance.acell('A14').value) 82 | A15 = (sheet_instance.acell('A15').value) 83 | 84 | # write values to text log file 85 | csv = open(filename, 'w') 86 | csv.write(A1) 87 | csv.write(",") 88 | csv.write(A2) 89 | csv.write(",") 90 | csv.write(A3) 91 | csv.write(",") 92 | csv.write(A4) 93 | csv.write(",") 94 | csv.write(A5) 95 | csv.write(",") 96 | csv.write(A6) 97 | csv.write(",") 98 | csv.write(A7) 99 | csv.write(",") 100 | csv.write(A8) 101 | csv.write(",") 102 | csv.write(A9) 103 | csv.write(",") 104 | csv.write(A10) 105 | csv.write(",") 106 | csv.write(A11) 107 | csv.write(",") 108 | csv.write(A12) 109 | csv.write(",") 110 | csv.write(A13) 111 | csv.write(",") 112 | csv.write(A14) 113 | csv.write(",") 114 | csv.write(A15) 115 | csv.write(",") 116 | csv.close 117 | 118 | # check if there is any new data since last time 119 | 120 | if (A1old != A1 or A2old != A2 or A3old != A3 or A4old != A4 or A5old != A5 or A6old != A6 or A7old != A7 or A8old != A8 or A9old != A9 or A10old != A10 or A11old != A11 or A12old != A12 or A13old != A13 or A14old != A14 or A15old != A15): 121 | 122 | # e-Paper display stuff 123 | 124 | epd = epd7in5_V2.EPD() 125 | epd.init() 126 | epd.Clear() 127 | # Drawing on the Vertical image 128 | Limage = Image.new('1', (epd.height, epd.width), 255) # 255: clear the frame 129 | draw = ImageDraw.Draw(Limage) 130 | print ("rendering display") 131 | draw.text((2, 0), A1, font = font35, fill = 0) 132 | draw.text((2, 50), A2, font = font35, fill = 0) 133 | draw.text((2, 100), A3, font = font35, fill = 0) 134 | draw.text((2, 150), A4, font = font35, fill = 0) 135 | draw.text((2, 200), A5, font = font35, fill = 0) 136 | draw.text((2, 250), A6, font = font35, fill = 0) 137 | draw.text((2, 300), A7, font = font35, fill = 0) 138 | draw.text((2, 350), A8, font = font35, fill = 0) 139 | draw.text((2, 400), A9, font = font35, fill = 0) 140 | draw.text((2, 450), A10, font = font35, fill = 0) 141 | draw.text((2, 500), A11, font = font35, fill = 0) 142 | draw.text((2, 550), A12, font = font35, fill = 0) 143 | draw.text((2, 600), A13, font = font35, fill = 0) 144 | draw.text((2, 650), A14, font = font35, fill = 0) 145 | draw.text((2, 700), A15, font = font35, fill = 0) 146 | 147 | #print(var1, ":", var2, " ", var3, ":", var4) 148 | 149 | epd.display(epd.getbuffer(Limage)) 150 | epd.sleep() 151 | print("sleeping") 152 | 153 | else: 154 | print("there was no new data") 155 | 156 | 157 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 James Bruton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IoT-Message-Board --------------------------------------------------------------------------------