ESPHome and Seeed XIAO Round Display - will these work with ESPHome?

Hi there,

Just tinkering and looking to use my XIAO Round Display with HA and an ESP32-C3.

Looking at the forums it appears that the display is actually a GC9A01A and was looking to use the display platform lil9xxx module to display some basic HA sensor values.

I ma not 100% sure I understand the GPIO pins for this, even thought the documentation on the Wiki is as excellent as ever.

MY ESPhome yaml is as follows:

substitutions:

change device name to match your desired name

device_name: “display”

change room name below to the one you want to see in Home Assistant

room: “Office”

change the below to be your WiFi SSID

ssid: “xxxx”

change the below to be your WiFi password

wifi_password: “xxxx”
screenstart: ALWAYS_ON

screenstart: ALWAYS_OFF

Timeout for the screen

screensaver: 1 min
#GPIO pins for the LCD screen
dcpin: GPIO3 #checked

Note - you may see an error on compilation “WARNING GPIO2 is a Strapping PIN and should be avoided” - ignore this as you have no choice

bkpin: GPIO6 #checked
clpin: GPIO9
mopin: GPIO10 #checked
cspin: GPIO1 #checked

GPIO pins for the touch screen

sdapin: GPIO4 #checked
sclpin: GPIO5 #checked
intpin: GPIO7 #checked

esphome:
name: $device_name

esp32:
board: esp32-c3-devkitm-1
variant: esp32c3
framework:
type: esp-idf

Enable logging

logger:
level: DEBUG #makes uart stream available in esphome logstream
logs:
component: ERROR

Enable Home Assistant API

api:
encryption:
key: “xxxx”

ota:
password: “xxxx”

wifi:
ssid: $ssid
password: $wifi_password
use_address: 192.168.8.14

Enable fallback hotspot (captive portal) in case wifi connection fails

ap:
ssid: “displayap”
password: $wifi_password
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.8.14
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.8.1
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0

captive_portal:

web_server:
port: 80
version: 2
include_internal: true

spi:
clk_pin: $clpin
mosi_pin: $mopin

i2c:
sda: $sdapin
scl: $sclpin

display:

  • platform: ili9xxx
    model: GC9A01A
    auto_clear_enabled: false
    id: gca901_display
    cs_pin: $cspin
    dc_pin:
    number: $dcpin
    update_interval: 1s
    lambda:
    it.printf(127, 23, id(font1), TextAlign::TOP_RIGHT , “%.1f°”, id(office_co2).state);

sensor:

  • platform: homeassistant
    id: office_co2
    entity_id: sensor.office_co2
    internal: True

font:

  • file: ‘Oswald-Light.ttf’
    id: font1
    size: 10

The display backlight is on, but nothing is being shown - the sensor values are registered in the web portal of the ESP32 okay…

Any ideas where to start?

Thanks

Tim

Hi there,
So which display driver are you using? TFT_Espi or ? You need to use the seeed version and edit the config for it. Go load up one of the Drag & Drop Uf2 files for to test it.
There’s a zip file attached to the first post that has the chimp wink gif demo. Take a look at that thread to glean some good info.
HTH
GL :slight_smile: PJ

Thank you for your reply - I did get the demo working with Arduino IDE following the instructions, but I was hoping to use ESPHome within Home Assistant and leveraging the GC9A01A driver from the ili9xxxx platform.

I can’t get the display to do anything (I know it works) so I must either have the ports incorrect, or the GC9A01A isn’t the right driver for the display. There are other example of others using the GC9A01A with ESPHome and some of the config I am using is from these examples. The difference is the Seeedstudio packaging potentially, or it not being compatible with ESPHome as all the Seeed examples are for Arduino IDE.

Any ideas, or should I give up getting this to work with ESPHome and use PlatformIO or Arduino IDE?

Thanks

Tim

Hi there,
So which mcu and BSP are you using?
I think if you connect all the right dots, and code is working It should work. AFAIK
GL :slight_smile: PJ

I saw that HA thread about the “cheap touch controller” btw , so I think someone has it working.

external_components:
  - source: github://bearpawmaxim/esphome@pr3625fix
    components: [gc9a01]
  - source: github://pr#5941
    components: [cst816]

spi:
  mosi_pin: GPIO7
  clk_pin: GPIO6

i2c:
  sda: GPIO4
  scl: GPIO5

output:
  - platform: ledc
    pin: GPIO3
    id: gpio_3_backlight_pwm

light:
  - platform: monochromatic
    output: gpio_3_backlight_pwm
    name: "Display Backlight"
    id: backlight
    restore_mode: ALWAYS_ON

display:
#  - platform: ili9xxx
#    model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
  - platform: gc9a01
    id: watchface
    cs_pin: GPIO10
    dc_pin: GPIO2
    width: 240
    height: 240
    eight_bit_color: false
    rotation: 270
    update_interval: 1s
    lambda: |-
      ...

touchscreen:
  id: cst816d
  platform: cst816
  interrupt_pin: GPIO0
  reset_pin: GPIO1
  transform:
    swap_xy: true
    mirror_y: true
  on_touch:
    - ...

You still need to tweek the pins ,for example I think the touch controller is INT GPOI7
or this?

PJ,

Thank you for this - yes this is what I was using for reference. Looks an awesome project, and uses a screen and ESP32 from AliExpress.

I was trying to recreate this using Seeedstudio Round Display and one of their XIAO ESP32-C3 boards which attach to the display. Perfect I thought…

So I tried to reference the pinouts from the display and ESP board and add the GC9A01A display model from the ili9xxx platform.

So what I don’t understand is:
1 - are my pinouts correct for this combination of board + display module
2 - has anyone else got this working using ESPHome
3 - is the GC9A01A able to be used in this way?

Thanks

Tim

Hi there,

  1. I can see from the wiki, No. looks to be what you have is for the Nrf52840 pins.
    see here? ESP32C3 pins
  2. no clue?
  3. yes.
    My .02 is the C3 is enough MCU for this task is my feeling. It will work, there are tons of examples for displays and touch screens for HA. nothing radical here get the pins correct.
    HTH
    GL :slight_smile: PJ

PJ,

Thank for - I thought I was following the ESP332-C3 - this is from the Round Display:

This is what I am mapping:

dcpin: GPIO3
cspin: GPIO1
sckpin: GPIO8
mosipin: GPIO10

#TouchPanel
tp_int: GPIO7
tp_rsp: GPIO9
sdapin: GPIO4
sclpin: GPIO5

spi:
clk_pin: $sckpin
mosi_pin: $mosipin

i2c:
sda: $sdapin
scl: $sclpin

display:

  • platform: ili9xxx
    model: GC9A01A
    auto_clear_enabled: false
    id: gca901_display
    cs_pin: $cspin
    dc_pin: $dcpin
    update_interval: 1s

So can you please double check these with your understanding of the pins for the Round display and XIAO ESP32-C3?

Kind regards

Tim

Hi there,
Those are the Logical pin numbers match them to the correct GPIO’s for ESP32C3,
That is from an Nrf52840 reference.
HTH
GL :slight_smile: PJ
i.e
#TouchPanel
tp_int: GPIO7 (it’s D7 , GPIO20 ) :v:

PJ,

Thank you for this - I feel like a total N00B!

Works perfectly now!!

I have learnt more today with you than in the 10 youtube videos!!

Kind regards

Tim

2 Likes

Hi there,
Awesome…
Mark it as the solution so others can find it. Good job staying at it :v:
GL :slight_smile: PJ

Hello Tim,

I am trying to do something very similar to you and see that you have got it working!

Would you mind uploading the .yaml config that you are using in ESPHome please, so that I and others are able to benefit from what you have learned?

Thanks,
Anth

Sure thing - hope this helps.

I got most of it working - however there is no support for the TouchScreen used so that doesn’t work.

In this code, I read the CO2, temp etc of sensors in HA and then display from animated .gif files on the display. As I was not able to get the touchscreen working, I used pages and intervals to move to the next page automatically.

The result is really good, but as the board I am using (SeeedStudio XIAO C3) only has 4mb of memory - storing the GIF images was problematic. Hope this helps…

It would be awesome if the touchscreen could be made compatible with ESPHome as this round display is otherwise excellent.

substitutions:

change device name to match your desired name

device_name: “round-display-3”

change the below to be your WiFi SSID

ssid: “xxxx”

change the below to be your WiFi password

wifi_password: “xxxxx”
screenstart: ALWAYS_ON

screenstart: ALWAYS_OFF

Timeout for the screen

screensaver: 1 min
timez: Pacific/Auckland

dcpin: GPIO5 #checked okay
cspin: GPIO3 #checked okay
sckpin: GPIO8
mosipin: GPIO10

#TouchPanel
tp_int: GPIO20
sdapin: GPIO6 #checked
sclpin: GPIO7 #checked
bkpin: GPIO21 #with the KE Swith 2 on the ON position.

esphome:
name: $device_name
platformio_options:
board_build.flash_mode: dio

esp32:
board: esp32-c3-devkitm-1
variant: esp32c3
framework:
type: esp-idf

Enable logging

logger:
level: DEBUG #makes uart stream available in esphome logstream
logs:
component: ERROR

Enable Home Assistant API

api:
encryption:
key: “xxx”

ota:
password: “xxxx”

wifi:
ssid: $ssid
password: $wifi_password
use_address: xxxxx

Enable fallback hotspot (captive portal) in case wifi connection fails

ap:
ssid: “round-display-3”
password: $wifi_password
manual_ip:
# Set this to the IP of the ESP
static_ip: xxxxx
# Set this to the IP address of the router. Often ends with .1
gateway: xxxxxx
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0

captive_portal:

web_server:
port: 80
version: 2
include_internal: true

spi:
clk_pin: $sckpin
mosi_pin: $mosipin

i2c:
sda: $sdapin
scl: $sclpin
scan: true
id: i2c_bus1

time:

  • platform: homeassistant
    timezone: “$timez”
    id: esptime

qr_code:

  • id: website_qr
    value: “xxxxx”

output:

  • platform: ledc
    pin: $bkpin
    id: backlight_pwm

light:

  • platform: monochromatic
    output: backlight_pwm
    name: “Display Backlight”
    id: back_light
    restore_mode: ALWAYS_ON

text_sensor:

  • platform: homeassistant
    id: display_backlight
    entity_id: input_number.backlight_level
    internal: true
    on_value:
    then:
    - output.turn_on: backlight_pwm
    - output.set_level:
    id: backlight_pwm
    level: !lambda
    return atoi(id(display_backlight).state.c_str()) / 100.0;

display:

  • platform: ili9xxx
    model: GC9A01A
    auto_clear_enabled: True
    id: watchface
    cs_pin: $cspin
    dc_pin: $dcpin
    dimensions:
    height: 240
    width: 240
    update_interval: 0.1s
    pages:
    • id: page1
      lambda: |-
      it.printf(75,15, id(font_35), “Office:”);
      it.image(30, 65, id(co2), COLOR_ON, COLOR_OFF);
      it.printf(80,75, id(font_20), “CO2: %.0f ppm”, id(office_co2).state);
      it.image(30, 110, id(temperature), COLOR_ON, COLOR_OFF);
      it.printf(80,120, id(font_20), “Temp: %.0f °C”, id(office_temp).state);
      it.image(30, 160, id(heartrate), COLOR_ON, COLOR_OFF);
      it.printf(80,170, id(font_20), “BPM: %.0f”, id(heartrate_level).state);
      it.strftime(80,215, id(font_12), “%d-%m-%y %H:%M”, id(esptime).now());
    • id: page2
      lambda: |-
      it.printf(75,15, id(font_35), “Office:”);
      id(co2).next_frame();
      id(temperature).next_frame();
      it.image(30, 65, id(co2), COLOR_ON, COLOR_OFF);
      it.printf(80,75, id(font_20), “CO2: %.0f ppm”, id(office_co2).state);
      it.strftime(80,215, id(font_12), “%d-%m-%y %H:%M”, id(esptime).now());
    • id: page3
      lambda: |-
      it.qr_code(45, 45, id(website_qr), Color(255,255,255), 6);
    • id: page4
      lambda: |-
      it.printf(75,15, id(font_35), “Office:”);
      it.image(25, 65, id(wifi_image));
      it.printf(75,75, id(font_20), “Wifi dB: %.0f dB”, id(wifi_signal_db).state);
      it.image(25, 110, id(wifi_image));
      it.printf(75,120, id(font_20), “Wifi Signal %: %.1f%%”, id(wifi_signal_percent).state);
    • id: page5
      lambda: |-
      auto red = Color(255, 0, 0);
      it.circle(120,120,119, red);

sensor:

  • platform: homeassistant
    id: office_co2
    name: “Co2 Levels”
    entity_id: sensor.office_co2
    unit_of_measurement: “ppm”
    internal: True
  • platform: homeassistant
    id: office_temp
    name: “Temperature”
    unit_of_measurement: “°C”
    entity_id: sensor.garage_sensor_temperature
    internal: True
  • platform: homeassistant
    id: heartrate_level
    name: “Heartrate”
    unit_of_measurement: “bpm”
    entity_id: sensor.office_heartrate_level
    internal: True
  • platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: “WiFi Signal dB”
    id: wifi_signal_db
    update_interval: 60s
    entity_category: “diagnostic”
  • platform: copy

    Reports the WiFi signal strength in %

    source_id: wifi_signal_db
    id: wifi_signal_percent
    name: “WiFi Signal Percent”
    filters:
    • lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
      unit_of_measurement: “%”
      entity_category: “diagnostic”
      device_class: “”

font:

  • file: “gfonts://Roboto”
    id: font_35
    size: 35
  • file: “gfonts://Roboto”
    id: font_25
    size: 25
  • file: “gfonts://Roboto”
    id: font_10
    size: 10
  • file: “gfonts://Roboto”
    id: font_12
    size: 12
  • file: “gfonts://Roboto”
    id: font_16
    size: 16
  • file: “gfonts://Roboto”
    id: font_24
    size: 24
  • file: “gfonts://Roboto”
    id: font_32
    size: 32
  • file: “gfonts://Roboto”
    id: font_20
    size: 20

animation:

  • file: “images/co2.gif”
    id: co2
    type: RGBA
  • file: “images/temperature.gif”
    id: temperature
    type: RGBA
  • file: “images/heart_rate.gif”
    id: heartrate
    type: RGBA

image:

interval:

  • interval: 0.1s
    then:
    animation.next_frame: co2
  • interval: 0.1s
    then:
    animation.next_frame: temperature
  • interval: 0.1s
    then:
    animation.next_frame: heartrate
  • interval: 5s
    then:
    • display.page.show_next: watchface
    • component.update: watchface
2 Likes