lewisxhe / esp32-camera-screen

TTGO T-camera Plus
https://ru.aliexpress.com/item/TTGO-T-camera-Plus-ESP32-DOWDQ6-8-MB-SPRAM-OV2640-1-3/32971057846.html?fbclid=IwAR1uUoWC-UiemD8rKwg15WvpM7zhtvxUxdZhh0jnbrkFkNah6MV6Stg5Kag
65 stars 52 forks source link

ESPHome General Configuration #22

Open NonaSuomy opened 7 months ago

NonaSuomy commented 7 months ago

Here are all the things I discovered in my attempt to get everything working on this board with ESPHome. Hope it helps someone if you learn something interesting please share back.

ESPHome working things

TTGO-Camera-Plus Module 
ST7789 Display IPS Panel 1.3 Inch 260ppi 240x240 16-bit full color pixels
OV2640 V2.1 2Megapixel
MSM261S4030H0 I2S Mic
MPU6050 Accelerometer/Gyroscope Sensor
IP5306 Battery Management
PSRAM

ESPHome doesn't currently support SDCards

SDCard Slot 

Issues: 1.) Devices use flash pins 2.) The camera uses the same I2C pins as the other I2C devices BME, MPU6050, IP5306 3.) The display code required a non-existent reset pin. 4.) Voice Assistant requires esp-idf to function properly

Fixes: 1.) Use DIO mode 2.) ESPHome ssieb added a patch below to fix this issue. 3.) ESPHome Clyde added a patch to use a different display driver to not require the reset pin. 4.) Switch code to esp-idf but other fixes won't work as they only work with Arduino builds. :(

Uncomment different parts of the code if you want to play with different features some won't currently work with everything.

The last thing I was trying to do was to display the camera feed on the display with an imgproxy docker as online_image only supports PNG currently. Got it displaying online images just not the camera feed (Currently crashes when you try to use interval to load images)

Voice Assistant works pretty good displays what you say on the LCD display etc.

Have fun!

# TTGO-Camera Plus 001 https://www.lilygo.cc/en-ca/products/t-camera-plus

substitutions:
  device_friendly_name: ttgo-camera-plus-001
  device_name: ttgo-camera-plus-001
  created_by: "TTGO 20190214"
  device_description: "TTGO-Camera-Plus Module with ST7789 Display IPS Panel 1.3 Inch 260ppi 240x240 16-bit full color pixels, OV2640 V2.1 2Megapixel, MSM261S4030H0 I2S Mic, MPU6050 Accelerometer/Gyroscope Sensor, SDCard Slot & IP5306 Battery Management"

  # Pin define

  # SDCard
  sd_cs: GPIO0 # Chip Select

  # SPI
  spi_clk: GPIO21  # Serial Clock
  spi_mosi: GPIO19 # Main Out Sub In
  spi_miso: GPIO22 # Main In Sub Out

  # Display
  #1: BLK = Backlight
  #2: D/C = Data/Command
  #3: RES = Reset
  #4: SDA = Serial Data or SPI MOSI
  #5: SCL = Serial Clock or SPI SCK
  #   (These pins being active conflict with the other I2C devices on the same lines)
  #6: VCC (3.3V)
  #7: Ground
  dis_cs: GPIO12 # Chip Select
  dis_dc: GPIO15 # Data/Command
  dis_bk: GPIO2  # Backlight

  # Camera
  cam_d0: GPIO34   # Camera Data pin 0
  cam_d1: GPIO13   # Camera Data pin 1
  cam_d2: GPIO26   # Camera Data pin 2
  cam_d3: GPIO35   # Camera Data pin 3
  cam_d4: GPIO39   # Camera Data pin 4
  cam_d5: GPIO38   # Camera Data pin 5
  cam_d6: GPIO37   # Camera Data pin 6
  cam_d7: GPIO36   # Camera Data pin 7
  cam_vsync: GPIO5 # Camera VSYNC
  cam_href: GPIO27 # Camera HREF
  cam_pclk: GPIO25 # Camera Pixel Clock
  cam_xclk: GPIO4  # Camera External Clock
  cam_sda: GPIO18  # Camera SDA
  cam_scl: GPIO23  # Camera SCL

  # Non-existant DAC MAX98357 https://cdn-shop.adafruit.com/product-files/3006/MAX98357A-MAX98357B.pdf
  #dac_sd: 'GPIO_NUM_'   # DAC Serial Data Output or float?
  #dac_gain: 'GPIO_NUM_' # DAC Gain Float!
  #dac_din: GPIO         # DAC Digital In
  #dac_bclk: GPIO        # DAC Bit Clock
  #dac_lrc: GPIO         # DAC Left-Right Clock

  # Microphone https://www.makerhero.com/img/files/download/Microfone-Sipeed-MSM261S4030H0-Datasheet.pdf
  mic_sd: GPIO33   # Mic Serial Data
  #mic_lr: GPIO    # Mic Left-Right Clock
  mic_ws: GPIO32   # Mic Word Select
  mic_sck: GPIO14  # Mic Serial Clock

  rgbdin: GPIO16 #RGB LED (Doesn't exist just random pin to work with virtual LED dot on the screen)

  # I2C Bus: 0x30 Camera OV2640 2MP, 0x75 IP5306 Battery Management, 0x68 MPU6050 Accelerometer/Gyroscope Sensor
  i2c_sda: GPIO18 # I2C Serial Data
  i2c_scl: GPIO23 # I2C Serial Clock

esphome:
  name: $device_name
  friendly_name: ${device_friendly_name}
  min_version: 2023.10.0
  comment: "${device_friendly_name}"
  project:
    name: nonasuomy.ttgo-camera-plus
    version: "1.0"
  platformio_options:
    # Run flash in 2 pin mode instead of 4 pin because:
    #   Pin 12 is used for display CS
    #   Pin 13 is used for camera data 1
    board_build.flash_mode: dio
  on_boot:
    - priority: -100
      then:
        - wait_until: api.connected
        - delay: 1s
        - component.update: download_image
        # - if:
        #     condition:
        #       switch.is_on: use_wake_word
        #     then:
        #       - voice_assistant.start_continuous:
  #  - component.update: example_image
  #    online_image.set_url:
  #      url: !lambda |-
  #        return id(image_url).c_str();
  #      id: example_image

esp32:
  board: esp32dev
  framework:
    type: arduino
    #type: esp-idf

psram:
  mode: quad
  speed: 80MHz

# globals:
# #   - id: coords
# #     type: int
# #     restore_value: no
# #     initial_value: '0'
# #   - id: length
# #     type: int
# #     restore_value: no
# #     initial_value: '0'
#   # Global URL string variable
#   - id: image_url1
#     type: std::string
#     restore_value: yes
#     max_restore_data_length: 80
#     #initial_value: '"https://www.kasandbox.org/programming-images/avatars/cs-hopper-cool.png"'
#     initial_value: '"https://github-production-user-asset-6210df.s3.amazonaws.com/1906575/280905647-ca42ade8-e4a9-4bfb-88ec-081e71963b32.png"'
#     #initial_value: '"http://10.0.1.100:8080/unsafe/size:240:240/plain/http://10.0.1.101:8081@png"'
#   - id: image_url2
#     type: std::string
#     restore_value: yes
#     max_restore_data_length: 80
#     initial_value: '"https://www.kasandbox.org/programming-images/avatars/cs-hopper-cool.png"'
#     #initial_value: '"http://10.0.1.100:8080/unsafe/size:240:240/plain/http://10.0.1.101:8081@png"'
#     #initial_value: '"http://10.0.1.102/image_static/aHR0cDovLzEwLjEzLjM3LjIwNDo4MDgx.png"'
#     #initial_value: '"https://i.ibb.co/1mp3SkP/image.png"'

# This is to fix a glitch where it says it requires image.h on compile when you have Online Image Display enabled
# We use a 1x1 pixel to use less memory as it is not required just so it pulls the image.h into the build.
image:
  - file: mdi:alert-outline
    id: alert
    resize: 1x1

external_components:
  # IP5306 Battery Management
  # - source:
  #     type: git
  #     url: https://github.com/ssieb/custom_components
  #   components: [ ip5306 ]

  # Online Image Display  
  - source: 'github://pr#4710'
    components: [ online_image ]

  # Voice Prompts
  # - source: github://pr#5230
  #   components:
  #     - esp_adf
  #   refresh: 0s

# This branch is to fix so that both the Camera and sensors can run on the same I2C currently only working with type: arduino not esp-idf
  # - source: github://ssieb/esphome@cam_i2c
  #   components: [ esp32_camera ]
  #   refresh: 1min

# Do not uncomment this as it has been released properly in the esphome 
# Current builds and will complain about being defined twice
# https://github.com/esphome/issues/issues/5089
#  - source: github://pr#5406
#    components: [ ili9xxx ]

# Voice Prompts
#esp_adf:

# Enable logging
logger:
  #baud_rate: 0
  #level: VERY_VERBOSE
  #level: VERBOSE
  #level: INFO
  #level: NONE
  # logs: 
  #   voice_assistant: verbose
  #   switch: debug
  #   wifi: debug

wifi:
  ssid: !secret wifi_ssid2
  password: !secret wifi_password2
  use_address: !secret use_address_wifi0072
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "TTGO-Camera-Plus-001"
    password: !secret fallbackhotspot007

# Enable Home Assistant API
api:
  encryption:
    key: !secret encryption_key007

# Over The Air updates
ota:
  password: !secret ota_pass007

captive_portal:

web_server:

# TTGO Camera Plus
# OV2640 2Megapixel
esp32_camera:
  name: TTGOCameraPlus001
  external_clock:
    pin: $cam_xclk
    frequency: 20MHz
  i2c_pins:
    sda: $cam_sda
    scl: $cam_scl
  data_pins: [$cam_d0, $cam_d1, $cam_d2, $cam_d3, $cam_d4, $cam_d5, $cam_d6, $cam_d7]
  vsync_pin: $cam_vsync
  href_pin: $cam_href
  pixel_clock_pin: $cam_pclk
  vertical_flip: false
  horizontal_mirror: false
  resolution: QQVGA

# Camera Web Server
esp32_camera_web_server:
  #- port: 8080
  #  mode: stream
  - port: 8081
    mode: snapshot

# # Microphone & Speaker I2S Audio Pins (Camera Plus has no default speaker DAC)
# i2s_audio:
#   # Mic MSM261S4030H0
#   - id: i2s_in  
#     i2s_lrclk_pin: $mic_ws # LRCLK, WS, FS
#     i2s_bclk_pin: $mic_sck # BLCK, SCK, CLK
  # DAC MAX98357
  #- id: i2s_out
  #  i2s_lrclk_pin: $dac_lrc  # LRCLK, WS, FS
  #  i2s_bclk_pin: $dac_bclk  # BLCK, SCK

# # Mic MSM261S4030H0
# microphone:
#   platform: i2s_audio
#   id: msm261S4030h0_mic
#   i2s_audio_id: i2s_in
#   i2s_din_pin: $mic_sd # DIN, SDIN, SD, SDATA, ADCDATA
#   adc_type: external
#   bits_per_sample: 32bit
#   channel: left
#   pdm: false

#speaker:
#  - platform: i2s_audio
#    id: dac_speaker
#    i2s_audio_id: i2s_out    
#    dac_type: external
#    i2s_dout_pin: $dac_din
#    mode: stereo

# voice_assistant:
#   id: va
#   microphone: msm261S4030h0_mic
#   #speaker: dac_speaker
#   noise_suppression_level: 2
#   auto_gain: 31dBFS
#   volume_multiplier: 2.0
#   vad_threshold: 2
#   use_wake_word: true
#   on_listening:
#     - light.turn_on:
#         id: led
#         blue: 100%
#         red: 0%
#         green: 0%
#         brightness: 100%
#         effect: pulse

  # on_tts_start:
  #   - light.turn_on:
  #       id: led
  #       blue: 0%
  #       red: 0%
  #       green: 100%
  #       brightness: 100%
  #       effect: pulse
  #   - text_sensor.template.publish: 
  #       id: line2
  #       state: !lambda return x;

  # on_end:
  #   - delay: 100ms
  #  # - wait_until:
  #  #     not:
  #  #       speaker.is_playing:
  #   - script.execute: reset_led
  #   #- script.execute: clear_error_script
  #  # - text_sensor.template.publish:
  #  #     id: line2
  #  #     state: !lambda return x;

  # on_error:
  #   - light.turn_on:
  #       id: led
  #       blue: 0%
  #       red: 100%
  #       green: 0%
  #       brightness: 100%
  #       effect: none
  #   - delay: 1s
  #   - script.execute: reset_led
  #   - script.wait: reset_led
  #   - lambda: |-
  #       if (code == "wake-provider-missing" || code == "wake-engine-missing") {
  #         id(use_wake_word).turn_off();
  #       }
  #       if (message == "Could not request start.") {
  #         id(restart_script).execute();
  #       } 
  #   - text_sensor.template.publish: 
  #       id: line4
  #       state: !lambda return code;
  #   - text_sensor.template.publish: 
  #       id: line5
  #       state: !lambda return message;
  #   - delay: 10s
  #   - script.execute: clear_error_script

  # on_client_connected:
  #   - if:
  #       condition:
  #         switch.is_on: use_wake_word
  #       then:
  #         - voice_assistant.start_continuous:
  #         #- script.execute: clear_error_script

  # on_client_disconnected:
  #   - if:
  #       condition:
  #         switch.is_on: use_wake_word
  #       then:
  #         - voice_assistant.stop:

  # on_stt_end:
  #   - text_sensor.template.publish: 
  #       id: line1
  #       state: !lambda return x;

  # on_tts_end:
  #   - text_sensor.template.publish: 
  #       id: line3
  #       state: !lambda return x;

# binary_sensor:
#   - platform: status
#     id: api_connection
#     filters:
#       - delayed_on: 1s
#     on_press:
#       - if:
#           condition:
#             switch.is_on: use_wake_word
#           then:
#             - voice_assistant.start_continuous:
#     on_release:
#       - if:
#           condition:
#             switch.is_on: use_wake_word
#           then:
#             - voice_assistant.stop:

# light:
#   - platform: esp32_rmt_led_strip
#     id: led
#     name: None
#     disabled_by_default: true
#     entity_category: config
#     pin: $rgbdin
#     default_transition_length: 0s
#     chipset: SK6812
#     num_leds: 1
#     rgb_order: grb
#     rmt_channel: 0
#     effects:
#       - pulse:
#           transition_length: 250ms
#           update_interval: 250ms
#     on_state: 
#       then:
#         - component.update: st7789_display
# script:
#   - id: reset_led
#     then:
#       - if:
#           condition:
#             - switch.is_on: use_wake_word
#             - switch.is_on: use_listen_light
#           then:
#             - light.turn_on:
#                 id: led
#                 blue: 100%
#                 red: 100%
#                 green: 0%
#                 brightness: 100%
#                 effect: none
#           else:
#             - light.turn_off: led
#   - id: restart_script
#     then:
#       - voice_assistant.stop
#       - delay: 1s
#       - text_sensor.template.publish: 
#           id: line4
#           state: " "
#       - text_sensor.template.publish: 
#           id: line5
#           state: " "
#       - voice_assistant.start_continuous
#   - id: clear_error_script
#     then:
#       - delay: 1s
#       - text_sensor.template.publish: 
#           id: line4
#           state: " "
#       - text_sensor.template.publish: 
#           id: line5
#           state: " "

switch:
  # OLD Backlight control use other code below much better
  #- platform: gpio
  #  pin: GPIO2
  #  name: "Display Backlight"
  #  id: backlight 
  #  disabled_by_default: True
  #  restore_mode: RESTORE_DEFAULT_ON  
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"
  #- platform: gpio
  #  pin: $mic_lr
  #  name: L-R Switch
  #  disabled_by_default: True
  #  restore_mode: RESTORE_DEFAULT_OFF
  # - platform: template
  #   name: Use wake word
  #   id: use_wake_word
  #   optimistic: true
  #   restore_mode: RESTORE_DEFAULT_ON
  #   entity_category: config
  #   on_turn_on:
  #     - lambda: id(va).set_use_wake_word(true);
  #     - if:
  #         condition:
  #           not:
  #             - voice_assistant.is_running
  #         then:
  #           - voice_assistant.start_continuous
  #     - script.execute: reset_led
  #   on_turn_off:
  #     - voice_assistant.stop
  #     - lambda: id(va).set_use_wake_word(false);
  #     - script.execute: reset_led
  # - platform: template
  #   name: Use Listen Light
  #   id: use_listen_light
  #   optimistic: true
  #   restore_mode: RESTORE_DEFAULT_ON
  #   entity_category: config
  #   on_turn_on:
  #     - script.execute: reset_led
  #   on_turn_off:
  #     - script.execute: reset_led

# I2C Bus Addresses
# 0x30 Camera OV2640 2Megapixel
# 0x68 MPU6050 Accelerometer/Gyroscope Sensor
# 0x75 IP5306 Battery Management
# i2c:
#   sda: $i2c_sda
#   scl: $i2c_scl
#   scan: true
#   id: bus_a

 # IP5306 Battery Management
 # Charging Current: 1A
 # Battery: 3.7V lithium battery
# ip5306:
#   i2c_id: bus_a
#   address: 0x75
#   #update_interval: 60s
#   battery_level:   # sensor
#     name: Battery Level
#   charger_connected:  # binary_sensor
#     id: connected
#     name: Battery Charger Connected
#     on_press:
#       then:
#         - lambda: ESP_LOGD("TEST", "charging");
#     on_release:
#       then:
#         - lambda: ESP_LOGD("TEST", "not charging");
#   charge_full:  # binary_sensor
#     id: full
#     name: Battery Charge Full
#     on_press:
#       then:
#         - lambda: ESP_LOGD("TEST", "fully charged");
#     on_release:
#       then:
#         - lambda: ESP_LOGD("TEST", "still charging");

# # MPU6050 Accelerometer/Gyroscope Sensor
# sensor:
#   - platform: mpu6050
#     i2c_id: bus_a
#     address: 0x68
#     update_interval: 60s
#     accel_x:
#       name: "MPU6050 Accel X"
#     accel_y:
#       name: "MPU6050 Accel Y"
#     accel_z:
#       name: "MPU6050 Accel Z"
#     gyro_x:
#       name: "MPU6050 Gyro X"
#     gyro_y:
#       name: "MPU6050 Gyro Y"
#     gyro_z:
#       name: "MPU6050 Gyro Z"
#     temperature:
#       name: "MPU6050 Temperature"

#   - platform: wifi_signal
#     name: "${friendly_name} Signal"
#     id: "wifisignal"
#     update_interval: 120s

# ST7789 Display
# IPS Panel 1.3 Inch 260ppi 240x240 16-bit full color pixels 
spi:
  clk_pin: $spi_clk
  mosi_pin: $spi_mosi
  miso_pin: $spi_miso

# text_sensor:
#   - platform: wifi_info
#     ip_address:
#       name: ESP IP Address
#       id: show_ip
#   - id: line1
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display
#   - id: line2
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display
#   - id: line3
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display
#   - id: line4
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display
#   - id: line5
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display
#   - id: line6
#     platform: template
#     on_value: 
#       then:
#         - component.update: st7789_display

# # time:
#   - platform: homeassistant
#     id: homeassistant_time
#     timezone: America/Toronto

# color:
#   - id: color_red
#     red: 1
#     green: 0
#     blue: 0
#   - id: color_black
#     red: 0
#     green: 0
#     blue: 0

# New Backlight code
# Define a PWM output on the ESP32
output:
  - platform: ledc
    pin: $dis_bk
    id: gpio_dis_bk_backlight_pwm

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: gpio_dis_bk_backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_ON

display:
  # Old display settings with no way to set anything to reset pin.
  # - platform: st7789v
  #   id: st7789_display
  #   model: Custom
  #   height: 240
  #   width: 240
  #   offset_width: 0
  #   offset_height: 0
  #   backlight_pin: $dis_bk
  #   cs_pin: $dis_cs
  #   dc_pin: $dis_dc
  #   reset_pin: 33 # Set to an unused pin as really this line is connected to chip_pu that is not controllable with GPIO.

  # Fixed display settings to not set a reset pin
  - platform: ili9xxx
    model: st7789v
    id: st7789_display
    dimensions:
      height: 240
      width: 240
      offset_width: 0
      offset_height: 0
    invert_colors: true 
    cs_pin: $dis_cs
    dc_pin: $dis_dc

    #update_interval: 2s
    # Simple text test
    # lambda: |-
    #  it.printf(0, 0, id(roboto16), "Test");
    # Image display
    lambda: |-
      it.image(0, 0, id(download_image));
    # Lots of stuff test
    # #pages:
    #  - id: "page1"
    # lambda: |-
    #       auto ledcolor = Color(id(led).remote_values.get_red()*255, id(led).remote_values.get_green()*255, id(led).remote_values.get_blue()*255);
    #       bool ledstatus = id(led).remote_values.get_state();
    #       int x = 0, y = 48, offs = 17;
    #       it.filled_circle(160, 10, 5, ledstatus ? ledcolor : color_black);
    #       it.printf(x, 0, id(roboto16), TextAlign::TOP_LEFT, "${device_friendly_name}");
    #       it.strftime(240, 0, id(roboto16), TextAlign::TOP_RIGHT, "%H:%M:%S", id(homeassistant_time).now());
    #       it.printf(x, 16, id(roboto16), "IP: %s", id(show_ip).state.c_str());
    #       it.printf(x, 32, id(roboto16), "Signal: %.1f dBm", id(wifisignal).state);

    #       //std::string printout1=id(line1).state.c_str();
    #       //int clength1 = printout1.length();
    #       //id(length)=clength1*4;
    #       //it.printf(id(coords), y, id(roboto16), printout1.c_str());

    #       //std::string printout2=id(line2).state.c_str();
    #       //int clength2 = printout2.length();
    #       //id(length)=clength2*4;
    #       //it.printf(id(coords), y=y+offs, id(roboto16), printout2.c_str());

    #       //std::string printout3=id(line3).state.c_str();
    #       //int clength3 = printout3.length();
    #       //id(length)=clength3*4;
    #       //it.printf(id(coords), y=y+offs, id(roboto16), printout3.c_str());

    #       it.printf(x, y, id(roboto16), "%s", id(line1).state.c_str());
    #       it.printf(x, y=y+offs, id(roboto16), "%s", id(line2).state.c_str());
    #       it.printf(x, y=y+offs, id(roboto16), "%s", id(line3).state.c_str());
    #       it.printf(x, y=y+offs, id(roboto16), color_red, "%s", id(line4).state.c_str());
    #       it.printf(x, y=y+offs, id(roboto16), color_red, "%s", id(line5).state.c_str());

#      - id: "page2"
#        lambda: |-
#          auto ledcolor = Color(id(led).remote_values.get_red()*255, id(led).remote_values.get_green()*255, id(led).remote_values.get_blue()*255);
#          bool ledstatus = id(led).remote_values.get_state();
#          int x = 0, y = 43, offs = 17;
#          it.filled_circle(10, 10, 5, ledstatus ? ledcolor : color_black);
      #    it.printf(x, y, id(roboto16), "L1: %s", id(line1).state.c_str());
      #    it.printf(x, y=y+offs, id(roboto16), "L2: %s", id(line2).state.c_str());
      #    it.printf(x, y=y+offs, id(roboto16), "L3: %s", id(line3).state.c_str());
      #    it.printf(x, y=y+offs, id(roboto16), color_red, "L4: %s", id(line4).state.c_str());
      #    it.printf(x, y=y+offs, id(roboto16), color_red, "L5: %s", id(line5).state.c_str());
#          it.printf(x, y=y+offs, id(roboto16), color_red, "L6: %s", id(line6).state.c_str());

# 35 Characters @ Size 16, 15 lines.
# font:
#   - file: "gfonts://Roboto"
#     id: roboto16
#     size: 14
#     glyphs: "'!%()[]{}+,-/_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyzμ₂³"

online_image:
  #url: "https://www.kasandbox.org/programming-images/avatars/cs-hopper-cool.png"
  #url: "http://10.0.1.100:8080/sig/size:16:16/aHR0cDovLzEwLjEzLjM3LjIwNDo4MDgx.png"
  #url: "http://10.0.1.100:8080/unsafe/size:240:240/plain/http://10.0.1.101:8081@png"
  #url: "http://10.0.1.102/image_static/aHR0cDovLzEwLjEzLjM3LjIwNDo4MDgx.png"
  #url: "https://i.ibb.co/1mp3SkP/image.png"
  url: "https://github-production-user-asset-6210df.s3.amazonaws.com/1906575/280905647-ca42ade8-e4a9-4bfb-88ec-081e71963b32.png"
  # Has to be PNG so this won't work as it is a JPG stream
  #url: "http://10.0.1.101:8081" 
  timeout: 20s
  id: download_image
  type: RGB565
  buffer_size: 16384
  on_download_finished:
    - component.update: st7789_display
  on_error:
    - logger.log: "Could not download the image"

# interval:
# #  - interval: 2s
# #    then:
# #        lambda: |-
# #            if (id(coords) < -(id(length))) {
# #             id(coords) = 0;
# #                }
# #            else  {
# #               id(coords) -= 2;
# #            }
#   - interval: 10s
#     then:
#       - component.update: st7789_display
#      - delay: 15s
#      - display.page.show_next: st7789_display

# Update the displayed URL image every nth min
# interval:
#  - interval: 1min
#    then:
#    - delay: 20s
#    - online_image.set_url:
#       url: !lambda |-
#                return id(image_url1).c_str();
#       id: download_image
#    #- delay: 10s
#    - component.update: download_image
#    #- delay: 10s
#    #- component.update: st7789_display
#    - delay: 20s
#    - online_image.set_url:
#       url: !lambda |-
#                return id(image_url2).c_str();
#       id: download_image
#    #- delay: 10s
#    - component.update: download_image
#    #- delay: 10s
#    #- component.update: st7789_display
roccotocco commented 4 months ago

Hello thank you for your work.... im getting this error during the esphome compiling:

INFO ESPHome 2024.2.1 INFO Reading configuration /config/esphome/ttgo-camera-plus.yaml... WARNING GPIO5 is a strapping PIN and should only be used for I/O with care. Attaching external pullup/down resistors to strapping pins can cause unexpected failures. See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins WARNING GPIO2 is a strapping PIN and should only be used for I/O with care. Attaching external pullup/down resistors to strapping pins can cause unexpected failures. See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins WARNING GPIO12 is a strapping PIN and should only be used for I/O with care. Attaching external pullup/down resistors to strapping pins can cause unexpected failures. See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins WARNING GPIO15 is a strapping PIN and should only be used for I/O with care. Attaching external pullup/down resistors to strapping pins can cause unexpected failures. See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins INFO Generating C++ source... Traceback (most recent call last): File "/usr/local/bin/esphome", line 33, in 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/6664c158/esphome/components/ili9xxx/display.py", line 161, in to_code 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 st7789_display was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.

How i can solve ? Thanks

NonaSuomy commented 4 months ago

Did you modify the code or just copy pasta compile?

roccotocco commented 4 months ago

no i didnt modify it... just added the wifi settings

NonaSuomy commented 4 months ago

Ok I will break out the board and have a look, probably what has happened is the display library is properly released now so maybe you don't require the git inclusion for it.

Edit: Yes this is the case so just remove...

# https://github.com/esphome/issues/issues/5089
#  - source: github://pr#5406
#    components: [ ili9xxx ]

Fixed above as well. Thanks for pointing that out.

0CB6D37E-56A5-476B-9E10-FDF2D840C635

roccotocco commented 4 months ago

Finally i flashed the module.... but the image into the display not refreshing and into the logs i have this errors:

[11:36:29][W][component:214]: Component display took a long time for an operation (0.14 s). [11:36:29][W][component:215]: Components should block for at most 20-30ms. [11:36:30][W][component:214]: Component display took a long time for an operation (0.14 s). [11:36:30][W][component:215]: Components should block for at most 20-30ms. [11:36:31][W][component:214]: Component display took a long time for an operation (0.14 s). [11:36:31][W][component:215]: Components should block for at most 20-30ms. [11:36:32][W][component:214]: Component display took a long time for an operation (0.14 s). [11:36:32][W][component:215]: Components should block for at most 20-30ms. [11:36:33][W][component:214]: Component display took a long time for an operation (0.14 s). [11:36:33][W][component:215]: Components should block for at most 20-30ms. [11:36:33][D][esp32_camera:196]: Got Image: len=2891

NonaSuomy commented 4 months ago

From that, it looks great so far. You're missing the start of the log. This happens sometimes, you won't see the URL it downloaded if you don't catch the log from startup. Those are not errors. They are part of newer logging features in esphome most sensors will dump stuff like that, which are heavy loads.

Are you using the exact same board as in the picture above?

There are two LCDs that are named the same but are completely different st7789 and the st7789v.

Have you tested the display in the past and seen something show up on it? Lilygo stuff does not have the best track record with me and quality control. Had many problems with diodes soldered on backward frying the boards, USB ports not even attached to the board, and sending the wrong products.

I'm not sure about your local speeds of connections but I had issues depending on the server I was pulling from. Maybe try to use a PNG server that is close to your location. Try that gopher one switch the url: https://www.kasandbox.org/programming-images/avatars/cs-hopper-cool.png as well. Also, test if you can see the URLs on your computer with wifi connected to the same network as the device.

https://github-production-user-asset-6210df.s3.amazonaws.com/1906575/280905647-ca42ade8-e4a9-4bfb-88ec-081e71963b32.png This image takes a long time to load on mine. Right when I think it failed, I look down and the image is on the device.

The other urls won't work for you as they are for a local jpg to png converting server. I was trying to load the camera server on the esp from a cached copy to the display on itself which that image above is from.

Here is an example of a successful log. Maybe try to reset the device a few times to see if it grabs the image but defo find a fast server with a tiny image to test with.

INFO ESPHome 2024.2.1
INFO Reading configuration /config/ttgo-camera-plus.yaml...
WARNING GPIO5 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO2 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO12 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Starting log output from 10.0.42.132 using esphome API
INFO Successfully connected to ttgo-camera-plus-001 @ 10.0.42.132 in 0.107s
INFO Successful handshake with ttgo-camera-plus-001 @ 10.0.42.132 in 0.476s
[20:00:39][I][app:102]: ESPHome version 2024.2.1 compiled on Mar  3 2024, 21:37:16
[20:00:39][I][app:104]: Project nonasuomy.ttgo-camera-plus version 1.0
[20:00:39][C][wifi:577]: WiFi:
[20:00:39][C][wifi:409]:   Local MAC: de:ad:be:ef:00:01
[20:00:39][C][wifi:414]:   SSID: [redacted]
[20:00:39][C][wifi:415]:   IP Address: 10.0.42.132
[20:00:39][C][wifi:417]:   BSSID: [redacted]
[20:00:39][C][wifi:418]:   Hostname: 'ttgo-camera-plus-001'
[20:00:39][C][wifi:420]:   Signal strength: -40 dB ▂▄▆█
[20:00:39][C][wifi:424]:   Channel: 10
[20:00:39][C][wifi:425]:   Subnet: 255.255.255.0
[20:00:39][C][wifi:426]:   Gateway: 10.0.42.1
[20:00:39][C][wifi:427]:   DNS1: 10.0.42.1
[20:00:39][C][wifi:428]:   DNS2: 0.0.0.0
[20:00:39][C][logger:447]: Logger:
[20:00:39][C][logger:448]:   Level: DEBUG
[20:00:39][C][logger:449]:   Log Baud Rate: 115200
[20:00:39][C][logger:451]:   Hardware UART: UART0
[20:00:39][C][spi:068]: SPI bus:
[20:00:39][C][spi:069]:   CLK Pin: GPIO21
[20:00:39][C][spi:070]:   SDI Pin: GPIO22
[20:00:39][C][spi:071]:   SDO Pin: GPIO19
[20:00:39][C][spi:076]:   Using HW SPI: SPI
[20:00:39][C][ledc.output:164]: LEDC Output:
[20:00:39][C][ledc.output:165]:   Pin GPIO2
[20:00:39][C][ledc.output:166]:   LEDC Channel: 0
[20:00:39][C][ledc.output:167]:   PWM Frequency: 1000.0 Hz
[20:00:39][C][ledc.output:168]:   Bit depth: 16
[20:00:39][C][ili9xxx:073]: ili9xxx
[20:00:39][C][ili9xxx:073]:   Rotations: 0 °
[20:00:39][C][ili9xxx:073]:   Dimensions: 240px x 240px
[20:00:39][C][ili9xxx:074]:   Width Offset: 0
[20:00:39][C][ili9xxx:075]:   Height Offset: 0
[20:00:39][C][ili9xxx:081]:   Color mode: 16bit
[20:00:39][C][ili9xxx:090]:   Data rate: 40MHz
[20:00:39][C][ili9xxx:093]:   CS Pin: GPIO12
[20:00:39][C][ili9xxx:094]:   DC Pin: GPIO15
[20:00:39][C][ili9xxx:096]:   Color order: BGR
[20:00:39][C][ili9xxx:097]:   Swap_xy: NO
[20:00:40][C][ili9xxx:098]:   Mirror_x: NO
[20:00:40][C][mdns:115]: mDNS:
[20:00:40][C][mdns:116]:   Hostname: ttgo-camera-plus-001
[20:00:40][C][ota:096]: Over-The-Air Updates:
[20:00:40][C][ota:097]:   Address: 10.0.42.132:3232
[20:00:40][C][ota:100]:   Using Password.
[20:00:40][C][ota:103]:   OTA version: 2.
[20:00:40][C][api:139]: API Server:
[20:00:40][C][api:140]:   Address: 10.0.42.132:6053
[20:00:40][C][api:142]:   Using noise encryption: YES
[20:00:40][I][online_image:348]: Updating image
[20:00:41][D][online_image:384]: Content Type: image/png
[20:00:42][D][online_image:385]: Content Length: 82550
[20:00:42][D][online_image:386]: ETag: "60776233109f4ddb996eb2a1cc110af2"
[20:00:42][I][online_image:408]: Downloading image from https://github-production-user-asset-6210df.s3.amazonaws.com/1906575/280905647-ca42ade8-e4a9-4bfb-88ec-081e71963b32.png
[20:00:42][W][component:214]: Component esphome.coroutine took a long time for an operation (1.95 s).
[20:00:42][W][component:215]: Components should block for at most 20-30ms.
[20:00:42][C][esp32_camera_web_server:088]: ESP32 Camera Web Server:
[20:00:42][C][esp32_camera_web_server:089]:   Port: 8081
[20:00:42][C][esp32_camera_web_server:093]:   Mode: snapshot
[20:00:42][D][online_image:154]: Allocating new buffer of 86400 Bytes...
[20:00:42][D][online_image:161]: New size: (240, 180)
[20:00:42][W][component:214]: Component online_image took a long time for an operation (0.10 s).
[20:00:42][W][component:215]: Components should block for at most 20-30ms.
[20:00:43][W][component:214]: Component online_image took a long time for an operation (0.16 s).
[20:00:43][W][component:215]: Components should block for at most 20-30ms.
[20:00:43][W][component:214]: Component online_image took a long time for an operation (0.16 s).
[20:00:43][W][component:215]: Components should block for at most 20-30ms.
[20:00:44][W][component:214]: Component online_image took a long time for an operation (0.16 s).
[20:00:44][W][component:215]: Components should block for at most 20-30ms.
[20:00:44][W][component:214]: Component online_image took a long time for an operation (0.14 s).
[20:00:44][W][component:215]: Components should block for at most 20-30ms.
[20:00:44][D][online_image:178]: Image fully downloaded
[20:00:44][W][component:214]: Component online_image took a long time for an operation (0.15 s).
[20:00:45][W][component:215]: Components should block for at most 20-30ms.
[20:00:45][W][component:214]: Component display took a long time for an operation (0.14 s).
[20:00:45][W][component:215]: Components should block for at most 20-30ms.
[20:00:46][W][component:214]: Component display took a long time for an operation (0.14 s).
[20:00:46][W][component:215]: Components should block for at most 20-30ms.
[20:00:47][W][component:214]: Component display took a long time for an operation (0.15 s).
[20:00:47][W][component:215]: Components should block for at most 20-30ms.
[20:00:48][D][api:102]: Accepted 10.0.10.42
[20:00:48][D][api.connection:1121]: Home Assistant 2024.3.0b5 (10.0.10.42): Connected successfully
[20:00:48][W][component:214]: Component display took a long time for an operation (0.15 s).
[20:00:48][W][component:215]: Components should block for at most 20-30ms.
[20:00:49][W][component:214]: Component display took a long time for an operation (0.15 s).
[20:00:49][W][component:215]: Components should block for at most 20-30ms.
[20:00:50][D][esp32_camera:196]: Got Image: len=3008

To pull this off it was all bleeding edge case stuff to get working especially this PNG library which is not finished yet. So there will be dragons.