ESP32-C3 with integrated GC9A01 - cheap touch controller

Pretty cool :slight_smile: Do you have some code for inspiration?

All the best

Jacob from Denmark

1 Like

Hi. If you mean how to turn on the screen when motion detected, just create an automation that when motion is detected the screen goes on eg:

alias: testing
description: ""
trigger:
  - type: motion
    platform: device
    device_id: 34d2a50dcb811f03aaf9a4270ff131dc
    domain: binary_sensor
condition: []
action:
  - service: light.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: light.wallwatch07_display_backlight
mode: single

Similarly, can always create an automation that turns the backlight off (say) 5 mins after motion has stopped being detected. :slight_smile:

FWIW I still haven’t worked out why I can’t seem to power these things via the JST socket (I’m waiting for a new bench power supply to arrive), but in the meantime I gave ble_tracker another try and something seems to have been updated recently (I’m on esphome 2023.12.9 and HA 2024.2.0) and it is pretty stable! I have had one running overnight without an issue. So that’s great news as, if you want, you can use them for presence detection for ble devices like watches, phones, etc. Of course it’s too early to say how accurate/sensitive they are, but if you want to try this, the key things to be aware of are:

  1. As stated in the docs, do not add in “esp32_ble_tracker:” and then update the code via OTA. Save the code locally, and then upload it to the device directly via USB and https://web.esphome.io/. Once you have done this the first time, you can go back to using OTA when you make changes.
  2. In the display section, do not use “eight_bit_color: false”. This uses up too much memory if you also want to run the ble_tracker. Sadly that means the colours & screen refreshes are not as good, but such is life. When I tested it, it did sort of work, but was very jerky and rebooted a few times by itself so it’s a no for me.
  3. Be careful when playing with the logger levels - I recommend leaving them at the minimum and not using these to do the initial discovery of devices or create a simple ble_tracker image that has no display etc settings in it. Again, I tried more detailed logging and the results were not great. Frankly, a ble scanner 'phone app works well.

update Spoke too soon. Finding it is rebooting randomly. Added in a monitor for the memory and it seems to be pretty stable at around the 50kb free mark but I suspect it’s borderline - perhaps if there’s a spike of ble activity it can’t cope. Without the ble it’s about 140kb. Without ble, but with the eight_bit_color disabled it’s around 80kb free. It might work for you, but I have a lot of ble devices so it’s probably not an option for me.

Hi,

Here is my config for this display: ESPHome round display · GitHub

  • Christian from Denmark :wink:
2 Likes

This is driving me crazy. I must be missing something obvious, so am looking through the circuit diagram to see if I can work out what it is.

Have hooked my new bench power supply up and tried a range of voltages with no luck. I thought maybe the “battery charging interface, supporting both charging and discharging, with overcharging and overcurrent protection” was swinging in early, but no joy at 3.7V or indeed 3.3V (which is what the circuit diagram indicates it wants). I know the JST cable is connected properly as it is pumping power out (to charge the battery - measured at 4.2V) over those wires when it’s plugged into a USB power source. I know the voltages are right as I’ve double checked it with my multimeter, but it just does not want to draw anything through that socket. I might have to resort to pumping power through the USB socket, but it won’t look as neat as I wanted unless I crack open the case and do some soldering - not what I’d like to have to do. Maybe I was just unlucky, and got three faulty devices. Sigh.

…and, worked it out. Can power via the jst socket but before it starts working you need to apply power to the usb-c port. This means I can do what I want ie run power from a central location to all the controllers, but if the power goes out I’ll need to go to each one and briefly apply power to the usb port. That is, as they say, sub optimal. I could run a cable from the usb c socket, but will look ugly. I might have to crack one open and try soldering wires to the positive/negative terminals on the usb c connector.

After working out the issue last night, I have thought about it further. I don’t like the idea of having to solder wires to every board as the risk of damaging something on such a small board is high, so I’m now thinking about a bare male USB C plug and using that. Depending on what I can find, the back of the plug should still be fairly flush to the side of the case.
Screenshot 2024-02-13 at 8.56.34 am

The wires are thin so they should be able to run along the back and still be able to mount the controller flush to the wall using 3M strips. If I can’t then my fallback option is to work out how to remove the case and route the wires through the gap beside the USB port and out through one of the existing holes on the back. Having something plugged into the USB port is not as neat as using the jst port but it looks like I have no option unless I’m willing to do some micro soldering.

1 Like

Maybe I have a different board, but at least for me pressing the side button labeled ‘switch’ in the diagram booted fine from a fully charged lipo

Quite likely, but I am planning to have multiple controllers stuck to the wall with DC coming from a central power supply. I don’t want to also hook up lipo batteries to them as that would require a case. In addition, going around to all the controllers after a power outage and having to press the switch or plug in USB power is something I’d rather avoid, so sending 5V to the USB port seems to be the only option for my use case. :slight_smile:

Well that was much harder than it should be. I am pumping 5V over ethernet cable to where each controller goes. I’m using a dumb PoE splitter to share a single power supply at a central location and that is working just fine for my existing esp32 based control panels. The power supply is a decent one but just to confirm I swapped it with my bench power supply and no go. It worked when I put 5V direct to the controller but not when running it over a distance. I noticed that the voltage varied a little (understandable due to the number of devices sharing the one supply) so although I found it could cope with higher and lower voltage levels, I suspect the variation was triggering the protection circuit. When this happens, either the controller fails to turn on, or it cycles on/off.

Solution was to put a capacitor (680uF, 10V - probably could use something better, but that’s what I had) in and “ta dah” it now works.


This photo is just to give you an idea of what I did - I actually used heat shrink on the thing before putting it in the wall.

All I need to do now is fix up the holes in the plaster left behind from the old controller. I might also see if I can hook a temp sensor up to it so I can lose the zigbee sensor that’s next to it.

1 Like

hello and thank you for your progress on this!

do you guys think that we can have a tutorial on installation and features?

No problem

As this is still a work in progress ie the drivers etc have not been integrated into esphome, it’s probably too early to make a tutorial as anything that is created will need to be updated, and on a very reqular basis. I have however tried to keep changes and documentation as such in the example code here.

In brief though, as far as features are concerned it’s a colour touch sensitive screen, similar to a smart watch, and is pretty inexpensive. It comes in a tidy package including an optional case (saving having to buy or make one of those) that includes an esp32 processor, albeit one that is not super powerful. How it can be used is up to each person, but I suspect most people reading this will use it to either display information from Home Assistant, or control devices through Home Assistant, or potentially both. The device can be powered through the USB-C port, or you can connect a battery up to it and the battery can be charged via the USB-C port. There is a UART serial port on one side that could also potentially be used to directly connect an external sensor such as a a temp or humidity sensor.

To set one up currently you need to load code onto the new device via esphome. For various reasons, the best way to do that appears to be to:

  • create the code first - see the ‘answer’ to this original thread for an example. You will need to edit it slightly to suit your use case.
  • save that locally as a binary file from within esphome
  • connect the device directly to a pc with a USB-C cable and select the option to prepare it for use for esphome via https://web.esphome.io/
  • save the code to the device

From then on you should be able to modify the code in esphome and upload the new code to the device OTA (Over The Air). One minor note - if you decide to try to use an existing device to monitor bluetooth devices, then prepare it by connecting it physically to a pc again - enabling bluetooth requires the esp32 device to be partitioned in a different way. Once done, then again you can make changes OTA.

There are some gotchas such as with bluetooth, most of which are due to low memory and processor speed (it is cheap after all), that I have tried to document in the sample code.

Cheers

@zagnuts

I will try to make a config. I use your config but I have questions over the image used. Now I get errors that it fails of these images. Can we download them somewhere?

Wat kind of image is this 2051v2.gif?
The sizes of the other icons, should these also be 40x40?

animation:
  - file: "icons/2051v2.gif"
    id: clear_day
    resize: 40x40
    type: RGB565 #default is binary ie greyscale
  - file: "images/lightoff.png"
    id: light_off
  - file: "images/lighton.png"
    id: light_on
    type: RGB565
  - file: "images/greenarrow.png"
    id: greenarrow
    type: RGB565
  - file: "images/redarrow.png"
    id: redarrow
    type: RGB565

The intent of the code I’ve shared is to provide guidance on how to use the device. The first image is a two page animated gif, and shows the code required to resize it to fit the screen. In general however I would try to avoid the resize option as it could use up some valuable processing power. The other images are standard png files, and I made them the size I wanted so I could avoid using the resize option.

I cannot provide the actual images I use as over the years I have created a library and frankly I am unsure whether I created all of these myself or found them somewhere on the interwebs - so there could be licensing issues! You can of course remove references to those images, but what I have however done is with gimp quickly created some base images you can probably use to get started if you just want to use my code as it is. I recommend however making ones that you want to suit your actual needs.

Cheers.

2 Likes

Thank you for sharing your progress.
I get a compile error when it’s trying to run your code, point me in the right direction?

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 1041, in main
    return run_esphome(sys.argv)
  File "C:\Users\bryan\AppData\Roaming\Python\Python310\site-packages\esphome\__main__.py", line 1028, 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 458, 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\1ffebe30\esphome\components\gc9a01\display.py", line 77, in to_code
    await setup_gc9a01(var, config)
  File "C:\Users\bryan\.esphome\external_components\1ffebe30\esphome\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 watchface 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

Late last year there was a change in the display structure within esphome that broke many external display components (as they were not updated automatically with esphome) that resulted in the code being unable to compile and coming up with the same error code you have ie “Component ID watchface was not declared to inherit from Component, or was registered twice.”. This was addressed via the updated external components here:

external_components:
  - source: github://bearpawmaxim/esphome@pr3625fix
    components: [ gc9a01 ]
  - source: github://GadgetFactory/[email protected] 

There are many code examples in this thread as a number of people have been working on getting this stable for a number of months, and some of the older code examples are broken due to changes to esphome in that time. If you are just starting, make sure you are using the latest code that is in the ‘answer’ to this topic or in my github repository. If your external component section is as above and you still have issues, also make sure that you aren’t referring to any other external display component and that you are running the latest version of esphome. Cheers.

1 Like

It works, thank you!!

1 Like

Just a head’s up re the I/O port on this thing. I got some SH1.0 4 pin cables and can confirm it is pumping out a solid 3.3V. I hooked up a DS18b20 and was able to read the 1-wire address from the sensor just fine. It is however reporting exactly 25 °C and not changing which is not right, of course.

I’m using a sensor that’s on a board with the required pull up resistor etc but I only found the one in my box of bits so as well as maybe a dumb coding issue on my part it’s quite possible that the sensor might be faulty. When I have the chance I’ll see if I can find something else to put onto it (I think I saw an old AM2302 somewhere) and/or use another esp32 to confirm if the ds18b20 is actually ok.

My end goal is to see if I can hook up a sensor to provide room temperature readings, and/or a motion sensor for occupancy/automatic display wakeup.

In the meantime, if anyone else wants to start playing with connecting something to the port, I believe (according to the diagram “ESP32-C3-MINI-1U.jpg” in the docs, and the rxpin was confirmed by my being able to read the 1-wire address) that the RX and TX pins translate to the following GPIO pins:

  rxpin: GPIO20
  txpin: GPIO21
1 Like

Your work on this continues to be an inspiration :slight_smile:

2 Likes

Heh. Thanks. I wish I had better news though - just confirmed that my sensor is working and also found and tried an AM2302 (DHT22 equivalent) that also tested fine on another device (specifically an old Wemos D1mini), but the controller is fighting me. Not getting anything from the AM2302 and just the 1-wire address and false reading from the ds18b20. Might just be another board quirk that it doesn’t like using the RX/TX as GPIO so need to do UART, which is annoying.

Will need to put this to one side now and just let that sit in the back of my mind. Is not critical for me - I already have separate temperature sensors in most rooms and the screen timeout is working well.