-
Notifications
You must be signed in to change notification settings - Fork 0
/
disply_lib.py
134 lines (109 loc) · 4.11 KB
/
disply_lib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import threading
from concurrent.futures import ThreadPoolExecutor
import board
import digitalio
from adafruit_rgb_display import ili9341
from icecream.icecream import IceCreamDebugger
from PIL import Image, ImageDraw, ImageFont
ic = IceCreamDebugger()
FONT_PATH = './DejaVuSans.ttf'
class DisplayController:
def __init__(self):
self.BORDER = 10
self.BAUDRATE = 24000000
self.FOREGROUND_FONT_COLOR = (0, 0, 0)
self.rotation = 90 # Modify this if needed
self.initialize_display()
self.initialize_image()
self.font = ImageFont.truetype(FONT_PATH, size=18)
def initialize_display(self):
cs_pin = digitalio.DigitalInOut(board.CE0)
dc_pin = digitalio.DigitalInOut(board.D25)
reset_pin = digitalio.DigitalInOut(board.D24)
spi = board.SPI()
self.disp = ili9341.ILI9341(
spi,
rotation=self.rotation,
cs=cs_pin,
dc=dc_pin,
rst=reset_pin,
baudrate=self.BAUDRATE,
)
if self.disp.rotation % 180 == 90:
self.height = self.disp.width
self.width = self.disp.height
else:
self.width = self.disp.width
self.height = self.disp.height
def initialize_image(self):
self.image = Image.new("RGB", (self.width, self.height))
self.draw = ImageDraw.Draw(self.image)
self.draw.rectangle((0, 0, self.width, self.height), fill=self.FOREGROUND_FONT_COLOR)
self.disp.image(self.image)
def render_text(self, text):
(x, y, font_width, font_height) = self.font.getbbox(text)
x_pos = self.BORDER
y_pos = self.BORDER
self.clear_screen()
self.draw_text(text, (x_pos, y_pos), (255, 255, 255))
self.display_image()
def render_text_threaded_v2(self, text):
# with ThreadPoolExecutor() as executor:
# future = executor.submit(self.render_text, text)
# future.result()
# pass
self.render_text(text),
def render_text_threaded(self, text):
thread = threading.Thread(target=self.render_text, args=(text,))
thread.daemon = True
thread.start()
def add_newlines_v2(self, text):
lines = []
while len(text) > 25:
last_space = text[:25].rfind(' ')
if last_space == -1:
lines.append(text[:25])
text = text[25:]
else:
lines.append(text[:last_space])
text = text[last_space+1:]
lines.append(text)
return '\n'.join(lines)
def add_newlines(self, text):
lines = []
while text:
if len(text) <= 25:
lines.append(text)
break
else:
# Find the last space within the first 25 characters
last_space = text[:25].rfind(' ')
if last_space == -1:
# If no space is found, split at exactly 25 characters
lines.append(text[:25])
text = text[25:]
else:
# Split at the last space within the first 25 characters
lines.append(text[:last_space])
text = text[last_space+1:]
return '\n'.join(lines)
def draw_text(self, text, position, fill):
ic(f"Drawing text {text}")
lines = self.add_newlines_v2(text).split("\n")
y = position[1]
for line in lines:
self.draw.text((position[0], y), line, font=self.font, fill=fill)
y = y+20
def clear_screen(self):
self.draw.rectangle((0, 0, self.width, self.height), fill=self.FOREGROUND_FONT_COLOR)
self.disp.image(self.image)
def display_image(self):
self.disp.image(self.image)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Control the OLED display.")
parser.add_argument("--text", type=str, help="Text to display on the OLED.")
args = parser.parse_args()
display = DisplayController()
if args.text:
display.render_text(args.text)