Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GC9A01 round TFT display #3625

Closed
wants to merge 6 commits into from
Closed

Add GC9A01 round TFT display #3625

wants to merge 6 commits into from

Conversation

4cello
Copy link

@4cello 4cello commented Jul 8, 2022

What does this implement/fix?

Add display platform for GC9A01 240x240 TFT LCD.
Tested with ESP32 and ESP8266. (ESP8266 only with reduced display size because of frame buffer size)

Types of changes

  • New feature (non-breaking change which adds functionality)

Related issue or feature (if applicable): -

Pull request in esphome-docs with documentation (if applicable): esphome/esphome-docs#2176

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266

Example entry for config.yaml:

# Example config.yaml
spi:
  mosi_pin: GPIO32
  clk_pin: GPIO27

display:
- platform: gc9a01
  reset_pin: GPIO26
  cs_pin: GPIO25
  dc_pin: GPIO33
  rotation: 180
  lambda: |-
    it.print(0, 120, id(font), "Hello World!");

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

@4cello
Copy link
Author

4cello commented Jul 26, 2022

do you mean 1.28"? The only Waveshare 1.8" display is not round.
I'll look into the code nevertheless, but I don't own that display and I'm not sure how easily I can buy it for a reasonable price.

Does your display work with this library? https://github.com/PaintYourDragon/Adafruit_GC9A01A
I basically only ported that to ESPHome, but I removed some code I didn't use for my display. Maybe I can add it back once I understand how it helps with your display.

@firepinn
Copy link

I actually managed to get it to work. Sorry for the confusion.

@velkrosmaak
Copy link

I actually managed to get it to work. Sorry for the confusion.

Can you please share the yaml you used to get this display working?

@pvh0
Copy link

pvh0 commented Sep 29, 2022

I actually managed to get it to work. Sorry for the confusion.

Can you please share the yaml you used to get this display working?

Probably something like:

external_components:
  - source: github://pr#3625
    components: [ gc9a01 ]

spi:
  mosi_pin: GPIO13
  clk_pin: GPIO14

display:
- platform: gc9a01
  reset_pin: GPIO26
  cs_pin: GPIO15
  dc_pin: GPIO33
  rotation: 180
  lambda: |-
      it.line(0, 0, 100, 50);

@sam632
Copy link

sam632 commented Oct 8, 2022

I'm getting this error when trying to install with the above YAML. Not 100% sure how esphome works in the background, any help would be appreciated.

In file included from src/esphome/components/gc9a01/gc9a01.cpp:1:0:
src/esphome/components/gc9a01/gc9a01.h:29:12: error: 'DisplayType' in namespace 'esphome::display' does not name a type
   display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }

@bigmoby
Copy link

bigmoby commented Dec 10, 2022

I'm getting this error when trying to install with the above YAML. Not 100% sure how esphome works in the background, any help would be appreciated.

In file included from src/esphome/components/gc9a01/gc9a01.cpp:1:0:
src/esphome/components/gc9a01/gc9a01.h:29:12: error: 'DisplayType' in namespace 'esphome::display' does not name a type
   display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }

@sam632 please you could have a try with:

external_components:
  - source: github://4cello/esphome@gc9a01
    components: ["gc9a01"]

@sam632
Copy link

sam632 commented Dec 10, 2022

I'm getting this error when trying to install with the above YAML. Not 100% sure how esphome works in the background, any help would be appreciated.

In file included from src/esphome/components/gc9a01/gc9a01.cpp:1:0:
src/esphome/components/gc9a01/gc9a01.h:29:12: error: 'DisplayType' in namespace 'esphome::display' does not name a type
   display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }

@sam632 please you could have a try with:

external_components:
  - source: github://4cello/esphome@gc9a01
    components: ["gc9a01"]

This didn't work unfortunately. What's the best way to debug this issue?

@github-actions
Copy link
Contributor

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.

@github-actions github-actions bot added the stale label Mar 11, 2023
@filmkorn
Copy link

I'd love to see this implemented as these displays are fairly cheap and widely available. How could I help with this PR without having any language knowledge?

@github-actions github-actions bot removed the stale label Mar 12, 2023
@pkejval
Copy link

pkejval commented Mar 28, 2023

Why is this stale? I'm using this PR component and works without any problems.

@bigmoby
Copy link

bigmoby commented Mar 28, 2023

Hi @pkejval yes it works, it should be maintained aligned with dev branch (there are some conflicts).

@jbishop129
Copy link

I've been working with this external component (Thanks @4cello !!!), and it works quite well. The only issue I've had so far is I cannot get it to drive two of these displays from one ESP32; you just use separate CS pins. Shouldn't be an issue, as there's several "animated eyes" projects out there in the wild such as this one, but it seems in ESPHome, adding a second instance of the display results in the last one in my code being the only one that works, the first one stops working. I dug through @4cello 's code to see if I could find a setting, but I didn't see anything.

Here's a basic Hello World example of what I'm troubleshooting with, trimmed down as much as possible to test with. Any thoughts?

esphome:
  name: "round-display"
  friendly_name: ESP32 Round Display

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:

api:
  encryption:
    key: [redacted]

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  ap:
    ssid: "Esphome-Round-Display"
    password: !secret ap

captive_portal:
    
external_components:
  - source: github://4cello/esphome@gc9a01
    components: ["gc9a01"]

spi:
  mosi_pin: GPIO23
  clk_pin: GPIO18

font:
  - file: 'fonts/Google_Sans_Regular.ttf'
    id: font_16
    size: 16

time:
  - platform: sntp
    id: my_time

display:
## First display <-- Nothing displays, when Second Display is configured. Works fine if comment out Second Display
  - platform: gc9a01
    id: roundOLED1
    reset_pin: GPIO26
    cs_pin: GPIO5
    dc_pin: GPIO25
    rotation: 90
    lambda: |-
      it.strftime(120,80, id(font_16), TextAlign::CENTER, "%A %b %w", id(my_time).now());

## Second display <-- Displays dateTime data as expected.
  - platform: gc9a01
    id: roundOLED2
    reset_pin: GPIO26
    cs_pin: GPIO15
    dc_pin: GPIO25
    rotation: 90
    lambda: |-
      it.strftime(120,80, id(font_16), TextAlign::CENTER, "%A %b %w", id(my_time).now());

@lboue
Copy link
Contributor

lboue commented Jun 1, 2023

Could you merge this PR with the dev branch? This has been tested by several people and works.

GC9A01_1 28inch_s

this->dc_pin_->digital_write(true);

if (this->eightbitcolor_) {
for (size_t line = 0; line < this->get_buffer_length(); line = line + this->get_width_internal()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop is extreamly slow. Sending pixel data on 40MHz SPI takes 30ms, but this loop for 240x240 on ESP32S3 (160MHz clock) takes ~200ms.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this too specifically on the ESP32S3, other variants seem normal refresh speed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 40MHz and using 16bit refresh takes roughly ~30ms for the 240x240 on esp32s3.

Copy link

@mcmanigle mcmanigle Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me (using esp32s2) setting eight_bit_color: false in yaml configuration results in a broken image and loss of connectivity. Leaving the default (true) works fine but with the long update as mentioned above.

edit - I am actually using an esp32s2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcmanigle can you add an photo from your broken image on your display?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue is here: https://imgur.com/a/CKaTwWo

It obviously also overflows memory or otherwise breaks things somehow -- note the sensors aren't reading right; wifi connectivity is non-existent, etc in the eight_bit_color: false version (everything else stays the same compared to version on the left).

I assumed it was crashing the ESP entirely (I usually use wifi logs etc), but when plugged in, see that it does pass messages from the display component. Also note the central RGB circles (added for debugging) change color; looks like wrong bits written.

My display code is here; it uses DATA_RATE_40MHZ and changes DisplayBufferRef to DisplayRef but no other changes.

For reference, on this esp32s2 (specifically this one; note in my earlier post I mentioned s3, but I was wrong; it's an s2), with eight_bit_display: false, the logger complains the display update takes 160ms. With eight_bit_display on (default), it says it takes 260ms.

class GC9A01 : public PollingComponent,
public display::DisplayBuffer,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
spi::DATA_RATE_8MHZ> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm able to use DATA_RATE_40MHZ.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
spi::DATA_RATE_8MHZ> {
spi::DATA_RATE_40MHZ> {

Comment on lines +95 to +97
ESP_LOGD(TAG, " START");
dump_config();
ESP_LOGD(TAG, " END");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ESP_LOGD(TAG, " START");
dump_config();
ESP_LOGD(TAG, " END");

dump_config();
ESP_LOGD(TAG, " END");

display_init_(INITCMD);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
display_init_(INITCMD);
this->display_init_(INITCMD);

Comment on lines +110 to +112
int GC9A01::get_height_internal() { return height_; }

int GC9A01::get_width_internal() { return width_; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int GC9A01::get_height_internal() { return height_; }
int GC9A01::get_width_internal() { return width_; }
int GC9A01::get_height_internal() { return this->height_; }
int GC9A01::get_width_internal() { return this->width_; }

this->cs_->digital_write(true);

this->init_reset_();
delay(100); // NOLINT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please alter this code to use a set_timeout instead of delaying

class GC9A01 : public PollingComponent,
public display::DisplayBuffer,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
spi::DATA_RATE_8MHZ> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
spi::DATA_RATE_8MHZ> {
spi::DATA_RATE_40MHZ> {

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Dec 26, 2023

Hello! When using this PR I'm getting an error with the latest esphome version (2023.12.5):

INFO Generating C++ source...
Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 33, in <module>
    sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1041, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1028, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 407, in command_compile
    exit_code = write_cpp(config)
                ^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 192, in write_cpp
    generate_cpp_contents(config)
  File "/esphome/esphome/__main__.py", line 204, in generate_cpp_contents
    CORE.flush_tasks()
  File "/esphome/esphome/core/__init__.py", line 679, in flush_tasks
    self.event_loop.flush_tasks()
  File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "/esphome/esphome/__main__.py", line 184, in wrapped
    await coro(conf)
  File "/data/external_components/1ff663bb/esphome/components/gc9a01/display.py", line 77, in to_code
    await setup_gc9a01(var, config)
  File "/data/external_components/1ff663bb/esphome/components/gc9a01/display.py", line 56, in setup_gc9a01
    await display.register_display(var, config)
  File "/esphome/esphome/components/display/__init__.py", line 119, in register_display
    await cg.register_component(var, config)
  File "/esphome/esphome/cpp_helpers.py", line 56, in register_component
    raise ValueError(
ValueError: Component ID watchface1 was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.

the config is

substitutions:
  device_name: pc-power-button
  device_name_underscore: pc_power_button

esphome:
  name: ${device_name}
  platform: ESP32
  board: esp32-c3-devkitm-1

packages:
  device_common: !include .device_common.yaml

external_components:
 - source: github://pr#3625
   components: [ gc9a01 ]
#  - source: github://4cello/esphome@gc9a01
#    components: ["gc9a01"]

spi:
  mosi_pin: GPIO7
  clk_pin: GPIO6

# Need to turn on backlight as by default is not on
output:
  - platform: ledc
    pin: GPIO3
    id: gpio_3_backlight_pwm

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

font:
  - file: "gfonts://Roboto"
    id: font_16
    size: 16
  - file: "gfonts://Roboto"
    id: font_32
    size: 32

color:
  - id: my_red
    red: 100%
    green: 3%
    blue: 5%
  - id: my_green
    red: 3%
    green: 100%
    blue: 5%
  - id: my_blue
    red: 3%
    green: 5%
    blue: 100%

display:
#  - platform: ili9xxx
#    model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
  - platform: gc9a01
    id: watchface1
    reset_pin: GPIO1
    cs_pin: GPIO10
    dc_pin: GPIO2
    rotation: 90
    lambda: |-
      it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(sntp_time).now());
      it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(sntp_time).now());
      it.circle(120, 120, 115, id(my_red));

UPD: looks like this happens because of #6009 being merged some days ago

@ParineetVernekar
Copy link

Hello! When using this PR I'm getting an error with the latest esphome version (2023.12.5):

INFO Generating C++ source...
Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 33, in <module>
    sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1041, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1028, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 407, in command_compile
    exit_code = write_cpp(config)
                ^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 192, in write_cpp
    generate_cpp_contents(config)
  File "/esphome/esphome/__main__.py", line 204, in generate_cpp_contents
    CORE.flush_tasks()
  File "/esphome/esphome/core/__init__.py", line 679, in flush_tasks
    self.event_loop.flush_tasks()
  File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "/esphome/esphome/__main__.py", line 184, in wrapped
    await coro(conf)
  File "/data/external_components/1ff663bb/esphome/components/gc9a01/display.py", line 77, in to_code
    await setup_gc9a01(var, config)
  File "/data/external_components/1ff663bb/esphome/components/gc9a01/display.py", line 56, in setup_gc9a01
    await display.register_display(var, config)
  File "/esphome/esphome/components/display/__init__.py", line 119, in register_display
    await cg.register_component(var, config)
  File "/esphome/esphome/cpp_helpers.py", line 56, in register_component
    raise ValueError(
ValueError: Component ID watchface1 was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.

the config is

substitutions:
  device_name: pc-power-button
  device_name_underscore: pc_power_button

esphome:
  name: ${device_name}
  platform: ESP32
  board: esp32-c3-devkitm-1

packages:
  device_common: !include .device_common.yaml

external_components:
 - source: github://pr#3625
   components: [ gc9a01 ]
#  - source: github://4cello/esphome@gc9a01
#    components: ["gc9a01"]

spi:
  mosi_pin: GPIO7
  clk_pin: GPIO6

# Need to turn on backlight as by default is not on
output:
  - platform: ledc
    pin: GPIO3
    id: gpio_3_backlight_pwm

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

font:
  - file: "gfonts://Roboto"
    id: font_16
    size: 16
  - file: "gfonts://Roboto"
    id: font_32
    size: 32

color:
  - id: my_red
    red: 100%
    green: 3%
    blue: 5%
  - id: my_green
    red: 3%
    green: 100%
    blue: 5%
  - id: my_blue
    red: 3%
    green: 5%
    blue: 100%

display:
#  - platform: ili9xxx
#    model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
  - platform: gc9a01
    id: watchface1
    reset_pin: GPIO1
    cs_pin: GPIO10
    dc_pin: GPIO2
    rotation: 90
    lambda: |-
      it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(sntp_time).now());
      it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(sntp_time).now());
      it.circle(120, 120, 115, id(my_red));

UPD: looks like this happens because of #6009 being merged some days ago

Hello! I'm having an issue with the same config. Did you find a way around it?

@bearpawmaxim
Copy link
Contributor

Hello! I'm having an issue with the same config. Did you find a way around it?

We need to wait until PR owner will issue a fix to code.
Until then, you can use my "fork" of this PR this way

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

@jbishop129
Copy link

hey @bearpawmaxim Thanks for lending a hand here.. still getting a compile error using your fork:
AttributeError: module 'esphome.components.display' has no attribute 'DisplayBufferRef'. Did you mean: 'DisplayBuffer'?

Looks like components.display is looking for DisplayBuffer instead of DisplayBufferRef. Is this a quick fix?

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

@ParineetVernekar
Copy link

hey @bearpawmaxim Thanks for lending a hand here.. still getting a compile error using your fork: AttributeError: module 'esphome.components.display' has no attribute 'DisplayBufferRef'. Did you mean: 'DisplayBuffer'?

Looks like components.display is looking for DisplayBuffer instead of DisplayBufferRef. Is this a quick fix?

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

I had the same issue too, I've made my own fork from @bearpawmaxim 's which seemed to work for me

external_components:
  - source: github://ParineetVernekar/esphome@pr3625fix
    components: [gc9a01]

@bearpawmaxim
Copy link
Contributor

still getting a compile error using your fork:

That is strange because it works for me)

@jbishop129
Copy link

@ParineetVernekar Thanks for jumping in. I tried your fork, and get a bit further, but still erroring on a parameter in DisplayBuffer see below:

using:

external_components:
  - source: github://ParineetVernekar/esphome@pr3625fix
    components: [gc9a01]

compile output:

Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_common_loader.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_clock_init.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_flash.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_mem.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_random.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_random_esp32c3.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_utility.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/esp_image_format.o
src/main.cpp: In function 'void setup()':
src/main.cpp:3384:53: error: cannot declare parameter 'it' to be of abstract type 'esphome::display::DisplayBuffer'
   roundOLED1->set_writer([=](display::DisplayBuffer it) -> void {
                              ~~~~~~~~~~~~~~~~~~~~~~~^~
In file included from src/esphome.h:19,
                 from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:15:7: note:   because the following virtual functions are pure within 'esphome::display::DisplayBuffer':
 class DisplayBuffer : public Display {
       ^~~~~~~~~~~~~
In file included from src/esphome/components/api/proto.h:3,
                 from src/esphome/components/api/api_pb2.h:5,
                 from src/esphome/components/api/api_connection.h:4,
                 from src/esphome.h:3,
                 from src/main.cpp:3:
src/esphome/core/component.h:302:16: note: 	'virtual void esphome::PollingComponent::update()'
   virtual void update() = 0;
                ^~~~~~
In file included from src/esphome.h:18,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:434:23: note: 	'virtual esphome::display::DisplayType esphome::display::Display::get_display_type()'
   virtual DisplayType get_display_type() = 0;
                       ^~~~~~~~~~~~~~~~
In file included from src/esphome.h:19,
                 from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:25:15: note: 	'virtual int esphome::display::DisplayBuffer::get_height_internal()'
   virtual int get_height_internal() = 0;
               ^~~~~~~~~~~~~~~~~~~
src/esphome/components/display/display_buffer.h:26:15: note: 	'virtual int esphome::display::DisplayBuffer::get_width_internal()'
   virtual int get_width_internal() = 0;
               ^~~~~~~~~~~~~~~~~~
src/esphome/components/display/display_buffer.h:29:16: note: 	'virtual void esphome::display::DisplayBuffer::draw_absolute_pixel_internal(int, int, esphome::Color)'
   virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<unicode string>:277:4: error: no matching function for call to 'esphome::gc9a01::GC9A01::set_writer(setup()::<lambda(esphome::display::DisplayBuffer)>)'
In file included from src/esphome.h:18,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:411:8: note: candidate: 'void esphome::display::Display::set_writer(esphome::display::display_writer_t&&)'
   void set_writer(display_writer_t &&writer);
        ^~~~~~~~~~
src/esphome/components/display/display.h:411:8: note:   no known conversion for argument 1 from 'setup()::<lambda(esphome::display::DisplayBuffer)>' to 'esphome::display::display_writer_t&&' {aka 'std::function<void(esphome::display::Display&)>&&'}
Compiling .pioenvs/esp32-c3/bootloader_support/src/flash_encrypt.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/secure_boot.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/flash_partitions.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/flash_qio_mode.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_flash_config_esp32c3.o
*** [.pioenvs/esp32-c3/src/main.o] Error 1

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Dec 27, 2023

@jbishop129 , @ParineetVernekar friends, what version of esphome you're using? I'm fine with my "fork" with this config on 2023.12.5. More to say, it is suitable only for this version...
Even tried to clean build files and compile again: it succeeded.
Here's the log of successful build https://hastebin.com/share/akuzayerup.bash

@jbishop129
Copy link

@bearpawmaxim good call. I was running ESPHome 2023.23.0 - DEV, I rolled back to the non-Dev Add-on (2023.12.5) and cleaned build files, unfortunately the same compile error. Seems like it is zoning in on this cannot declare parameter 'it' reference in the DisplayBuffer. Anything stand out here?

Compiling .pioenvs/esp32-c3/app_trace/gcov/gcov_rtio.o
Compiling .pioenvs/esp32-c3/app_update/esp_ota_ops.o
Compiling .pioenvs/esp32-c3/app_update/esp_app_desc.o
Compiling .pioenvs/esp32-c3/bootloader_support/src/bootloader_common.o
src/main.cpp: In function 'void setup()':
src/main.cpp:3384:53: error: cannot declare parameter 'it' to be of abstract type 'esphome::display::DisplayBuffer'
   roundOLED1->set_writer([=](display::DisplayBuffer it) -> void {

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Dec 27, 2023

Anything stand out here?

Nothing unless you specify your config ;)

@jbishop129
Copy link

jbishop129 commented Dec 27, 2023

Anything stand out here?

Nothing unless you specify your config ;)

Fair enough ;) Removed unnecessary part of my display lambda:
EDIT: Adding the full compile output log: below. looks like it doesnt like DisplayBufferRef vs DisplayBuffer

esphome:
  name: esp32-c3
  friendly_name: ESP32-C3
  platform: ESP32
  board: esp32-c3-devkitm-1

  on_boot:
    then:
      - light.turn_on:
          id: backlight
          brightness: 65%

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

logger:

api:
  encryption:
    key: !secret api

ota:
  password: !secret ota

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

  ap:
    ssid: "Esp32-C3 Fallback Hotspot"
    password: !secret ap

spi:
  mosi_pin: GPIO10
  clk_pin: GPIO7

light:
  - platform: monochromatic
    id: backlight
    name: "Backlight"
    output: pwm_output

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

#########
# Fonts
#########
font:
  - file: 'fonts/Google_Sans_Regular.ttf'
    id: font_16
    size: 16

  - file: 'fonts/Google_Sans_Regular.ttf'
    id: font_32
    size: 32

  - file: 'fonts/Google_Sans_Regular.ttf'
    id: font_48
    size: 48

  - file: 'fonts/Google_Sans_Regular.ttf'
    id: font_80
    size: 80

## Weather icons - Size 46
  - file: 'fonts/mdi.ttf'
    id: icon_weather
    size: 46
    glyphs: [
      "\U000F0590", # mdi-weather-cloudy
      "\U000F0F2F", # mdi-weather-cloudy-alert
      "\U000F0E6E", # mdi-weather-cloudy-arrow-right
      "\U000F0591", # mdi-weather-fog
      "\U000F0592", # mdi-weather-hail
      "\U000F0F30", # mdi-weather-hazy
      "\U000F0898", # mdi-weather-hurricane
      "\U000F0593", # mdi-weather-lightning
      "\U000F067E", # mdi-weather-lightning-rainy
      "\U000F0594", # mdi-weather-night
      "\U000F0F31", # mdi-weather-night-partly-cloudy
      "\U000F0595", # mdi-weather-partly-cloudy
      "\U000F0F32", # mdi-weather-partly-lightning
      "\U000F0F33", # mdi-weather-partly-rainy
      "\U000F0F34", # mdi-weather-partly-snowy
      "\U000F0F35", # mdi-weather-partly-snowy-rainy
      "\U000F0596", # mdi-weather-pouring
      "\U000F0597", # mdi-weather-rainy
      "\U000F0598", # mdi-weather-snowy
      "\U000F0F36", # mdi-weather-snowy-heavy
      "\U000F067F", # mdi-weather-snowy-rainy
      "\U000F0599", # mdi-weather-sunny
      "\U000F0F37", # mdi-weather-sunny-alert
      "\U000F14E4", # mdi-weather-sunny-off
      "\U000F059A", # mdi-weather-sunset
      "\U000F059B", # mdi-weather-sunset-down
      "\U000F059C", # mdi-weather-sunset-up
      "\U000F0F38", # mdi-weather-tornado
      "\U000F059D", # mdi-weather-windy
      "\U000F059E", # mdi-weather-windy-variant
      ]

# ## Other icons - Size 32
  - file: 'fonts/mdi.ttf'
    id: icon_32
    size: 32
    glyphs: [
      "\U000F000E", # mdi-account-multiple
    ]  

##################
# Sensors from HA
##################
time:
  - platform: sntp
    id: my_time
    timezone: America/Phoenix

sensor:
  - platform: homeassistant
    id: outside_temp_dht22
    entity_id: sensor.dht22_temp

  - platform: homeassistant
    id: openweather_temp
    entity_id: sensor.openweathermap_temp_rounded

  - platform: homeassistant
    id: spa_temp
    entity_id: sensor.pool_temp

binary_sensor:
  - platform: homeassistant
    id: office_motion
    entity_id: binary_sensor.office_motion_sensor

  - platform: homeassistant
    id: spa_heater
    entity_id: switch.pool_spa
  
text_sensor:
  - platform: homeassistant
    id: weather
    entity_id: weather.openweathermap
    internal: true

  - platform: homeassistant
    name: Readable_time
    entity_id: sensor.12h_time
    id: readable_ha_time

color:
  - id: yellow
    hex: FFC300

  - id: light_gray
    hex: DEDEDE

display:
  - platform: gc9a01
    id: roundOLED1
    reset_pin: GPIO4
    cs_pin: GPIO6
    dc_pin: GPIO5
    rotation: 90
    
    lambda: |-
 ... trimmed out my display lambda.. not relevant... 

compile error:

INFO ESPHome 2023.12.5
INFO Reading configuration /config/esphome/esp32-c3.yaml...
INFO Generating C++ source...
Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 33, in <module>
    sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1041, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1028, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 458, in command_run
    exit_code = write_cpp(config)
                ^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 192, in write_cpp
    generate_cpp_contents(config)
  File "/esphome/esphome/__main__.py", line 204, in generate_cpp_contents
    CORE.flush_tasks()
  File "/esphome/esphome/core/__init__.py", line 679, in flush_tasks
    self.event_loop.flush_tasks()
  File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "/esphome/esphome/__main__.py", line 184, in wrapped
    await coro(conf)
  File "/data/external_components/ad3b3ff5/esphome/components/gc9a01/display.py", line 76, in to_code
    await setup_gc9a01(var, config)
  File "/data/external_components/ad3b3ff5/esphome/components/gc9a01/display.py", line 62, in setup_gc9a01
    config[CONF_LAMBDA], [(display.DisplayBufferRef, "it")], return_type=cg.void
                           ^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'esphome.components.display' has no attribute 'DisplayBufferRef'. Did you mean: 'DisplayBuffer'?

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Dec 27, 2023

compile error

I've managed to compile your code on 2023.12.5 with the @ParineetVernekar's version. Until the code from this PR isn't merged it is better to use it.

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

@jbishop129
Copy link

compile error

I've managed to compile your code on 2023.12.5 with the @ParineetVernekar's version. Until the code from this PR isn't merged it is better to use it.

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

Really appreciate your time and attention on this. I'm still getting a different compile error when using Parineet's version as well, however if you are able to compile, I will take this aside to work further on my own. I don't want to treat this area as a troubleshooting forum :)

@jbishop129
Copy link

Some progress made: It turns out the code I gave you above with the redacted display content after lambda: |- Is actually the key point where it fails. If you insert anything in the lambda: it will fail to compile (example hello world one-liners, basic if/then, etc.) and dump the error below. Seems to be having a hard time with the display initiation. @bearpawmaxim I wonder if you just add a simple:

    lambda: |-
      // Outside Temp
      if (id(openweather_temp).has_state()) {
        it.printf(120,210, id(font_32), TextAlign::CENTER, "%.0f°F", id(openweather_temp).state);
        it.printf(115,230, id(font_16), TextAlign::CENTER, "Outside");
      }

do you get a compile error like this?

|-- SPI @ 2.0.0
Compiling .pioenvs/esp32-s2/src/main.cpp.o
src/main.cpp: In function 'void setup()':
src/main.cpp:3319:53: error: cannot declare parameter 'it' to be of abstract type 'esphome::display::DisplayBuffer'
   roundOLED1->set_writer([=](display::DisplayBuffer it) -> void {
                              ~~~~~~~~~~~~~~~~~~~~~~~^~
In file included from src/esphome.h:21,
                 from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:15:7: note:   because the following virtual functions are pure within 'esphome::display::DisplayBuffer':
 class DisplayBuffer : public Display {
       ^~~~~~~~~~~~~
In file included from src/esphome/components/api/proto.h:3,
                 from src/esphome/components/api/api_pb2.h:5,
                 from src/esphome/components/api/api_connection.h:4,
                 from src/esphome.h:3,
                 from src/main.cpp:3:
src/esphome/core/component.h:302:16: note: 	'virtual void esphome::PollingComponent::update()'
   virtual void update() = 0;
                ^~~~~~
In file included from src/esphome.h:20,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:449:23: note: 	'virtual esphome::display::DisplayType esphome::display::Display::get_display_type()'
   virtual DisplayType get_display_type() = 0;
                       ^~~~~~~~~~~~~~~~
In file included from src/esphome.h:21,
                 from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:25:15: note: 	'virtual int esphome::display::DisplayBuffer::get_height_internal()'
   virtual int get_height_internal() = 0;
               ^~~~~~~~~~~~~~~~~~~
src/esphome/components/display/display_buffer.h:26:15: note: 	'virtual int esphome::display::DisplayBuffer::get_width_internal()'
   virtual int get_width_internal() = 0;
               ^~~~~~~~~~~~~~~~~~
src/esphome/components/display/display_buffer.h:29:16: note: 	'virtual void esphome::display::DisplayBuffer::draw_absolute_pixel_internal(int, int, esphome::Color)'
   virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<unicode string>:180:4: error: no matching function for call to 'esphome::gc9a01::GC9A01::set_writer(setup()::<lambda(esphome::display::DisplayBuffer)>)'
In file included from src/esphome.h:20,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:426:8: note: candidate: 'void esphome::display::Display::set_writer(esphome::display::display_writer_t&&)'
   void set_writer(display_writer_t &&writer);
        ^~~~~~~~~~
src/esphome/components/display/display.h:426:8: note:   no known conversion for argument 1 from 'setup()::<lambda(esphome::display::DisplayBuffer)>' to 'esphome::display::display_writer_t&&' {aka 'std::function<void(esphome::display::Display&)>&&'}
*** [.pioenvs/esp32-s2/src/main.cpp.o] Error 1

@bearpawmaxim
Copy link
Contributor

Is actually the key point where it fails

Yes. I got the same thing.. Will investigate in it.

@tiimsvk
Copy link

tiimsvk commented Dec 29, 2023

hello another compilation error. commented here: https://github.com/landonr/lilygo-tdisplays3-esphome/pull/46

Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 33, in <module>
    sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1041, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1028, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 458, in command_run
    exit_code = write_cpp(config)
                ^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 192, in write_cpp
    generate_cpp_contents(config)
  File "/esphome/esphome/__main__.py", line 204, in generate_cpp_contents
    CORE.flush_tasks()
  File "/esphome/esphome/core/__init__.py", line 679, in flush_tasks
    self.event_loop.flush_tasks()
  File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "/esphome/esphome/__main__.py", line 184, in wrapped
    await coro(conf)
  File "/config/esphome/custom_component/gc9a01/display.py", line 78, in to_code
    await setup_gc9a01(var, config)
  File "/config/esphome/custom_component/gc9a01/display.py", line 56, in setup_gc9a01
    await display.register_display(var, config)
  File "/esphome/esphome/components/display/__init__.py", line 119, in register_display
    await cg.register_component(var, config)
  File "/esphome/esphome/cpp_helpers.py", line 56, in register_component
    raise ValueError(
ValueError: Component ID round_display was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.

Do you happen to know how to fix it?

@bearpawmaxim
Copy link
Contributor

hello another compilation error
@tiimsvk just use my "fork"

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

@jbishop129, @ParineetVernekar I've fixed lambda in my fork, so you're free to use it.

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Dec 30, 2023

@4cello hi! I'm getting the weird issue while trying to use 16-bit color (eight_bit_color: false)
20231230_201040

Do you have any ideas about what can be wrong?
P.S.: maybe it's time to complete with this PR?
P.P.S.: my display works with 80MHz spi (done in my fork, so it definitely works for other people)

@jbishop129
Copy link

  • source: github://bearpawmaxim/esphome@pr3625fix
    components: [gc9a01]

Success! Thank you very much @bearpawmaxim I have this running on an ESP32 C3, display is working!

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Jan 4, 2024

I'm getting the weird issue while trying to use 16-bit color

The issue was in uint16_t overflow while calculating buffer position. Fixed in my fork.

P.S.: the benefit of using the 16bit mode are x2 drawing speed while using x2 memory (115200 bytes) and more essential colors. It is ok if you have 250+ kbytes of ram

@tiimsvk
Copy link

tiimsvk commented Jan 4, 2024

hello another compilation error
@tiimsvk just use my "fork"

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

@jbishop129, @ParineetVernekar I've fixed lambda in my fork, so you're free to use it.

Hi after update to esphome 12.5 and using this plugin, the display flickers during the update (the RGB color of some brightness blocks changes, etc. as if there is a bad power supply).
After installing back to 11.6 everything works as it should
what changed in the code? can you make the code available so that I can download it manually and compare?
well thank you

@bearpawmaxim
Copy link
Contributor

the display flickers during the update

It may be related to the 80MHz spi speed I've set for the display. Try to lower it from spi::DATA_RATE_80MHZ to spi::DATA_RATE_40MHZ in gc9a01.h and see if it would help. If not - set to spi::DATA_RATE_20MHZ

The code can be downloaded from here

@tiimsvk
Copy link

tiimsvk commented Jan 6, 2024

the display flickers during the update

It may be related to the 80MHz spi speed I've set for the display. Try to lower it from spi::DATA_RATE_80MHZ to spi::DATA_RATE_40MHZ in gc9a01.h and see if it would help. If not - set to spi::DATA_RATE_20MHZ

The code can be downloaded from here

got you

On old file is speed spi is 8Mhz (also works 20MHz, I haven't tried anything else)
spi::DATA_RATE_8MHZ> {

And another problem is color on display: RGB scheme is changed
Fix this problem replace old file gc9a01.cpp

  if (this->eightbitcolor_) {
    const uint32_t color332 = display::ColorUtil::color_to_332(color);
//    const uint32_t color332 = display::ColorUtil::color_to_332(color,
//      display::ColorOrder::COLOR_ORDER_BGR);
    uint16_t pos = (x + y * this->get_width_internal());
    this->buffer_[pos] = color332;
  } else {
    const uint32_t color565 = display::ColorUtil::color_to_565(color);
    uint16_t pos = (x + y * this->get_width_internal()) * 2;
//    const uint32_t color565 = display::ColorUtil::color_to_565(color,
//      display::ColorOrder::COLOR_ORDER_BGR);
//    uint32_t pos = (x + y * this->get_width_internal()) * 2;
    this->buffer_[pos++] = (color565 >> 8) & 0xff;
    this->buffer_[pos] = color565 & 0xff;
  }

@bearpawmaxim
Copy link
Contributor

bearpawmaxim commented Jan 7, 2024

RGB scheme is changed

This is strange because on my side these lines fixes the colors in 16 bit mode (blue was red and red was blue).

@bearpawmaxim
Copy link
Contributor

RGB scheme is changed

@tiimsvk
Oh, I've found the issue! While fixing the color displacement in 16bit mode, I occasionally broke the 8bit mode))). Now everything is fixed in my fork.

About your flickering. Did lowering the frequency fixed your issue?
I have an idea that it may happen because of an addition of the display buffer. I assume that there was no display buffer on 11.6.. If so, then I can't help you a lot, unfortunately..
The last thing to try (only if you have 250kb + of ram on your device) is to set eight_bit_color: false in your display config.

@clydebarrow
Copy link
Contributor

#6351 adds GC9A01A support to the ili9xxx driver. Closing this one.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet