Seeed Xiao Round Display in CircuitPython

I’ve managed to use this beautifull board with my Seeed XIAO RP2040.

Still looking for correct I2C Touch device name (appears to be CST816S with I2C address of 0x2E, but I am not sure yet).

The library for touch device could be installed using
circup install adafruit_cst8xx

Using todbot examples at: GitHub - todbot/CircuitPython_GC9A01_demos: Demos showing how to use CircuitPython displayio driver for GC9A01 round LCDs and change the pinout and new displayio method (for Circuitpython 9.x):

import time, math, random
import board, busio
import displayio
import adafruit_imageload
import gc9a01

# This need to be changed
tft_dc  = board.D3
tft_cs  = board.D1
tft_bl  = board.D6

# The touch int pin. Not used here...
touch_int = board.D7

spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI)

# load our eye and iris bitmaps
dw, dh = 240,240  # display dimensions
eyeball_bitmap, eyeball_pal = adafruit_imageload.load("imgs/eye0_ball2.bmp")
iris_bitmap, iris_pal = adafruit_imageload.load("imgs/eye0_iris0.bmp")
iris_pal.make_transparent(0)

# compute or declare some useful info about the eyes
iris_w, iris_h = iris_bitmap.width, iris_bitmap.height  # iris is normally 110x110
iris_cx, iris_cy = dw//2 - iris_w//2, dh//2 - iris_h//2
r = 25  # allowable deviation from center for iris

# class to help us track eye info (not needed for this use exactly, but I find it interesting)
class Eye:
    def __init__(self, spi, dc, cs, rot=0, eye_speed=0.3, twitch=2):
        display_bus = displayio.FourWire(spi, command=dc, chip_select=cs)
        display = gc9a01.GC9A01(display_bus, width=dw, height=dh, rotation=rot)
        main = displayio.Group()
        # This is the new way to show something in display
        display.root_group = main
        self.display = display
        self.eyeball = displayio.TileGrid(eyeball_bitmap, pixel_shader=eyeball_pal)
        self.iris = displayio.TileGrid(iris_bitmap, pixel_shader=iris_pal, x=iris_cx,y=iris_cy)
        main.append(self.eyeball)
        main.append(self.iris)
        self.x, self.y = iris_cx, iris_cy
        self.tx, self.ty = self.x, self.y
        self.next_time = time.monotonic()
        self.eye_speed = eye_speed
        self.twitch = twitch

    def update(self):
        self.x = self.x * (1-self.eye_speed) + self.tx * self.eye_speed # "easing"
        self.y = self.y * (1-self.eye_speed) + self.ty * self.eye_speed
        self.iris.x = int( self.x )
        self.iris.y = int( self.y )
        if time.monotonic() > self.next_time:
            t = random.uniform(0.25,self.twitch)
            self.next_time = time.monotonic() + t
            self.tx = iris_cx + random.uniform(-r,r)
            self.ty = iris_cy + random.uniform(-r,r) 
        self.display.refresh()

# a list of all the eyes, in this case, only one
the_eyes = [
    Eye( spi, tft_dc, tft_cs,  rot=0),
]

while True:
    for eye in the_eyes:
        eye.update()
1 Like

Thank you for your sharing!

which PINs would be needed for a XIAO ESP32C3?

i tried the pins as written in the .xls but cannot get it working.

okay, i have to admit that i’m very confused because of different naming/sayings. either, in the datasheets as well as in different tutorials

is there a working example with said setup? (Circuitpython, esp32c3, round display) ?

Hi there,
So I see this allot , seems it works if you use the GPIO Number in place of the Pin name or physical pin number.
for example: To use the A0 or D0 pin in your code, You address it as GPIO2.


If your using some serial LIB in there, then GPIO21, GPIO20 would be used for TXD(D6) and RXD(D7).
Talk about cheap, No user LED, C’mon Seeed …:wink: so that too would be by the GPIO Number it is assigned too.

HTH
GL :slight_smile: PJ :v:

See here,

Hi,
Regarding the XIAO ESP32C3 and ESP32C6 (using CircuitPython beta versions from S3), I use the code below I wrote based on my personal researches here and there.
There is still an issue on how to release pin board.D3. I will update this message if fixed some day! :slight_smile:

round_display.py:

import board
import busio
import displayio
import gc9a01

# Round Display constants:                                                                                                                              
ROUND_ROUND_WIDTH  = 240
ROUND_ROUND_HEIGHT = 240

# Board pins:                                                                                                                                           
ROUND_DISPLAY_TFT_CS   = board.D1  # LCD_CS                                                                                                             
ROUND_DISPLAY_TFT_DC   = board.D3  # LCD_DC                                                                                                             
ROUND_DISPLAY_TFT_BL   = board.D6  # Note: Backlight, can't be changed on the Round Display                                                             
ROUND_DISPLAY_TFT_CLK  = board.D8  # Aka board.SCK                                                                                                      
ROUND_DISPLAY_SD_MISO  = board.D9  # Aka board.MISO, for SPI read/write devices (eg, SDCard)                                                            
ROUND_DISPLAY_TFT_MOSI = board.D10 # Aka board.MOSI, for SPI read only devices (eg, Display)                                                            


def display_init():
    spi_bus = busio.SPI(
        clock=ROUND_DISPLAY_TFT_CLK, MOSI=ROUND_DISPLAY_TFT_MOSI,
    )
    display_conn = displayio.FourWire(
        spi_bus,
        command=ROUND_DISPLAY_TFT_DC, chip_select=ROUND_DISPLAY_TFT_CS,
    )
    display = gc9a01.GC9A01(
        display_conn, rotation=0,
        width=ROUND_ROUND_WIDTH, height=ROUND_ROUND_HEIGHT,
    )
    return spi_bus, display_conn, display


def display_deinit(spi_bus, display_conn, display):
    spi_bus.deinit()
    # Don't know yet how to release board.D3 used by display_conn

Would you please fix the hardware name above (should be CHSC6X) as it sound wrong regarding what you wrote one day after on this topic.

hi, i dunno if there’s still a “release” problem.

but I hope you remember to call “release_displays()”

I just wanted to thank you, you brought on the right path to get this working, back then. if you allow I would mention you in my upcoming cookbook/tutorial collection, I’m working on

Best Regards Boones

Thank you for the reply.
Actually, yes, the solution was to call release_displays() before using the screen.
(Of course this can also work if you call it after (during your resource releasing stage) since a post-operation for iteration n would be a pre-operation for iteration n+1.)