Merge pull request from python273/add-non-blocking-screen-updating

Add non blocking display updating
This commit is contained in:
evilsocket 2019-10-23 12:52:02 +02:00 committed by GitHub
commit 7779ebc983
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 17 deletions
pwnagotchi/ui
display.py
hw/libs/waveshare/v1

@ -1,7 +1,8 @@
import os import os
import logging import logging
import pwnagotchi.plugins as plugins import threading
import pwnagotchi.plugins as plugins
import pwnagotchi.ui.hw as hw import pwnagotchi.ui.hw as hw
import pwnagotchi.ui.web as web import pwnagotchi.ui.web as web
from pwnagotchi.ui.view import View from pwnagotchi.ui.view import View
@ -18,6 +19,14 @@ class Display(View):
self.init_display() self.init_display()
self._canvas_next_event = threading.Event()
self._canvas_next = None
self._render_thread_instance = threading.Thread(
target=self._render_thread,
daemon=True
)
self._render_thread_instance.start()
def is_inky(self): def is_inky(self):
return self._implementation.name == 'inky' return self._implementation.name == 'inky'
@ -59,6 +68,14 @@ class Display(View):
img = self._canvas if self._rotation == 0 else self._canvas.rotate(-self._rotation) img = self._canvas if self._rotation == 0 else self._canvas.rotate(-self._rotation)
return img return img
def _render_thread(self):
"""Used for non-blocking screen updating."""
while True:
self._canvas_next_event.wait()
self._canvas_next_event.clear()
self._implementation.render(self._canvas_next)
def _on_view_rendered(self, img): def _on_view_rendered(self, img):
web.update_frame(img) web.update_frame(img)
try: try:
@ -70,4 +87,5 @@ class Display(View):
if self._enabled: if self._enabled:
self._canvas = (img if self._rotation == 0 else img.rotate(self._rotation)) self._canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
if self._implementation is not None: if self._implementation is not None:
self._implementation.render(self._canvas) self._canvas_next = self._canvas
self._canvas_next_event.set()

@ -47,11 +47,11 @@ class EPD:
# Hardware reset # Hardware reset
def reset(self): def reset(self):
epdconfig.digital_write(self.reset_pin, GPIO.HIGH) epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
epdconfig.delay_ms(200) epdconfig.delay_ms(200)
epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset
epdconfig.delay_ms(200) epdconfig.delay_ms(200)
epdconfig.digital_write(self.reset_pin, GPIO.HIGH) epdconfig.digital_write(self.reset_pin, GPIO.HIGH)
epdconfig.delay_ms(200) epdconfig.delay_ms(200)
def send_command(self, command): def send_command(self, command):
epdconfig.digital_write(self.dc_pin, GPIO.LOW) epdconfig.digital_write(self.dc_pin, GPIO.LOW)
@ -64,8 +64,9 @@ class EPD:
epdconfig.digital_write(self.cs_pin, GPIO.LOW) epdconfig.digital_write(self.cs_pin, GPIO.LOW)
epdconfig.spi_writebyte([data]) epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, GPIO.HIGH) epdconfig.digital_write(self.cs_pin, GPIO.HIGH)
def ReadBusy(self): def ReadBusy(self):
epdconfig.delay_ms(20)
while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
epdconfig.delay_ms(100) epdconfig.delay_ms(100)
@ -79,16 +80,16 @@ class EPD:
self.send_data(0x17) self.send_data(0x17)
self.send_data(0x17) self.send_data(0x17)
self.send_data(0x17) self.send_data(0x17)
self.send_command(0x04) # POWER_ON self.send_command(0x04) # POWER_ON
self.ReadBusy() self.ReadBusy()
self.send_command(0x00) # PANEL_SETTING self.send_command(0x00) # PANEL_SETTING
self.send_data(0x8F) self.send_data(0x8F)
self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
self.send_data(0xF0) self.send_data(0xF0)
self.send_command(0x61) # RESOLUTION_SETTING self.send_command(0x61) # RESOLUTION_SETTING
self.send_data(self.width & 0xff) self.send_data(self.width & 0xff)
self.send_data(self.height >> 8) self.send_data(self.height >> 8)
@ -120,7 +121,7 @@ class EPD:
for i in range(0, int(self.width * self.height / 8)): for i in range(0, int(self.width * self.height / 8)):
self.send_data(imageblack[i]) self.send_data(imageblack[i])
self.send_command(0x92) self.send_command(0x92)
self.send_command(0x12) # REFRESH self.send_command(0x12) # REFRESH
self.ReadBusy() self.ReadBusy()
@ -129,26 +130,26 @@ class EPD:
for i in range(0, int(self.width * self.height / 8)): for i in range(0, int(self.width * self.height / 8)):
self.send_data(imageblack[i]) self.send_data(imageblack[i])
self.send_command(0x92) self.send_command(0x92)
self.send_command(0x13) self.send_command(0x13)
for i in range(0, int(self.width * self.height / 8)): for i in range(0, int(self.width * self.height / 8)):
self.send_data(imagecolor[i]) self.send_data(imagecolor[i])
self.send_command(0x92) self.send_command(0x92)
self.send_command(0x12) # REFRESH self.send_command(0x12) # REFRESH
self.ReadBusy() self.ReadBusy()
def Clear(self): def Clear(self):
self.send_command(0x10) self.send_command(0x10)
for i in range(0, int(self.width * self.height / 8)): for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF) self.send_data(0xFF)
self.send_command(0x92) self.send_command(0x92)
self.send_command(0x13) self.send_command(0x13)
for i in range(0, int(self.width * self.height / 8)): for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF) self.send_data(0xFF)
self.send_command(0x92) self.send_command(0x92)
self.send_command(0x12) # REFRESH self.send_command(0x12) # REFRESH
self.ReadBusy() self.ReadBusy()
@ -157,7 +158,7 @@ class EPD:
self.ReadBusy() self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5) # check code self.send_data(0xA5) # check code
# epdconfig.module_exit() # epdconfig.module_exit()
### END OF FILE ### ### END OF FILE ###