1.28" 240x240 Round Display with GC9A01 SPI, on Raspberry Pi Pico 2 W.
Exercises run on Raspberry Pi Pico 2 W/CircuitPython 10.0.3, to display on 1.28 inch IPS Module: GC9A01+CST816S 240*240(Round) 4W-SPI.
Connection:
Code:
cpy_rpPicoW_gc9a01_color.py, basic color test.
cpy_rpPicoW_gc9a01_circle_scene.py, draw something circles.
cpy_rpPicoW_gc9a01_heart.py, display beating heart.
Connection:
Raspberry Pi Pico 2 W
Run |
GP22| ------- LCD_BLK ------------+
GND | |
GP21| ------- LCD_DC ---------+ |
GP20| ------- LCD_RES-------+ | |
GP19| MOSI - SPI_SDA ----+ | | |
GP18| SCK - SPI_SCL --+ | | | |
GND | | | | | |
GP17| SS - LCD_CS ---|-|-|-|-+ |
GP16| MISO - no use | | | | | |
--------+ | | | | | |
| | | | | |
| | | | | | GC9A01
| | | | | |
| | | | | +---- BLK
| | | | +------ CS
| | | +-------- DC
| | +---------- RES
| +------------ SDA
+-------------- SCL
3V3 --- VCC
GND --- GND
Code:
cpy_rpPicoW_gc9a01_color.py, basic color test.
"""
Raspberry Pi Pico 2 W/CircuitPython 10.0.3
with 1.28" 240x240 Round GC9A01 SPI IPS LCD
Basic Color Test
details:
https://coxxect.blogspot.com/2026/01/128-240x240-round-display-with-gc9a01.html
Library needed:
- adafruit_gc9a01a.mpy
- adafruit_display_text folder
"""
import os, sys
import board
import time
import displayio
import busio
import terminalio
import adafruit_gc9a01a
from fourwire import FourWire
from adafruit_display_text import label
displayio.release_displays()
tft_blk = board.GP22
tft_cs = board.GP17
tft_dc = board.GP21
tft_res = board.GP20
tft_sda = board.GP19
tft_scl = board.GP18
# Release any resources currently in use for the displays
displayio.release_displays()
disp_spi = busio.SPI(clock=tft_scl, MOSI=tft_sda)
display_bus = FourWire(spi_bus=disp_spi,
command=tft_dc,
chip_select=tft_cs,
reset=tft_res)
display = adafruit_gc9a01a.GC9A01A(display_bus, width=240, height=240, backlight_pin=tft_blk)
#=======================================
info = os.uname()[4] + "\n" + \
sys.implementation[0] + " " + os.uname()[3] + "\n" + \
adafruit_gc9a01a.__name__ + " " + adafruit_gc9a01a.__version__
print("=======================================")
print(info)
print("=======================================")
print()
# Make the display context
bgGroup = displayio.Group()
#display.show(bgGroup)
display.root_group = bgGroup
colorSet = ((0xFF0000, "RED"),
(0x00FF00, "GREEN"),
(0x0000FF, "BLUE"),
(0xFFFFFF, "WHITE"),
(0x000000, "BLACK"))
color_bitmap = displayio.Bitmap(display.width, display.height, 1) # with one color
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000 # BLACK
color_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
bgGroup.append(color_sprite)
# Draw label
text_group = displayio.Group(scale=1, x=20, y=120)
text_area = label.Label(terminalio.FONT, text=info, color=0xFFFFFF)
text_group.append(text_area) # Subgroup for text scaling
bgGroup.append(text_group)
time.sleep(3)
text_group.scale = 2
time.sleep(2)
text_group.scale = 3
time.sleep(2)
while True:
for i in colorSet:
color_palette[0] = i[0]
text_area.text = i[1]
text_area.color = i[0] ^ 0xFFFFFF
time.sleep(3)
cpy_rpPicoW_gc9a01_circle_scene.py, draw something circles.
"""
Raspberry Pi Pico 2 W/CircuitPython 10.0.3
with 1.28" 240x240 Round GC9A01 SPI IPS LCD
Draw something (concentric circles, rainbow wheel, spiral illusion),
also show how to switch between scenes (bgGroup and group), by calling show_scene().
details:
https://coxxect.blogspot.com/2026/01/128-240x240-round-display-with-gc9a01.html
Library needed:
- adafruit_gc9a01a.mpy
- adafruit_display_text folder
"""
import os, sys
import board
import time
import displayio
import busio
import terminalio
import adafruit_gc9a01a
from fourwire import FourWire
from adafruit_display_text import label
import math
displayio.release_displays()
tft_blk = board.GP22
tft_cs = board.GP17
tft_dc = board.GP21
tft_res = board.GP20
tft_sda = board.GP19
tft_scl = board.GP18
# Release any resources currently in use for the displays
displayio.release_displays()
disp_spi = busio.SPI(clock=tft_scl, MOSI=tft_sda)
display_bus = FourWire(spi_bus=disp_spi,
command=tft_dc,
chip_select=tft_cs,
reset=tft_res)
display = adafruit_gc9a01a.GC9A01A(display_bus, width=240, height=240, backlight_pin=tft_blk)
#=======================================
info = os.uname()[4] + "\n" + \
sys.implementation[0] + " " + os.uname()[3] + "\n" + \
adafruit_gc9a01a.__name__ + " " + adafruit_gc9a01a.__version__
print("=======================================")
print(info)
print("=======================================")
print()
# Group to display Title
bgGroup = displayio.Group()
color_bitmap = displayio.Bitmap(display.width, display.height, 1) # with one color
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000 # BLACK
color_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
bgGroup.append(color_sprite)
# Draw label
text_group = displayio.Group(scale=1, x=20, y=120)
text_area = label.Label(terminalio.FONT, text=info, color=0xFFFFFF)
text_group.append(text_area) # Subgroup for text scaling
bgGroup.append(text_group)
# Group to display Bitmap
bitmap = displayio.Bitmap(240, 240, 256)
palette = displayio.Palette(256)
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)
# Used to switch whole root_group, between bgGroup and group
def show_scene(scene_group):
display.root_group = scene_group
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
# clear palette all to black
def clear_palette():
for i in range(0, 256):
palette[i] = (0, 0, 0)
def fill_palette_red():
palette[0] = (0, 0, 0)
for i in range(1, 256):
palette[i] = (i, 255-i, 255-i)
def fill_palette_green():
palette[0] = (0, 0, 0)
for i in range(1, 256):
palette[i] = (255-i, i, 255-i)
def fill_palette_blue():
palette[0] = (0, 0, 0)
for i in range(1, 256):
palette[i] = (255-i, 255-i, 255)
def fill_palette_white():
palette[0] = (0, 0, 0)
for i in range(1, 256):
palette[i] = (i, i, i)
def fill_palette_black():
palette[0] = (0, 0, 0)
for i in range(1, 256):
palette[i] = (255-i, 255-i, 255-i)
def change_palette():
fill_palette_red()
time.sleep(2)
fill_palette_green()
time.sleep(2)
fill_palette_blue()
time.sleep(2)
fill_palette_white()
time.sleep(2)
fill_palette_black()
time.sleep(2)
def draw_concentric_circles():
text_group.scale = 1
text_area.text = "concentric\ncircles"
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
clear_palette()
bitmap.fill(0)
for r in range(10, 120, 5):
color = (r*2) % 255
for angle in range(0, 360, 1):
angle_radians = math.radians(angle)
x = int(120 + r * (math.cos(angle_radians)))
y = int(120 + r * (math.sin(angle_radians)))
if 0 <= x < 240 and 0 <= y < 240:
bitmap[x, y] = color
change_palette()
def draw_rainbow_wheel():
text_group.scale = 2
text_area.text = "rainbow\nwheel"
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
clear_palette()
bitmap.fill(0)
for angle in range(0, 360, 5):
# Because palette[0]=Black, so map 0~359(angle) to 1~255(color)
color = 1 + int(angle * 254 / 359)
for r in range(20, 120):
x = int(120 + r * math.cos(math.radians(angle)))
y = int(120 + r * math.sin(math.radians(angle)))
if 0 <= x < 240 and 0 <= y < 240:
bitmap[x, y] = color
change_palette()
def draw_spiral_illusion():
text_group.scale = 3
text_area.text = "spiral\nillusion"
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
clear_palette()
bitmap.fill(0)
palette[0] = 0x000000 # Black
palette[1] = 0xFFFFFF # White
for s in range(4, 9, 1):
do_spiral_illusion(step=s)
time.sleep(2)
def do_spiral_illusion(step=5):
bitmap.fill(0)
for angle in range(0, 360, step):
for r in range(20, 120, step):
x = int(120 + r * math.cos(math.radians(angle)))
y = int(120 + r * math.sin(math.radians(angle)))
if 0 <= x < 240 and 0 <= y < 240:
bitmap[x, y] = ((r//step + angle//step) % 2)
while True:
draw_concentric_circles()
draw_rainbow_wheel()
draw_spiral_illusion()
cpy_rpPicoW_gc9a01_heart.py, display beating heart.
"""
Raspberry Pi Pico 2 W/CircuitPython 10.0.3
with 1.28" 240x240 Round GC9A01 SPI IPS LCD
Draw beating heart, switch between two bitmaps to prevent flicker problem.
details:
https://coxxect.blogspot.com/2026/01/128-240x240-round-display-with-gc9a01.html
Library needed:
- adafruit_gc9a01a.mpy
- adafruit_display_text folder
"""
import os, sys
import board
import time
import displayio
import busio
import terminalio
import adafruit_gc9a01a
from fourwire import FourWire
from adafruit_display_text import label
import math
displayio.release_displays()
tft_blk = board.GP22
tft_cs = board.GP17
tft_dc = board.GP21
tft_res = board.GP20
tft_sda = board.GP19
tft_scl = board.GP18
# Release any resources currently in use for the displays
displayio.release_displays()
disp_spi = busio.SPI(clock=tft_scl, MOSI=tft_sda)
display_bus = FourWire(spi_bus=disp_spi,
command=tft_dc,
chip_select=tft_cs,
reset=tft_res)
display = adafruit_gc9a01a.GC9A01A(display_bus, width=240, height=240, backlight_pin=tft_blk)
#=======================================
info = os.uname()[4] + "\n" + \
sys.implementation[0] + " " + os.uname()[3] + "\n" + \
adafruit_gc9a01a.__name__ + " " + adafruit_gc9a01a.__version__
print("=======================================")
print(info)
print("=======================================")
print()
# Group to display Title
bgGroup = displayio.Group()
color_bitmap = displayio.Bitmap(display.width, display.height, 1) # with one color
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000 # BLACK
color_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
bgGroup.append(color_sprite)
# Draw label
text_group = displayio.Group(scale=1, x=20, y=120)
text_area = label.Label(terminalio.FONT, text=info, color=0xFFFFFF)
text_group.append(text_area) # Subgroup for text scaling
bgGroup.append(text_group)
# Group to display Bitmap
# two bitmaps, same palette
bitmap_a = displayio.Bitmap(240, 240, 2)
bitmap_b = displayio.Bitmap(240, 240, 2)
palette = displayio.Palette(2)
palette[0] = 0x000000 # Black
palette[1] = 0xFF0000 # Red
tile_grid = displayio.TileGrid(bitmap_a, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)
# Used to switch whole root_group, between bgGroup and group
def show_scene(scene_group):
display.root_group = scene_group
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
WIDTH = display.width
HEIGHT = display.height
CENTER_X = WIDTH//2
CENTER_Y = HEIGHT//2
# parameter to calculate scale
heart_size = 5
beating_amplitude = 1
beating_speed = 2
def to_draw_heart():
use_a = True
while True:
scale = heart_size + beating_amplitude*math.sin(time.monotonic()*beating_speed)
if use_a:
draw_heart(bitmap_a, scale)
tile_grid.bitmap = bitmap_a
else:
draw_heart(bitmap_b, scale)
tile_grid.bitmap = bitmap_b
use_a = not use_a
time.sleep(0.05)
# helper to draw heart into a bitmap
def draw_heart(bitmap, scale):
bitmap.fill(0)
for t in range(0, 360, 2):
rad = math.radians(t)
x = int(CENTER_X + scale * 16 * math.sin(rad)**3)
y = int(CENTER_Y - scale * (13*math.cos(rad)
- 5*math.cos(2*rad)
- 2*math.cos(3*rad)
- math.cos(4*rad)))
if 0 <= x < WIDTH and 0 <= y < HEIGHT:
bitmap[x, y] = 1
while True:
text_group.scale = 3
text_area.text = "Beating\nheart"
show_scene(bgGroup)
time.sleep(2)
show_scene(group)
to_draw_heart()
Comments
Post a Comment