ESP32-C3 with integrated GC9A01 - cheap touch controller

@zagnuts ,

Your code now compiles correct.

I have a question. For the light, you use a binary sensor (number). If I want to control a light for HA , do I then need an automation in HA?? But it doesn’t read the state?? It shuld me nice to have it as toggle light switch and reads the state also

You can call any home assistant service (eg, light.turn_on) from esphome, or you can put the automation in home assistant. Up to you.

See Native API Component — ESPHome and don’t forget

Before a newly added ESPHome device can interact with the Home Assistant API it needs to be allowed to communicate with it. This setting can be found in the ESPHome integration (NOT in the Add-On) by clicking “CONFIGURE” for that device and enabling the “Allow device to make service calls” option.

(From the same page)

1 Like

Excellent point, @nickrout. I hadn’t mentioned that as I was more focussed on getting the dang thing to work. On the other hand, assuming the device you want to control is supported then it does mean not having to worry about automations, it’s quicker, and direct so - all things considered - is probably the better option. :slight_smile:

Next time I update the sample code I might put that in as an option.

1 Like

Hi! As suggested by @nickrout, I’ve updated the sample code to show how to change the light directly using homeassistant.service rather than by automations. Actually, updated it to both change that and the thermostat temps directly. Toggling the HVAC mode I left to going via an automation as I want to be able to go through specific functions rather than all of the options my system has - could probably do that directly as well, but for now it’s easier to use an automation and in any case is good to have in there as an example of what can be done. Cheers. :slight_smile:

This display is getting support in mainline!! ili9xxx: Add support for GC9A01A display by clydebarrow · Pull Request #6351 · esphome/esphome · GitHub

3 Likes

Yeah but not the touch part, just the display at this stage?

Probably yes, but touch is a separate driver anyways right?

1 Like

Correct - so having the screen in mainstream is a big step. The fewer things there are that require external components the better! Definitely good news. :slight_smile:

1 Like

if you have a solution for the holes next to the display please let me know :wink:
“Gira or buschjeager ? impulse” Switch wars used for the cover
the Tempsensor DS18B20 is connected to the display pcb IO8 pin, and is used for room temp sensing

3 Likes

Nice to know that it seems to fit the busch-jaeger plates, although sadly they are unobtanium out here in Australia. Even if I could get them, I suspect that the cost of finding and shipping the things out would make them no longer economical.

Anyhow, if you have the chance, would like to see how you actually connected the temp sensor. A future option may be to create a plate with a spot to mount the temp sensor with a discrete grill that people could 3d print (then sand & paint to make them look professional… or if you need a lot, use one to make a mold and cast plates).

As for the holes, well yes. I have spent many years fixing up old houses and I usually use a fine topcoat filler for small holes. Wonderful stuff. Different brands out there, but usually can get them in a small tub that includes a spatula on the lid, so perfect for small repairs. Push any jutting out bits in from the old screw holes, then do a few coats (allowing to dry and then sand with fine paper between each coat) and you can get a virtually invisible repair.

Ready for final sand and paint:

Does anyone know what GPIO8 does? I saw one config using it for LCD IRQ but the schematic says GPIO0 is used for this (TP_INT).

I thought S1 might refer to the battery/side switch but I haven’t been able to see it in Tasmota anyway.

The esp32c3.svd bundled with the demo code says GPIO08 can change UART/boot messages but I don’t know if that’s applicable here.

Has anyone traced the PCB? I haven’t opened the case yet. Since it’s a battery powered device I wondered why there wasn’t some way to read the battery voltage/status.

image

I have mine working with the new LVGL component that is still in development :smiley: Details here: GitHub - clowrey/esphome-esp32-2424s012-lvgl-powermeter

There is no dedicated documentation for it yet as far as I know - so try not to bug him too much asking for details yet as its still in development - but the gist examples I link to in that repo should allow anyone to use it as is with a bit of tinkering :wink:

Suffice to say this component is a huge game changer and clydebarrow (Clyde Stubbs) · GitHub has done an amazing job creating it - he is the same one who got this display into main ESPHome and other displays as well.

3 Likes

I think that’s just an extra GPIO pin they are breaking out, but could be wrong.

Do you guys know how to obtain the x and y coordinates where the screen was clicked?

When I try using these external components: external_components:

  - source: github://GadgetFactory-Jeannie/esphome-components@main
    components: [gc9a01, CST816S_touchscreen]

I encounter this problem with the display:

- platform: gc9a01
    id: smart_switch_display
    reset_pin: $repin
    cs_pin: $cspin
    dc_pin: $dcpin
    rotation: 90

The problem:

INFO Generating C++ source...
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Program Files\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\Scripts\esphome.exe\__main__.py", line 7, in <module>
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 1061, in main
    return run_esphome(sys.argv)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 1048, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 478, in command_run
    exit_code = write_cpp(config)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 192, in write_cpp
    generate_cpp_contents(config)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 204, in generate_cpp_contents
    CORE.flush_tasks()
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\core\__init__.py", line 679, in flush_tasks
    self.event_loop.flush_tasks()
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 184, in wrapped
    await coro(conf)
  File "C:\Users\bryan\.esphome\external_components\4c59ea0a\components\gc9a01\display.py", line 77, in to_code
    await setup_gc9a01(var, config)
  File "C:\Users\bryan\.esphome\external_components\4c59ea0a\components\gc9a01\display.py", line 56, in setup_gc9a01
    await display.register_display(var, config)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\components\display\__init__.py", line 119, in register_display
    await cg.register_component(var, config)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\cpp_helpers.py", line 56, in register_component
    raise ValueError(
ValueError: Component ID smart_switch_display was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.
sys:1: RuntimeWarning: coroutine 'to_code' was never awaited
sys:1: RuntimeWarning: coroutine 'add_arduino_global_workaround' was never awaited

Do you guys know how to fix it?

FYI - I have updated my sample code in the ‘solution’ for this thread as well as my github repository to account for the recent addition of integrated support for the screen within the ili9xxx driver ie you no longer need to include gc9a01 under external components. Note - you still need an external driver for the touch screen.

If you are having issues with getting the device to work, make sure that you are using versions of both HA and esphome that are the same or newer as those referred to in the sample code, and then use and tweak it as required. :slight_smile:

2 Likes

Yep. Don’t use that external component. :slight_smile: Check out my updated code. Cheers.

thank you!!!

First, thank you to all of you for your work!

I’m sharing my work in case it can help someone.

I’m not a C/C++ developer, so I’m trying my best to create something that works, and I’m new to ESPHome or Home Assistant.

In my fork, I updated the function that returns the gesture to also return an ID with the X and Y position. (i’m sure there is many other and better way to do it)

I’ve included my YAML file for the screen + touchscreen, in case it can be helpful.

With my modifications, I have to use lambda functions only (I think), but that’s okay, I’m more used to working like this. ^^

My config turn on and off a light and change the brightness of the screen and only on click it display a circle where i click.

For now i try many thing to learn, but now with the click i can have more feature.

2 Likes

I did some experiments to see if it is possible to get rid of the external components and here is what I fixed together.

This make use of the esphome touchscreen component.
Esphome touchscreen component

This is a minimal working example that will show touch data and sliding touch data in the log output. With this you can try to build further.

substitutions:
  devicename: touchdemo
  friendname: "Touch Demo"
  board: esp32-c3-devkitm-1


#GPIO pins for the LCD screen
  repin: GPIO1
  dcpin: GPIO2
# 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: GPIO3
  clpin: GPIO6
  mopin: GPIO7
  cspin: GPIO10
# GPIO pins for the touch screen
  sdapin: GPIO4
  sclpin: GPIO5
  intpin: GPIO8  

esphome:
  name: $devicename
  friendly_name: $friendname

esp32:
  board: $board
  framework:
    type: arduino

# Enable logging
# Change to avoid "Components should block for at most 20-30ms" warning messages in the log - an issue since 2023.7.0
# Not really a breaking change - it's an issue I suspect due to the device being slow and this error previously
# simply not being reported
logger:
  level: DEBUG #makes uart stream available in esphome logstream
  logs:
    component: ERROR
  #Turn off UART logging over RX/TX 
  baud_rate: 0


# Enable Home Assistant API
api:
  encryption:
    key: "YOUR ENCRYPTION KEY or remove this block"

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: !secret fallback_ssid
    password: !secret fallback_password

captive_portal:

touchscreen:
  id: my_touch_screen_test
  platform: cst816
  interrupt_pin: GPIO0
  transform:
    swap_xy: true
    mirror_y: true
  on_touch:
    - lambda: |-
        ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
        );
    - component.update: watchface
    - delay: 5s
    - component.update: watchface
  on_update:
    - lambda: |-
          for (auto touch: touches)  {
              if (touch.state <= 2) {
                 ESP_LOGI("Touch points:", "id=%d x=%d, y=%d", touch.id, touch.x, touch.y);
              }
          }


spi:
  mosi_pin: $mopin
  clk_pin: $clpin


i2c:
  sda: $sdapin
  scl: $sclpin


display:
  - platform: ili9xxx
    model: GC9A01A
    id: watchface
    reset_pin: $repin
    cs_pin: $cspin
    dc_pin: 
      number: $dcpin
      ignore_strapping_warning: true
      # The above is to remove the strapping pin warning message
    # How often to refresh the display
    update_interval: 1s


font:
  - file: "gfonts://Roboto"
    id: font_12
    size: 12
4 Likes