2
0
Эх сурвалжийг харах

Performance improvements using the 5.65" 7 color E Ink display.

1. As many others have done, switch to using SPI writebytes2() to send pixel data in bulk.  This makes a significant difference on a Raspberry Pi Zero W.
2. Use PIL (Pillow) to convert the image into the correct 4-bit color using a custom palette.  This dramatically speeds up conversion of the image, with the benefit of allow any kind of input image.  PIL will dither quantize/dither the colors as needed.
3. Minor formatting changes to add/remove whitespace
Ryan Ziolko 4 жил өмнө
parent
commit
4fb55dbb71

+ 52 - 87
RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in65f.py

@@ -32,6 +32,10 @@
 import logging
 from . import epdconfig
 
+import PIL
+from PIL import Image
+import io
+
 # Display resolution
 EPD_WIDTH       = 600
 EPD_HEIGHT      = 448
@@ -51,12 +55,12 @@ class EPD:
         self.RED    = 0x0000ff   #   0100
         self.YELLOW = 0x00ffff   #   0101
         self.ORANGE = 0x0080ff   #   0110
-        
-        
+
+
     # Hardware reset
     def reset(self):
         epdconfig.digital_write(self.reset_pin, 1)
-        epdconfig.delay_ms(600) 
+        epdconfig.delay_ms(600)
         epdconfig.digital_write(self.reset_pin, 0)
         epdconfig.delay_ms(2)
         epdconfig.digital_write(self.reset_pin, 1)
@@ -73,25 +77,31 @@ class EPD:
         epdconfig.digital_write(self.cs_pin, 0)
         epdconfig.spi_writebyte([data])
         epdconfig.digital_write(self.cs_pin, 1)
-        
+
+    def send_data_bulk(self, data):
+        epdconfig.digital_write(self.dc_pin, 1)
+        epdconfig.digital_write(self.cs_pin, 0)
+        epdconfig.spi_writebyte2(data)
+        epdconfig.digital_write(self.cs_pin, 1)
+
     def ReadBusyHigh(self):
         logging.debug("e-Paper busy")
         while(epdconfig.digital_read(self.busy_pin) == 0):      # 0: idle, 1: busy
-            epdconfig.delay_ms(100)    
+            epdconfig.delay_ms(100)
         logging.debug("e-Paper busy release")
-        
+
     def ReadBusyLow(self):
         logging.debug("e-Paper busy")
         while(epdconfig.digital_read(self.busy_pin) == 1):      # 0: idle, 1: busy
-            epdconfig.delay_ms(100)    
+            epdconfig.delay_ms(100)
         logging.debug("e-Paper busy release")
-        
+
     def init(self):
         if (epdconfig.module_init() != 0):
             return -1
         # EPD hardware init start
         self.reset()
-        
+
         self.ReadBusyHigh()
         self.send_command(0x00)
         self.send_data(0xEF)
@@ -122,7 +132,7 @@ class EPD:
         self.send_data(0xC0)
         self.send_command(0xE3)
         self.send_data(0xAA)
-        
+
         epdconfig.delay_ms(100)
         self.send_command(0x50)
         self.send_data(0x37)
@@ -130,102 +140,58 @@ class EPD:
         return 0
 
     def getbuffer(self, image):
+        # Create a pallette with the 7 colors supported by the panel
+        pal_image= Image.new("P", (1,1))
+        pal_image.putpalette( (0,0,0,  255,255,255,  0,255,0,   0,0,255,  255,0,0,  255,255,0, 255,128,0) + (0,0,0)*249)
+
+        # Convert the soruce image to the 7 colors, dithering if needed
+        image_7color = image.convert("RGB").quantize(palette=pal_image)
+        buf_7color = bytearray(image_7color.tobytes('raw'))
+
+        # PIL does not support 4 bit color, so pack the 4 bits of color
+        # into a single byte to transfer to the panel
         buf = [0x00] * int(self.width * self.height / 2)
-        image_monocolor = image.convert('RGB')#Picture mode conversion
-        imwidth, imheight = image_monocolor.size
-        pixels = image_monocolor.load()
-        logging.debug('imwidth = %d  imheight =  %d ',imwidth, imheight)
-        if(imwidth == self.width and imheight == self.height):
-            for y in range(imheight):
-                for x in range(imwidth):
-                    # Set the bits for the column of pixels at the current position.
-                    Add = int((x + y * self.width) / 2)
-                    Color = 0;
-                    if (pixels[x, y][0] == 0 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
-                        Color = 0
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 255):
-                        Color = 1
-                    elif (pixels[x, y][0] == 0 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
-                        Color = 2
-                    elif (pixels[x, y][0] == 0 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 255):
-                        Color = 3
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
-                        Color = 4
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
-                        Color = 5
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 128 and pixels[x, y][2] == 0):
-                        Color = 6
-                    
-                    data_t = buf[Add]&(~(0xF0 >> ((x % 2)*4)))
-                    buf[Add] = data_t | ((Color << 4) >> ((x % 2)*4));
-                        
-        elif(imwidth == self.height and imheight == self.width):
-            for y in range(imheight):
-                for x in range(imwidth):
-                    newx = y
-                    newy = self.height - x - 1   
-                    Add = int((newx + newy*self.width) / 2)
-                    Color = 0;
-                    if (pixels[x, y][0] == 0 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
-                        Color = 0
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 255):
-                        Color = 1
-                    elif (pixels[x, y][0] == 0 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
-                        Color = 2
-                    elif (pixels[x, y][0] == 0 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 255):
-                        Color = 3
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
-                        Color = 4
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
-                        Color = 5
-                    elif (pixels[x, y][0] == 255 and  pixels[x, y][1] == 128 and pixels[x, y][2] == 0):
-                        Color = 6
-                    
-                    data_t = buf[Add]&(~(0xF0 >> ((newx % 2)*4)))
-                    buf[Add] = data_t | ((Color << 4) >> ((newx % 2)*4));
+        idx = 0
+        for i in range(0, len(buf_7color), 2):
+            buf[idx] = (buf_7color[i] << 4) + buf_7color[i+1]
+            idx += 1
+
         return buf
 
     def display(self,image):
-        self.send_command(0x61)#Set Resolution setting
+        self.send_command(0x61) #Set Resolution setting
         self.send_data(0x02)
         self.send_data(0x58)
         self.send_data(0x01)
         self.send_data(0xC0)
         self.send_command(0x10)
-        for i in range(0, int(EPD_HEIGHT)):
-            for j in range(0, int(EPD_WIDTH/2)):
-                self.send_data((image[j+(int(EPD_WIDTH/2)*i)]))
-        self.send_command(0x04)#0x04
+
+        self.send_data_bulk(image)
+        self.send_command(0x04) #0x04
         self.ReadBusyHigh()
-        self.send_command(0x12)#0x12
+        self.send_command(0x12) #0x12
         self.ReadBusyHigh()
-        self.send_command(0x02)  #0x02
+        self.send_command(0x02) #0x02
         self.ReadBusyLow()
         epdconfig.delay_ms(500)
-        
+
     def Clear(self):
-        self.send_command(0x61)#Set Resolution setting
+        self.send_command(0x61) #Set Resolution setting
         self.send_data(0x02)
         self.send_data(0x58)
         self.send_data(0x01)
         self.send_data(0xC0)
         self.send_command(0x10)
-        for i in range(0, int(EPD_HEIGHT)):
-            for j in range(0, int(EPD_WIDTH/2)):
-                self.send_data(0x11)
-        #BLACK   0x00    /// 0000
-        #WHITE   0x11    /// 0001
-        #GREEN   0x22    /// 0010
-        #BLUE    0x33    /// 0011
-        #RED     0x44    /// 0100
-        #YELLOW  0x55    /// 0101
-        #ORANGE  0x66    /// 0110
-        #CLEAN   0x77    /// 0111   unavailable  Afterimage
-        self.send_command(0x04)#0x04
+
+        # Set all pixels to white
+        buf = [0x11] * int(self.width * self.height / 2)
+        self.send_data_bulk(buf)
+
+        self.send_command(0x04) #0x04
         self.ReadBusyHigh()
-        self.send_command(0x12)#0x12
+        self.send_command(0x12) #0x12
         self.ReadBusyHigh()
-        self.send_command(0x02)  #0x02
+        self.send_command(0x02) #0x02
         self.ReadBusyLow()
         epdconfig.delay_ms(500)
 
@@ -236,5 +202,4 @@ class EPD:
         epdconfig.digital_write(self.reset_pin, 0)
 
         epdconfig.delay_ms(2000)
-        epdconfig.module_exit() 
-        
+        epdconfig.module_exit()