Skip to content

Commit 1feedb5

Browse files
committed
Add example for multicolor-epaper
1 parent 0aa01e1 commit 1feedb5

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed

example/multicolor-epaper.py

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
import time
2+
from boards.xiao import XiaoPin, XiaoSPI
3+
4+
# GDEY0213F51 2.13" 4-color ePaper Display Driver
5+
# Screen Resolution: 128x250 pixels (2-bit per pixel for 4 colors)
6+
7+
# Pin configuration (same as epaper.py)
8+
RST = 0 # D0
9+
CS = 1 # D1
10+
DC = 3 # D3
11+
BUSY = 5 # D5
12+
sck = 9 # D9
13+
mosi = 10 # D10
14+
miso = 8 # D8
15+
spi = "spi0"
16+
17+
# Screen parameters
18+
SOURCE_BITS = 128
19+
GATE_BITS = 250
20+
ALLSCREEN_BYTES = SOURCE_BITS * GATE_BITS // 4 # 2-bit per pixel = 4 pixels per byte
21+
22+
# Color definitions (2-bit)
23+
BLACK = 0x00 # 00
24+
WHITE = 0x01 # 01
25+
YELLOW = 0x02 # 10
26+
RED = 0x03 # 11
27+
28+
# Hardware configuration
29+
RST = XiaoPin(RST, XiaoPin.OUT)
30+
CS = XiaoPin(CS, XiaoPin.OUT)
31+
DC = XiaoPin(DC, XiaoPin.OUT)
32+
BUSY = XiaoPin(BUSY, XiaoPin.IN, XiaoPin.PULL_UP)
33+
spi = XiaoSPI(spi, 10000000, sck, mosi, miso)
34+
35+
# Reset the display
36+
def reset():
37+
RST.value(0)
38+
time.sleep_ms(40) # At least 40ms delay
39+
RST.value(1)
40+
time.sleep_ms(50) # At least 50ms delay
41+
42+
# Send command
43+
def send_command(command):
44+
DC.value(0)
45+
CS.value(0)
46+
spi.write(bytearray([command]))
47+
CS.value(1)
48+
49+
# Send data
50+
def send_data(data):
51+
DC.value(1)
52+
CS.value(0)
53+
if isinstance(data, int):
54+
spi.write(bytearray([data]))
55+
else:
56+
spi.write(data)
57+
CS.value(1)
58+
59+
# Wait until the display is idle (BUSY=1 means idle)
60+
def wait_until_idle():
61+
# while BUSY.value() == 0: # Wait while BUSY is LOW
62+
time.sleep_ms(1)
63+
64+
# Simple 8x8 font for ASCII characters (32-127)
65+
FONT_8X8 = {
66+
'H': [0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x00],
67+
'e': [0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x00],
68+
'l': [0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00],
69+
'o': [0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00],
70+
' ': [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
71+
'W': [0x7F, 0x20, 0x18, 0x20, 0x7F, 0x00, 0x00, 0x00],
72+
'r': [0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00],
73+
'd': [0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, 0x00, 0x00],
74+
}
75+
76+
# Set a pixel in the frame buffer with the given color (2-bit)
77+
def set_pixel_in_buffer(buffer, x, y, color):
78+
if x < 0 or x >= SOURCE_BITS or y < 0 or y >= GATE_BITS:
79+
return
80+
81+
byte_index = (y * SOURCE_BITS + x) // 4
82+
pixel_pos = (y * SOURCE_BITS + x) % 4
83+
shift = (3 - pixel_pos) * 2
84+
85+
# Clear the 2 bits for this pixel
86+
buffer[byte_index] &= ~(0x03 << shift)
87+
# Set the new color
88+
buffer[byte_index] |= (color & 0x03) << shift
89+
90+
# Draw a character at position (x, y) with the given color
91+
def draw_char(buffer, x, y, char, color):
92+
if char not in FONT_8X8:
93+
return x + 8
94+
95+
font_data = FONT_8X8[char]
96+
for row in range(8):
97+
byte_data = font_data[row]
98+
for col in range(8):
99+
if byte_data & (0x80 >> col):
100+
set_pixel_in_buffer(buffer, x + (7 - col), y + (7 - row), color) # Flip horizontally only
101+
102+
return x + 8 # Return next x position
103+
104+
# Draw text string at position (x, y) with the given color
105+
def draw_text(buffer, x, y, text, color):
106+
current_x = x
107+
for char in text:
108+
current_x = draw_char(buffer, current_x, y, char, color)
109+
return current_x
110+
111+
# Initialize the display (based on Arduino EPD_init)
112+
def init_display():
113+
time.sleep_ms(20) # At least 20ms delay
114+
reset()
115+
116+
wait_until_idle()
117+
118+
send_command(0x4D)
119+
send_data(0x78)
120+
121+
send_command(0x00) # PSR
122+
send_data(0x0F)
123+
send_data(0x29)
124+
125+
send_command(0x01) # PWRR
126+
send_data(0x07)
127+
send_data(0x00)
128+
129+
send_command(0x03) # POFS
130+
send_data(0x10)
131+
send_data(0x54)
132+
send_data(0x44)
133+
134+
send_command(0x06) # BTST_P
135+
send_data(0x05)
136+
send_data(0x00)
137+
send_data(0x3F)
138+
send_data(0x0A)
139+
send_data(0x25)
140+
send_data(0x12)
141+
send_data(0x1A)
142+
143+
send_command(0x50) # CDI
144+
send_data(0x37)
145+
146+
send_command(0x60) # TCON
147+
send_data(0x02)
148+
send_data(0x02)
149+
150+
send_command(0x61) # TRES (Resolution)
151+
send_data(SOURCE_BITS >> 8) # Source_BITS_H
152+
send_data(SOURCE_BITS & 0xFF) # Source_BITS_L
153+
send_data(GATE_BITS >> 8) # Gate_BITS_H
154+
send_data(GATE_BITS & 0xFF) # Gate_BITS_L
155+
156+
send_command(0xE7)
157+
send_data(0x1C)
158+
159+
send_command(0xE3)
160+
send_data(0x22)
161+
162+
send_command(0xB4)
163+
send_data(0xD0)
164+
165+
send_command(0xB5)
166+
send_data(0x03)
167+
168+
send_command(0xE9)
169+
send_data(0x01)
170+
171+
send_command(0x30)
172+
send_data(0x08)
173+
174+
send_command(0x04) # Power on
175+
wait_until_idle()
176+
177+
# Refresh display
178+
def refresh():
179+
send_command(0x12) # Display Update Control
180+
send_data(0x00)
181+
wait_until_idle()
182+
183+
# Clear screen to white
184+
def clear_screen_white():
185+
send_command(0x10) # Write to RAM
186+
187+
# For 4-color display, white = 0x01 (01 in binary)
188+
# 4 pixels per byte: 0x55 = 01010101 = white, white, white, white
189+
white_byte = 0x55
190+
191+
for i in range(ALLSCREEN_BYTES):
192+
send_data(white_byte)
193+
194+
# Refresh the display
195+
refresh()
196+
197+
# Display buffer
198+
def display_buffer(buffer):
199+
send_command(0x10) # Write to RAM
200+
201+
for byte_data in buffer:
202+
send_data(byte_data)
203+
204+
# Refresh the display
205+
refresh()
206+
207+
# Create a frame buffer initialized with white color
208+
def create_frame_buffer():
209+
buffer = bytearray(ALLSCREEN_BYTES)
210+
for i in range(ALLSCREEN_BYTES):
211+
buffer[i] = 0x55 # All white pixels
212+
return buffer
213+
214+
def sleep():
215+
send_command(0x02) # Power off
216+
send_data(0x00)
217+
wait_until_idle()
218+
219+
send_command(0x07) # Deep sleep
220+
send_data(0xA5)
221+
222+
# Main execution
223+
try:
224+
print("Initializing 2.13\" 4-color ePaper display...")
225+
init_display()
226+
227+
print("Creating frame buffer...")
228+
buffer = create_frame_buffer()
229+
230+
print("Drawing 'Hello World' in different colors...")
231+
# Display "Hello World" in different colors from top to bottom
232+
draw_text(buffer, 10, 80, "Hello World", BLACK) # Black
233+
draw_text(buffer, 10, 120, "Hello World", YELLOW) # Yellow
234+
draw_text(buffer, 10, 160, "Hello World", RED) # Red
235+
draw_text(buffer, 10, 200, "Hello World", BLACK) # Black again
236+
237+
print("Displaying image...")
238+
display_buffer(buffer)
239+
240+
print("Display complete!")
241+
242+
print("Putting display to sleep...")
243+
sleep()
244+
245+
print("Done!")
246+
except KeyboardInterrupt:
247+
print("\nProgram interrupted by user")
248+
except Exception as e:
249+
print("Error occurred: %s" % str(e))
250+
251+

0 commit comments

Comments
 (0)