e-Paper
e-Paper copied to clipboard
提升 python Clear() 和 display() 的性能
Python脚本在跑 Clear() 和 display() 时有严重的性能问题,CPU利用率一直位于100%,后面发现是send_data消耗大量性能。 spi_writebyte最多可以输入4096bytes
- 测试平台:Raspberry Pi Zero W
- 测试系统:ArchLinux ARM (armv6l Linux 4.19.97-1-ARCH)
- Python版本:Python 3.8.1
- 问题代码: https://github.com/waveshare/e-Paper/blob/8973995e53cb78bac6d1f8a66c2d398c18392f71/RaspberryPi%26JetsonNano/python/lib/waveshare_epd/epd5in83.py#L62-L66
- 改进方式:
加入以下代码
@@ -43,6 +43,7 @@ class EPD:
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
+ self.SPIMaxDatas = 4096
# Hardware reset
def reset(self):
@@ -64,7 +65,29 @@ class EPD:
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
-
+
+ @staticmethod
+ def _chunks(lst, n):
+ """Yield successive n-sized chunks from lst."""
+ for i in range(0, len(lst), n):
+ yield lst[i:i + n]
+
+ def _send_large_datas(self, datas):
+ for data in self._chunks(datas, self.SPIMaxDatas):
+ self._send_datas(data)
+
+ def _send_datas(self, datas):
+ epdconfig.digital_write(self.dc_pin, 1)
+ epdconfig.digital_write(self.cs_pin, 0)
+ epdconfig.spi_writebyte(datas)
+ epdconfig.digital_write(self.cs_pin, 1)
+
+ def send_datas(self, datas):
+ if len(datas) > self.SPIMaxDatas:
+ self._send_large_datas(datas)
+ else:
+ self._send_datas(datas)
修改Clear() 与 display() 中有关 send_data 的代码,改为 append 到数组
@@ -153,6 +169,7 @@ class EPD:
def display(self, image):
self.send_command(0x10)
+ senddatas = []
for i in range(0, int(self.width / 4 * self.height)):
temp1 = image[i]
j = 0
@@ -173,18 +190,16 @@ class EPD:
else:
temp2 |= 0x04
temp1 = (temp1 << 2) & 0xFF
- self.send_data(temp2)
+ senddatas.append(temp2)
j += 1
-
+ self.send_datas(senddatas)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
self.send_command(0x10)
- for i in range(0, int(self.width / 4 * self.height)):
- for j in range(0, 4):
- self.send_data(0x33)
+ self.send_datas([0x33] * int(self.width / 4 * self.height) * 4)
self.send_command(0x12)
self.ReadBusy()
测试结果
-
epd5in83_old
为 git clone的版本,epd5in83
为修改版
epd_5in83_test_old.py
中仅将epd5in83
修改为epd5in83_old
[root@rpi examples]# time python epd_5in83_test.py
INFO:root:epd5in83 Demo
INFO:root:init and Clear
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:1.Drawing on the Horizontal image...
DEBUG:root:imwidth = 600 imheight = 448
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:2.Drawing on the Vertical image...
DEBUG:root:imwidth = 448 imheight = 600
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:3.read bmp file
DEBUG:root:imwidth = 600 imheight = 448
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:4.read bmp file on window
DEBUG:root:imwidth = 448 imheight = 600
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:Clear...
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:Goto Sleep...
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:spi end
DEBUG:root:close 5V, Module enters 0 power consumption ...
real 2m2.305s
user 1m11.051s
sys 0m0.360s
[root@rpi examples]# time python epd_5in83_test_old.py
INFO:root:epd5in83 Demo
INFO:root:init and Clear
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:1.Drawing on the Horizontal image...
DEBUG:root:imwidth = 600 imheight = 448
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:2.Drawing on the Vertical image...
DEBUG:root:imwidth = 448 imheight = 600
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:3.read bmp file
DEBUG:root:imwidth = 600 imheight = 448
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:4.read bmp file on window
DEBUG:root:imwidth = 448 imheight = 600
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:Clear...
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
INFO:root:Goto Sleep...
DEBUG:root:e-Paper busy
DEBUG:root:e-Paper busy release
DEBUG:root:spi end
DEBUG:root:close 5V, Module enters 0 power consumption ...
real 6m31.419s
user 3m38.717s
sys 1m13.439s
或许可以考虑一下提升getbuffer的性能
加上 display() 和 getbuffer() 的性能优化方案
- 屏幕:5.83inch e-Paper HAT
def display(self, image):
imwidth, imheight = image.size
image_monocolor = image.convert('1')
logging.debug('imwidth = %d imheight = %d ',imwidth, imheight)
if(imwidth == self.width and imheight == self.height):
pixels = image_monocolor.getdata()
elif(imwidth == self.height and imheight == self.width):
pixels = image_monocolor.rotate(90, expand=True).getdata()
else:
pixels = image_monocolor.resize((self.width,self.height)).getdata()
buf = [ (pixels[i]>>6<<4) + (pixels[i+1]>>6) for i in range(0, len(pixels), 2)]
self.send_command(0x10)
self.send_datas(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
这个是很好的点子,等疫情过去,我到公司测试一遍
ReadBusy 耗时是由硬件决定的吗?