Help needed to get this tiny screen working - ESP32-c6 1.47in display

I’m trying to make the ESPHome initialization via the serial port of an ESP32C6.

https://web.esphome.io/
When I attempt to use the “Prepare for First Use” button on the main web page a box reports:

Error: Unsupported platform ESP32C6.
Only …S2, …S3, …C3 are supported.

How were you able to upload to ESP32C6?

My thanks

Taken from discord group. Only issue is it sets the flash as 8MB instead of 4MB but it seems to work. Having issues with the screen but everything else is working

esphome:
name: esp32c6new
friendly_name: esp32c6new
platformio_options:
platform: https://github.com/platformio/platform-espressif32/archive/refs/tags/v6.7.0.zip
board_build.f_cpu: 160000000L
board_build.f_flash: 80000000L
board_build.flash_size: 4MB
build_flags: “-DBOARD_HAS_PSRAM”
board_build.arduino.memory_type: qio_opi

esp32:
board: esp32-c6-devkitm-1
variant: esp32c6
framework:
type: esp-idf
version: 5.2.1
platform_version: 6.7.0
# version: latest
sdkconfig_options:
CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y

Dont want to read the long text ?
Scroll down to EDIT 2 :wink:

I am also trying to get this little screen in esphome

but after successful connection it stuck on the “circle of dead” with “Preparing Installation”

grafik

.

  • Mac Mini M4 with Mac OS 15.3
  • Chrome Version 133.0.6943.54 (Offizieller Build) (arm64)
  • Connected via Nabu Casa (https)
  • CP210x and CH34x Driver are installed (both, to make sure)
    grafik
  • entered boot mode by holding the boot button while powering up (screen is black instead of showing the demo)

I already tried to uninstall and reinstall esphome

I tried this config:

esphome:
  name: esp32c6new
  friendly_name: esp32c6new
  platformio_options:
    platform: https://github.com/platformio/platform-espressif32/archive/refs/tags/v6.7.0.zip
    board_build.f_cpu: 160000000L
    board_build.f_flash: 80000000L
    board_build.flash_size: 4MB
    build_flags: “-DBOARD_HAS_PSRAM”
    board_build.arduino.memory_type: qio_opi

esp32:
  board: esp32-c6-devkitm-1
  variant: esp32c6
  framework:
    type: esp-idf
    version: 5.2.1
    platform_version: 6.7.0
    # version: latest
    sdkconfig_options:
      CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y

and also this config: (found on the esp github page)

esphome:
  name: esp32c6new
  friendly_name: esp32c6new
  platformio_options: 
    build_flags: "-DI2C_NUM_1=I2C_NUM_0"

esp32:
  board: esp32-c6-devkitc-1
  # flash_size: 4MB
  variant: esp32c6
  framework:
    type: esp-idf
    version: "5.3.1"
    platform_version: 6.9.0

Any ideas ?

EDIT:

After some time (for the 1st code block) I got this message:

grafik

If I click on “See what went wrong”
I get this log:

EDIT 2:

With this code

esphome:
  name: esp32c6new
  friendly_name: esp32c6new

esp32:
  board: esp32-c6-devkitc-1
  variant: esp32c6
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESPTOOLPY_FLASHSIZE_8MB: y
    version: 5.1.2
    platform_version: 6.5.0
    source: https://github.com/tasmota/esp-idf/releases/download/v5.1.2.240221/esp-idf-v5.1.2.zip

I was able to compile. It was complaining about the 8MB size but its working.

with

spi:
  clk_pin: GPIO7
  mosi_pin: GPIO6

display:
  - platform: st7789v
    model: CUSTOM
    dc_pin: GPIO15
    height: 320
    width: 172
    offset_height: 34
    offset_width: 0
    cs_pin: GPIO14
    reset_pin: GPIO21
    backlight_pin: GPIO22
    spi_mode: 3
    data_rate: 4000000.0
    id: tft_ha
    lambda: |-
      // Draw a circle in the middle of the display
      it.filled_circle(it.get_width() / 2, it.get_height() / 2, 20);

its drawing the circle in the middle of the screen.

Thanks to all contributors.
It does work now. Took hours but the code below works!
For beginners like me - First time install:
Write the yaml file and then complile manually to make a download bin file.
Plug the ESP32C6-lcd into your PC - check there’s a COM port has come up.
Now, using Chrome on Esphome Web connect and download the bin file to the COM port.
It should reboot and show some text!

After first file write then you can upload wirelessly on subsequent ones if you’ve set wifi correctly and esphome can find it.
I had issues with an error coming up that there was a lock file for a long time.
I had to delete the original file, paste the yaml into a new one and then manually connect again.

The next long waste of time was the unit needs to be ‘added in’ the esphome integration to be able to send data from homeassistant to it. Otherwise the sensor info comes up as nan.

p.s. Remember to ask an AI because they seem to be good at finding some useful hints.

esphome:
  name: esp32-lcd
  friendly_name: Esp32-LCD

esp32:
  board: esp32-c6-devkitc-1
  variant: esp32c6
  framework:
    type: esp-idf
    version: 5.1.2
    platform_version: 6.5.0
    sdkconfig_options:
      CONFIG_ESPTOOLPY_FLASHSIZE_8MB: y
    source: https://github.com/tasmota/esp-idf/releases/download/v5.1.2.240221/esp-idf-v5.1.2.zip

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

# snip - other parts in here to deal with fonts, colours, sensors etc taken from homeassistant to display on the screen.
# It didn't need another 'backlight' setting statement. Data rate doesn't seem to matter if 4000000 or 5000000

spi:
  clk_pin: GPIO7
  mosi_pin: GPIO6

display:
  - platform: st7789v
    model: Waveshare 1.47in 172X320
    dc_pin: GPIO15
    cs_pin: GPIO14
    reset_pin: GPIO21
    backlight_pin: GPIO22
    spi_mode: 3
    data_rate: 5000000.0
    update_interval: 1s
    id: tft_ha
    rotation: 270
    lambda: |-
      it.rectangle(0,  0, it.get_width(), it.get_height(), id(my_blue));
      it.rectangle(0, 28, it.get_width(), it.get_height(), id(my_blue));   // header bar
      it.strftime(15, 2, id(helvetica_24), id(my_gray), TextAlign::LEFT, "%Y-%m-%d", id(esptime).now());
      it.strftime(160, 2, id(helvetica_24), id(my_gray), TextAlign::LEFT, "%H:%M:%S", id(esptime).now());
      it.print(10, 35, id(helvetica_24), id(my_red), "Electrical Power");
      it.printf(10, 65, id(arial), id(my_gray), "G1:%.0fW G1k:%.0fW G1w:%.0fW", id(g1_power).state, id(g1k_power).state, id(g1w_power).state);
      it.printf(10, 85, id(arial), id(my_gray), "G2:%.0fW G2f:%.0fW G2ts:%.0fW", id(g2_power).state, id(g2f_power).state, id(g2ts_power).state);


You’re going to have to define the sensors and colours and time output but they should be fairly easy. Sample here:

time:
  - platform: homeassistant
    id: esptime

sensor:
  - platform: homeassistant
    id: g1_power
    entity_id: sensor.g1_c0_main_power_minute_average
# these bits below don't seem to matter if in or not
    unit_of_measurement: "W"
    state_class: "measurement"
    internal: true

Here’s my config that reports the wifi signal, home assistant API connection and the temperature and humidity index from my Bambu Lab AMS.

Feel free to change the font files for your own liking.

My working config:

substitutions:
  friendly_name: "ESP32-C6-LCD-1.47"
  device_name: esp32-c6-lcd-147
  id: esp32_c6_lcd_147
  area: Home Assistant
  device_description: ""
  bt_proxy: "false"
  logger: "DEBUG"
  # logger: "VERY_VERBOSE"

  vendor: "Waveshare"
  model: "ESP32-C6-LCD-1-47in"
  device_version: "v"
  microcontroller: "ESP32-C6FH4 (QFN32) (revision v0.1)"
  frequency: "160MHz"
  ram: "512KB"
  rom: "320KB"
  hp_sram: "512KB"
  lp_sram: "16KB"
  flash: "4MB"
  features: "WiFi 6, BT 5, Thread (802.15.4)"
  crystal: "40MHz"
  mac: "9c:9e:6e:ff:fe:76:51:a8"
  base_mac: "9c:9e:6e:76:51:a8"
  mac_ext: "ff:fe"

  # i2c
  i2c_id: bus_a
  sda: GPIO1
  scl: GPIO2
  scan: "false"
  # SPI bus for LCD and SD Card
  miso_pin: GPIO5
  mosi_pin: GPIO6
  clk_pin: GPIO7
  # LCD Pinout
  lcd_cs_pin: GPIO14
  lcd_dc_pin: GPIO15
  lcd_reset_pin: GPIO21
  lcd_backlight_pin: GPIO22
  # SD Card
  sd_cs_pin: GPIO4
  # LED
  rgb_led: GPIO8
  # One Wire
  one_wire: GPIO10

i2c:
  - id: $i2c_id
    sda: $sda
    scl: $scl
    scan: False

spi:
  clk_pin: $clk_pin
  miso_pin: $miso_pin
  mosi_pin: $mosi_pin

one_wire:
  - pin: $one_wire
    platform: gpio

esp32:
  board: esp32-c6-devkitc-1
  variant: esp32c6
  flash_size: 4MB
  framework:
    type: esp-idf
    version: 5.3.1
    platform_version: 6.9.0
    sdkconfig_options:
      CONFIG_ESPTOOLPY_FLASHSIZE_DETECT: y
      CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y
      CONFIG_OPENTHREAD_ENABLED: n
      CONFIG_USE_MINIMAL_MDNS: y
      # Memory optimization
      COMPILER_OPTIMIZATION_SIZE: y
      COMPILER_OPTIMIZATION_LEVEL_RELEASE: y
      CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE: y
      CONFIG_HEAP_POISONING_DISABLED: y

esphome:
  friendly_name: $friendly_name
  name: $id
  name_add_mac_suffix: false
  comment: "${device_description}"
  area: $area
  project:
    name: "${vendor}.${model}"
    version: "${device_version}"
  platformio_options:
    board_build.flash_mode: dio
    build_flags:
      - "-DI2C_NUM_1=I2C_NUM_0"
      - "-DBOARD_HAS_PSRAM"
      - "-Wl,-Map,output.map"
    board_build.arduino.memory_type: qio_opi
    platform_packages:
      - platformio/toolchain-xtensa-esp-elf @ 14.2.0+20241119

logger:
  level: $logger

api:
  id: api_id
  reboot_timeout: 300s
  on_client_connected:
    if:
      condition:
        api.connected:
      then:
        - logger.log:
            format: "API Connection: %s [%s]"
            args: ["client_info.c_str()", "client_address.c_str()"]
  on_client_disconnected:
    - logger.log: 
        format: "API Disonnection: %s [%s]"
        args: ["client_info.c_str()", "client_address.c_str()"]

ota:
  - platform: esphome
    id: ota_esphome

safe_mode:
  on_safe_mode:
    - logger.log: "Safe Mode Activated"

wifi:
  id: wifi_id
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: off
  reboot_timeout: 5min
  power_save_mode: HIGH
  # ap:
  #   ssid: "${friendly_name} Fallback"
  #   password: !secret wifi_ap_password
  #   manual_ip:
  #     static_ip: $static_ip
  #     gateway: !secret gateway
  #     subnet: !secret subnet
  #     dns1: !secret dns1
  #     dns2: !secret dns2
  #   ap_timeout: 5min
  on_connect:
    then:
      - logger.log: "WiFi connected"
  on_disconnect:
    then:
      - logger.log: "WiFi disconnected"
  # ESP-IDF ONLY https://esphome.io/components/wifi.html
  # Enable 802.11v BSS Transition Management support.
  enable_btm: true
  # Enable 802.11k Radio Resource Management support.
  enable_rrm: true

network:
  enable_ipv6: False

# https://esphome.io/components/esp32_ble_tracker
# Enable Bluetooth Proxying
esp32_ble_tracker:
  id: ble_tracker
  scan_parameters:
    interval: 1100ms
    window: 1100ms
    active: ${bt_proxy}
    continuous: false
  on_scan_end:
    - then:
        - lambda: |-
             ESP_LOGD("ble_auto", "The scan has ended!");

# https://esphome.io/components/bluetooth_proxy.html
bluetooth_proxy:
  id: ble_proxy
  # Enables proxying active connections. Defaults to false.
  active: ${bt_proxy}
  cache_services: true

# https://esphome.io/components/esp32_improv.html
esp32_improv:
  authorizer: none
  on_start:
    then:
      - logger.log: "Improv awaiting authorization/authorized"
  on_provisioning:
    then:
      - logger.log: "Improv provisioning"
  on_provisioned:
    then:
      - logger.log: "Improv provisioned"
  on_stop:
    then:
      - logger.log: "Improv stopped"
  on_state:
    then:
      - if:
          condition:
            lambda: return state == improv::STATE_AUTHORIZED;
          then:
            - logger.log: "Improv state is STATE_AUTHORIZED"


# https://esphome.io/components/improv_serial
improv_serial:
  
# https://esphome.io/components/captive_portal
# captive_portal:

# deep_sleep:
#   run_duration: 2min   # Time the device stays awake
#   sleep_duration: 28min  # Time the device sleeps

text_sensor:
  # ESPHome Version
  - platform: version
    name: "ESPHome Version"
    id: "${id}_esphome_version"
    icon: si:esphomes
    hide_timestamp: 'true'
    entity_category: diagnostic
  # WiFi Info: IP, MAC, SSID, BSSID, Scan
  - platform: wifi_info
    ip_address:
      name: "IP Address"
      icon: mdi:ip
      entity_category: diagnostic
      update_interval: never
      disabled_by_default: True
    mac_address:
      name: "WiFi MAC Address"
      icon: mdi:fingerprint
      entity_category: diagnostic
      disabled_by_default: True
    ssid:
      name: "Connected SSID"
      icon: mdi:wifi-settings
      entity_category: diagnostic
      update_interval: never
      disabled_by_default: True
    bssid:
      name: "Connected BSSID"
      icon: mdi:wifi
      entity_category: diagnostic
      update_interval: never
      disabled_by_default: True
    scan_results:
      name: "Latest Scan Results"
      icon: mdi:wifi-sync
      entity_category: diagnostic
      disabled_by_default: True

binary_sensor:
  # https://esphome.io/components/binary_sensor/status.html
  # Reports if this device is Connected or not
  - platform: status
    name: "Status"
    id: "${id}_status"
    icon: mdi:check-network
    entity_category: diagnostic

button:
  # Remotely reboot your node into Safe Mode.
  # https://esphome.io/components/switch/safe_mode.html
  - platform: safe_mode
    name: "(Safe Mode)"
    icon: mdi:restart-alert
    id: "${id}_safe_mode"
    entity_category: config
    disabled_by_default: True
  # Restart
  - platform: restart
    name: "Restart"
    icon: mdi:restart
    id: "${id}_restart"
    # entity_category: diagnostic
    disabled_by_default: True
  # Shutdown
  - platform: shutdown
    name: "Shutdown"
    id: "${id}_shutdown"
    # entity_category: diagnostic
    disabled_by_default: True

light:
  # RGB LED
  - platform: esp32_rmt_led_strip
    pin:
      number: $rgb_led
      ignore_strapping_warning: true
    name: "RGB LED"
    id: rgb_led
    chipset: ws2812
    rmt_channel: 0
    num_leds: 1
    rgb_order: RGB
    # gamma_correct: 2.8
    default_transition_length: 2s
    restore_mode: RESTORE_DEFAULT_OFF
    effects:
      - random:
      - random:
          name: "My Slow Random Effect"
          transition_length: 30s
          update_interval: 30s
      - random:
          name: "My Fast Random Effect"
          transition_length: 4s
          update_interval: 5s
      - pulse:
      - pulse:
          name: "Fast Pulse"
          transition_length: 0.5s
          update_interval: 0.5s
          min_brightness: 0%
          max_brightness: 100%
      - pulse:
          name: "Slow Pulse"
          transition_length: 500ms
          update_interval: 2s
      - pulse:
          name: "Asymmetrical Pulse on1s off500ms"
          transition_length:
            on_length: 1s
            off_length: 500ms
          update_interval: 1.5s
      - strobe:
      - strobe:
          name: "Strobe Effect br100 r100g90b0 250/500"
          colors:
            - state: true
              brightness: 100%
              red: 100%
              green: 90%
              blue: 0%
              duration: 500ms
            - state: false
              duration: 250ms
            - state: true
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
      - flicker:
      - flicker:
          name: "Flicker a95 i1.5"
          alpha: 95%
          intensity: 1.5%
      - addressable_rainbow:
      - addressable_rainbow:
          name: "Rainbow w12"
          width: 12
      - addressable_rainbow:
          name: "Rainbow sp10 w50"
          speed: 10
          width: 50
      - addressable_color_wipe:
      - addressable_color_wipe:
          name: "Color Wipe r100g100b100 100ms"
          colors:
            - red: 100%
              green: 100%
              blue: 100%
              num_leds: 1
              gradient: true
            - red: 0%
              green: 0%
              blue: 0%
              num_leds: 1
          add_led_interval: 100ms
          reverse: false
      - addressable_scan:
      - addressable_scan:
          name: "Scan Effect i100ms w1"
          move_interval: 100ms
          scan_width: 1
      - addressable_twinkle:
      - addressable_twinkle:
          name: "Twinkle p5 i4ms"
          twinkle_probability: 5%
          progress_interval: 4ms #default 4ms
      - addressable_twinkle:
          name: "Twinkle p50 i4ms"
          twinkle_probability: 50%
      - addressable_random_twinkle:
      - addressable_random_twinkle:
          name: "Random Twinkle p50 i32ms"
          twinkle_probability: 5%
          progress_interval: 32ms
      - addressable_fireworks:
      - addressable_fireworks:
          name: "Fireworks sp10% fade120 i32ms"
          spark_probability: 10%
          use_random_color: false
          fade_out_rate: 120
          update_interval: 32ms
      - addressable_flicker:
      - addressable_flicker:
          name: Flicker Effect With Custom Values
          update_interval: 16ms
          intensity: 5%
      - addressable_lambda:
          name: "Error"
          update_interval: 10ms
          lambda: |-
            static uint8_t brightness_step = 0;
            static bool brightness_decreasing = true;
            static uint8_t brightness_step_number = 10;
            if (initial_run) {
              brightness_step = 0;
              brightness_decreasing = true;
            }
            Color error_color(255, 0, 0);
            for (int i = 0; i < 12; i++) {
              it[i] = error_color * uint8_t(255/brightness_step_number*(brightness_step_number-brightness_step));
            }
            if (brightness_decreasing) {
              brightness_step++;
            } else {
              brightness_step--;
            }
            if (brightness_step == 0 || brightness_step == brightness_step_number) {
              brightness_decreasing = !brightness_decreasing;
            }

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

sensor:
  - platform: uptime
    type: timestamp
    name: Uptime
    entity_category: diagnostic
  # WiFi Signal sensor
  - platform: wifi_signal
    name: WiFi Signal
    id: wifi_signal_db
    icon: mdi:wifi-strength-outline
    entity_category: diagnostic
    update_interval: 30s
    disabled_by_default: True
  - platform: copy 
    source_id: wifi_signal_db
    name: "WiFi Signal Percent"
    id: wifi_signal_percent
    icon: mdi:wifi-strength-outline
    unit_of_measurement: "%"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    entity_category: "diagnostic"
    device_class: ""
    disabled_by_default: True
  - platform: uptime
    type: seconds
    name: Uptime Sensor
    entity_category: diagnostic
  - platform: internal_temperature
    entity_category: diagnostic
    name: "Internal Temperature"

  - platform: homeassistant
    name: AMS_Temperature
    entity_id: sensor.ams_temperature
    id: ams_temperature
    internal: true
    unit_of_measurement: "°F"

  - platform: homeassistant
    name: Humidity Index
    entity_id: sensor.ams_humidity_index
    id: ams_humidity_index
    internal: true

font:
  - file: "common/fonts/8-bit-nintendo.ttf"
    id: nes_1x
    size: 7 # Pixel Perfect
  - file: "common/fonts/8-bit-nintendo.ttf"
    id: nes_2x
    size: 14
  # - file: "common/fonts/8-bit-nintendo.ttf"
  #   id: nes_3x
  #   size: 21
  # - file: "common/fonts/8-bit-nintendo.ttf"
  #   id: nes_4x
  #   size: 28
  # - file: "common/fonts/gotham-Light-webfont.ttf"
  #   id: gotham_lt
  #   size: 25
  - file: "common/fonts/gotham-Medium-webfont.ttf"
    id: gotham_md
    size: 60
  # - file: "common/fonts/gotham-Black-webfont.ttf"
  #   id: gotham_b
  #   size: 30

image:
    # Home Assistant Logo
  - file: mdi:home-assistant
    id: home_assistant_logo
    # resize: 35x35
  - file: mdi:home-assistant
    id: home_assistant_logo_l
    resize: 150x150
    # WiFi
  - file: mdi:signal-cellular-3
    id: wifi_3
    # resize: 35x35
  - file: mdi:signal-cellular-2
    id: wifi_2
    # resize: 35x35
  - file: mdi:signal-cellular-1
    id: wifi_1
    # resize: 35x35
  - file: mdi:signal-cellular-outline
    id: wifi_0
    # resize: 35x35
  - file: mdi:signal-off
    id: wifi_off
    resize: 150x150
    # Temperature
  - file: mdi:thermometer-low
    id: temp_low
    resize: 200x200
  - file: mdi:thermometer
    id: temp_med
    resize: 200x200
  - file: mdi:thermometer-high
    id: temp_high
    resize: 200x200
    # Humidity
  - file: mdi:water
    id: water_drop
    resize: 100x100
  # - file: mdi:water-percent
  #   id: hum_icon
  #   resize: 30x30
  # - file: mdi:water-percent-alert
  #   id: hum_icon_alert
  #   resize: 30x30

output:
  - platform: ledc
    pin: $lcd_backlight_pin
    id: lcd_backlight
    frequency: 1000 Hz

number:
  - platform: template
    name: "Display Brightness"
    id: display_brightness
    optimistic: true
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 100
    restore_value: true
    mode: slider
    on_value:
      then:
        - output.set_level:
            id: lcd_backlight
            level: !lambda "return x / 100.0;"

# https://esphome.io/components/display/
# TFT Display (ST7789)
display:
  - platform: st7789v
    cs_pin: $lcd_cs_pin
    dc_pin:
      number: $lcd_dc_pin
      ignore_strapping_warning: true
    reset_pin: $lcd_reset_pin
    model: Waveshare 1.47in 172X320
    id: tft_ha
    rotation: 0
    lambda: |-
      ESP_LOGD("display", "Display update running");
      auto black = Color(0, 0, 0);
      auto gray = Color(128, 128, 128);
      auto red = Color(255, 0, 0);
      auto orange = Color(255, 165, 0);
      auto yellow = Color(255, 255, 0);
      auto green = Color(0, 255, 0);
      auto blue = Color(0, 0, 255);
      auto hablue = Color(3, 169, 244);
      auto white = Color(255, 255, 255);

      // Check if the HA time text sensor is available
      // if (id(readable_ha_time).has_state() && id(readable_ha_time).state.length() > 0) {
        // Print time from HA text sensor
      //   it.printf(it.get_width()/2, 10, id(nes_1x), TextAlign::TOP_CENTER, "%s", id(readable_ha_time).state.c_str());
      // } else {
        // Fallback to time from ESPHome's `homeassistant_time`
        auto cur_time = id(homeassistant_time).now();
        if (cur_time.is_valid()) {
          auto hour = cur_time.hour;
          auto ampm = "am";
          // Convert military time to standard AM/PM format
          if (hour > 12) hour = hour - 12;
          if (hour >= 12) ampm = "pm";
          if (hour == 0) hour = 12; // Midnight adjustment
          // Print formatted time
          // it.printf(it.get_width()/2, -10, id(nes_2x), TextAlign::TOP_CENTER, "%2d:%02d %s", hour, cur_time.minute, ampm);
          it.printf(it.get_width()/2, -8, id(nes_2x), TextAlign::TOP_CENTER, "%2d:%02d", hour, cur_time.minute);
        } else {}
      // }
      
      // Determine the appropriate WiFi icon
      if (!id(wifi_signal_percent).has_state()) {
        // Display WiFi off icon when disconnected
        it.image(it.get_width()/2, it.get_height()/2, id(wifi_off), ImageAlign::CENTER, gray);
      } else {
        // Home Assistant API Connection Status
        if (!id(api_id).is_connected()) {
          // When disconnected, draw the icon with reduced opacity or you could skip drawing it
          it.image(it.get_width()/2, it.get_height()/2, id(home_assistant_logo_l), ImageAlign::CENTER, gray); // Gray color for disconnected state
        } else {
          it.image(it.get_width()-2, 0, id(home_assistant_logo), ImageAlign::TOP_RIGHT, hablue);
        }
        // WiFi Signal Strength Status
        int wifi_strength = id(wifi_signal_percent).state;
        if (wifi_strength >= 75) {
          it.image(5, 0, id(wifi_3), ImageAlign::TOP_LEFT, green);
        } else if (wifi_strength >= 50) {
          it.image(5, 0, id(wifi_2), ImageAlign::TOP_LEFT, orange);
        } else if (wifi_strength >= 25) {
          it.image(5, 0, id(wifi_1), ImageAlign::TOP_LEFT, yellow);
        } else {
          it.image(5, 0, id(wifi_0), ImageAlign::TOP_LEFT, red);
        }
      }

      // Humidity Index
      if (id(ams_humidity_index).has_state()) {
        if (!isnan(id(ams_humidity_index).state)) {
          //Humidity Index Status
          int hum_idx = id(ams_humidity_index).state;
          if (hum_idx == 1) {
            it.image(it.get_width()/2 +10, it.get_height()/2, id(temp_low), ImageAlign::CENTER, blue);
            it.image(it.get_width()/2 -38, it.get_height()/2 +2, id(water_drop), ImageAlign::CENTER, black);
            it.image(it.get_width()/2 -40, it.get_height()/2, id(water_drop), ImageAlign::CENTER, blue);
          } else if (hum_idx == 2) {
            it.image(it.get_width()/2 +10, it.get_height()/2, id(temp_med), ImageAlign::CENTER, green);
            it.image(it.get_width()/2 -38, it.get_height()/2 +2, id(water_drop), ImageAlign::CENTER, black);
            it.image(it.get_width()/2 -40, it.get_height()/2, id(water_drop), ImageAlign::CENTER, green);
          } else if (hum_idx == 3) {
            it.image(it.get_width()/2 +10, it.get_height()/2, id(temp_med), ImageAlign::CENTER, yellow);
            it.image(it.get_width()/2 -38, it.get_height()/2 +2, id(water_drop), ImageAlign::CENTER, black);
            it.image(it.get_width()/2 -40, it.get_height()/2, id(water_drop), ImageAlign::CENTER, yellow);
          } else if (hum_idx == 4) {
            it.image(it.get_width()/2 +10, it.get_height()/2, id(temp_high), ImageAlign::CENTER, orange);
            it.image(it.get_width()/2 -38, it.get_height()/2 +2, id(water_drop), ImageAlign::CENTER, black);
            it.image(it.get_width()/2 -40, it.get_height()/2, id(water_drop), ImageAlign::CENTER, orange);
          } else if (hum_idx == 5) {
            it.image(it.get_width()/2 +10, it.get_height()/2, id(temp_high), ImageAlign::CENTER, red);
            it.image(it.get_width()/2 -38, it.get_height()/2 +2, id(water_drop), ImageAlign::CENTER, black);
            it.image(it.get_width()/2 -40, it.get_height()/2, id(water_drop), ImageAlign::CENTER, red);
          } else {}
          it.printf(it.get_width()/2 +10, it.get_height()/2 +40, id(gotham_md), white, TextAlign::CENTER, "%.0f", id(ams_humidity_index).state);
        } else {}
      } else {}

      // AMS Temperature
      if (id(ams_temperature).has_state()) {
        if (!isnan(id(ams_temperature).state)) {
          it.printf(it.get_width()/2, it.get_height()+10, id(nes_2x), white, TextAlign::BOTTOM_CENTER, "%.0f °F", id(ams_temperature).state);
        } else {}
      } else {}
1 Like

I can’t compile it, i always get error messages. can you share the already compiled bin file?
Thanks

Thanks, this works perfectly! Also, I must say it’s a very nice layout.

Before I found your config, I struggled quite a while with the display working initially but not after a restart. I wonder what exactly in your config solved this. Is it due to the newer ESP-IDF?

PS: Check out Time Component — ESPHome strftime. You could use something like it.strftime(it.get_width()/2, 2, id(nes_2x), TextAlign::TOP_CENTER, "%I:%M", cur_time); to display the time in the imperial 12-hour format and save a few lines of code.

1 Like

Make sure to update to the latest ESPHome device builder. If it still doesn’t work, post the error messages here.

Surely you will want to adapt the config somewhat, so a .bin file won’t be very helpful.

Thanks! Although I am certainly not a coder, I do have a design background. I wish I could figure out how to use gradients but I’m always hitting the 4MB limit of storage on this little guy.

I struggled with getting this device to work. I scoured through github and these were the latest settings I could find that would compile (challenge no. 1), boot (challenge no. 2) and not crash (challenge no. 3, aka the final boss).

Thank you for the suggestion of the time component. I’ll integrate that into my collection of snippets I use across my esphome projects.

Ultimately though… I’m still in my return window and am gonna send this back. I found the amount of storage too limiting and I’d rather learn how to use LVGL and no matter what settings/optimizations/component removals I tried, I just couldn’t get LVGL to fit in the storage amount and work. I think the best I got was 100.63% of the storage size. I’m gonna go with the gambler’s take on this one…

“Gotta know when to hold 'em, know then to fold 'em.”

Godspeed to the rest of ya.