I managed to get it building, but there is no output on the display.
I`m using esphome 2024.4.0 dev.
I managed to get it building, but there is no output on the display.
I`m using esphome 2024.4.0 dev.
I don’t have the device myself, but looking into it. But, I don’t see where you setup the blacklight pin. The backlight enable is located on the gpio expander chip exio2 per the schematic with the LCD reset pin. That doesn’t look like it’s in the esphome per this GitHub issue Support for WCH(Jiangsu Qin Heng) CH422G I/O Expander · Issue #2671 · esphome/feature-requests · GitHub
There is quite some info on this device in the following zip file:
ZFile and select the 4.0inch version.
Probably you’ve already seen this file, but just to be sure…
It;s a great screen, so I hope that it will work with HASS some day.
I got the display to almost work fine
Here my configuration
captive_portal:
time:
- platform: homeassistant
timezone: "Australia/Melbourne"
id: esptime
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: 38
id: gpio_38_backlight_pwm
light:
- platform: monochromatic
output: gpio_38_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
psram:
mode: octal
speed: 80MHz
spi:
clk_pin: 48
mosi_pin: 47
miso_pin: 41
display:
- platform: st7701s
spi_mode: MODE3
color_order: bgr
dimensions:
width: 480
height: 480
cs_pin: 39
de_pin: 18
hsync_pin: 16
hsync_pulse_width: 8
hsync_front_porch: 1
hsync_back_porch: 1
vsync_pin: 17
vsync_pulse_width: 8
vsync_front_porch: 1
vsync_back_porch: 1
pclk_pin: 21
#pclk_frequency: 8MHz
#pclk_inverted: false
update_interval: 1s
auto_clear_enabled: false
data_rate: 1MHz
init_sequence:
- 1 # select canned init sequence number 1
- [ 0xE0, 0x1F ] # Set sunlight readable enhancement
data_pins:
red:
- 4 #r1
- 5 #r2
- 6 #r3
- 7 #r4
- 15 #r5
green:
- 8 #g0
- 20 #g1
- 3 #g2
- 46 #g3
- 9 #g4
- 10 #g5
blue:
- 11 #b1
- 12 #b2
- 13 #b3
- 14 #b4
- 0 #b5
lambda: |-
auto blue = Color(255, 0, 0);
auto green = Color(0, 255, 0);
auto red = Color(0, 0, 255);
it.rectangle(230, 230, 100, 100, green);
it.rectangle(231, 231, 98, 98, red);
it.rectangle(231, 232, 96, 96, red);
it.rectangle(233, 233, 94, 94, green);
it.rectangle(30, 30, 100, 100, green);
it.rectangle(31, 31, 98, 98, green);
it.rectangle(32, 32, 96, 96, green);
it.rectangle(33, 33, 94, 94, green);
it.rectangle(34, 34, 92, 92, green);
it.rectangle(35, 35, 90, 90, green);
Using the above configuration my device just goes into a boot loop displaying this in the ESP log:
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x10 (RTCWDT_RTC_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x400454d5
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
Here with the touchscreen working as well:
captive_portal:
time:
- platform: homeassistant
timezone: "Australia/Melbourne"
id: esptime
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: 38
id: gpio_38_backlight_pwm
light:
- platform: monochromatic
output: gpio_38_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
- platform: homeassistant
id: devils_ivy_moisture
entity_id: sensor.flower_care_moisture
- platform: homeassistant
id: outdoor_temperature
entity_id: sensor.temperature_humidity_sensor_f402_temperature
# Example configuration entry
i2c:
- id: bus_a
sda: 19
scl: 45
scan: false
frequency: 10kHz
psram:
mode: octal
speed: 80MHz
spi:
clk_pin: 48
mosi_pin: 47
miso_pin: 41
font:
- file: 'fonts/arial.ttf'
id: font_16
size: 16
- file: 'fonts/arial.ttf'
id: font_24
size: 24
- file: 'fonts/arial.ttf'
id: font_32
size: 32
color:
- id: my_red
red: 100%
green: 1%
blue: 1%
- id: my_green
red: 3%
green: 100%
blue: 5%
- id: my_blue
red: 3%
green: 5%
blue: 100%
- id: my_white
red: 100%
green: 100%
blue: 100%
- id: my_black
red: 1%
green: 1%
blue: 1%
touchscreen:
platform: gt911
id: touchscreen_4_inches
i2c_id: bus_a
on_touch:
then:
- display.page.show_next: display_4_inches
- component.update: display_4_inches
- logger.log: "Touch, go to next page"
display:
- platform: st7701s
id: display_4_inches
spi_mode: MODE3
color_order: bgr
#invert_colors: true
dimensions:
width: 480
height: 480
cs_pin: 39
de_pin: 18
hsync_pin: 16
hsync_pulse_width: 9
hsync_front_porch: 10
hsync_back_porch: 50
vsync_pin: 17
vsync_pulse_width: 9
vsync_front_porch: 10
vsync_back_porch: 20
pclk_pin: 21
#pclk_frequency: 8MHz
#pclk_inverted: false
update_interval: never
auto_clear_enabled: false
#data_rate: 75kHz
#init_sequence:
# - 1 # select canned init sequence number 1
# - [ 0xE0, 0x1F ] # Set sunlight readable enhancement
data_pins:
blue:
- 11 #b1
- 12 #b2
- 13 #b3
- 14 #b4
- 0 #b5
green:
- 8 #g0
- 20 #g1
- 3 #g2
- 46 #g3
- 9 #g4
- 10 #g5
red:
- 4 #r1
- 5 #r2
- 6 #r3
- 7 #r4
- 15 #r5
pages:
- id: page1
lambda: |-
it.filled_rectangle(0, 0, 241, 241, my_black);
it.strftime(120,70, id(font_24), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(esptime).now());
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(outdoor_temperature).state);
it.circle(120, 120, 117, id(my_white));
it.circle(120, 120, 118, id(my_white));
- id: page2
lambda: |-
it.filled_rectangle(0, 0, 241, 241, my_black);
it.print(120, 100, id(font_32), id(my_white), TextAlign::CENTER, "Zanzibar Gem");
it.printf(120, 150, id(font_32), id(my_green), TextAlign::CENTER, "%.1f %%", id(devils_ivy_moisture).state);
if (id(devils_ivy_moisture).state>15) {
it.circle(120, 120, 115, id(my_green));
it.circle(120, 120, 116, id(my_green));
it.circle(120, 120, 117, id(my_green));
it.circle(120, 120, 118, id(my_green));
it.circle(120, 120, 119, id(my_green));
it.circle(120, 120, 120, id(my_green));
} else {
it.circle(120, 120, 115, id(my_red));
it.circle(120, 120, 116, id(my_red));
it.circle(120, 120, 117, id(my_red));
it.circle(120, 120, 118, id(my_red));
it.circle(120, 120, 119, id(my_red));
it.circle(120, 120, 120, id(my_red));
}
Sorry, nOOb question.
I’ve flashed the right Tosmato version, but where should I paste the config txt? Not in the HASS config file it seems.
This file is for ESPhome not Tosmato.
There is no way, Android will ever run on an ESP32 chip. The information you found applies to a device that is called “Sonoff NSPanel Pro” that looks the same but sells for close to $100. The NSPannel Pro has an ARM chips inside. (Like the chip in youe phone) With this ESP32-based device, if you want it to do graphics, you will have to write grapics software
openHASP uses LVGL to render widget & pictures. Works quite well on the ESP32-S3 4 inch module. Still exploring what is possible with this device.
A screenshot of the thermostat page:
Boot loop with my board too:
[23:56:47]ESP-ROM:esp32s3-20210327
[23:56:47]Build:Mar 27 2021
[23:56:47]rst:0x7 (TG0WDT_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
[23:56:47]Saved PC:0x400454d5
[23:56:47]SPIWP:0xee
[23:56:47]mode:QIO, clock div:1
[23:56:47]load:0x3fce3808,len:0x1658
[23:56:47]ets_loader.c 78
[23:56:47]ESP-ROM:esp32s3-20210327
[23:56:47]Build:Mar 27 2021
[23:56:47]rst:0x10 (RTCWDT_RTC_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
[23:56:47]SPIWP:0xee
[23:56:47]mode:QIO, clock div:1
[23:56:47]load:0x3fce3808,len:0x1658
[23:56:47]ets_loader.c 78
[23:56:48]ESP-ROM:esp32s3-20210327
[23:56:48]Build:Mar 27 2021
[23:56:48]rst:0x7 (TG0WDT_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
[23:56:48]Saved PC:0x400454d5
[23:56:48]SPIWP:0xee
[23:56:48]mode:QIO, clock div:1
[23:56:48]load:0x3fce3808,len:0x1658
[23:56:48]ets_loader.c 78
I’d like to understand why it works for some people but not for us.
YAML config
esphome:
name: 480x480
friendly_name: 480x480
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
version: recommended
# Custom sdkconfig options
sdkconfig_options:
COMPILER_OPTIMIZATION_SIZE: y
# Advanced tweaking options
advanced:
ignore_efuse_mac_crc: false
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "**************************"
ota:
password: "7267d8b91c798f050f17d37473c2aedc"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "480X480 Fallback Hotspot"
password: "c5Zlxtp2uTme"
captive_portal:
time:
- platform: homeassistant
timezone: "Europe/Paris"
id: esptime
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: 38
id: gpio_38_backlight_pwm
light:
- platform: monochromatic
output: gpio_38_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
- platform: homeassistant
id: devils_ivy_moisture
entity_id: sensor.flower_care_moisture
- platform: homeassistant
id: outdoor_temperature
entity_id: sensor.temperature_humidity_sensor_f402_temperature
# Example configuration entry
i2c:
- id: bus_a
sda: 19
scl: 45
scan: false
frequency: 10kHz
psram:
mode: octal
speed: 80MHz
spi:
clk_pin: 48
mosi_pin: 47
miso_pin: 41
font:
- file: 'fonts/arial.ttf'
id: font_16
size: 16
- file: 'fonts/arial.ttf'
id: font_24
size: 24
- file: 'fonts/arial.ttf'
id: font_32
size: 32
color:
- id: my_red
red: 100%
green: 1%
blue: 1%
- id: my_green
red: 3%
green: 100%
blue: 5%
- id: my_blue
red: 3%
green: 5%
blue: 100%
- id: my_white
red: 100%
green: 100%
blue: 100%
- id: my_black
red: 1%
green: 1%
blue: 1%
touchscreen:
platform: gt911
id: touchscreen_4_inches
i2c_id: bus_a
on_touch:
then:
- display.page.show_next: display_4_inches
- component.update: display_4_inches
- logger.log: "Touch, go to next page"
display:
- platform: st7701s
id: display_4_inches
spi_mode: MODE3
color_order: bgr
#invert_colors: true
dimensions:
width: 480
height: 480
cs_pin: 39
de_pin: 18
hsync_pin: 16
hsync_pulse_width: 9
hsync_front_porch: 10
hsync_back_porch: 50
vsync_pin: 17
vsync_pulse_width: 9
vsync_front_porch: 10
vsync_back_porch: 20
pclk_pin: 21
#pclk_frequency: 8MHz
#pclk_inverted: false
update_interval: never
auto_clear_enabled: false
#data_rate: 75kHz
#init_sequence:
# - 1 # select canned init sequence number 1
# - [ 0xE0, 0x1F ] # Set sunlight readable enhancement
data_pins:
blue:
- 11 #b1
- 12 #b2
- 13 #b3
- 14 #b4
- 0 #b5
green:
- 8 #g0
- 20 #g1
- 3 #g2
- 46 #g3
- 9 #g4
- 10 #g5
red:
- 4 #r1
- 5 #r2
- 6 #r3
- 7 #r4
- 15 #r5
pages:
- id: page1
lambda: |-
it.filled_rectangle(0, 0, 241, 241, my_black);
it.strftime(120,70, id(font_24), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(esptime).now());
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(outdoor_temperature).state);
it.circle(120, 120, 117, id(my_white));
it.circle(120, 120, 118, id(my_white));
- id: page2
lambda: |-
it.filled_rectangle(0, 0, 241, 241, my_black);
it.print(120, 100, id(font_32), id(my_white), TextAlign::CENTER, "Zanzibar Gem");
it.printf(120, 150, id(font_32), id(my_green), TextAlign::CENTER, "%.1f %%", id(devils_ivy_moisture).state);
if (id(devils_ivy_moisture).state>15) {
it.circle(120, 120, 115, id(my_green));
it.circle(120, 120, 116, id(my_green));
it.circle(120, 120, 117, id(my_green));
it.circle(120, 120, 118, id(my_green));
it.circle(120, 120, 119, id(my_green));
it.circle(120, 120, 120, id(my_green));
} else {
it.circle(120, 120, 115, id(my_red));
it.circle(120, 120, 116, id(my_red));
it.circle(120, 120, 117, id(my_red));
it.circle(120, 120, 118, id(my_red));
it.circle(120, 120, 119, id(my_red));
it.circle(120, 120, 120, id(my_red));
}
Which platformio_options are you using to make it work?
Initially I had some errors too. Then I found out that any device Id that isn’t exactly what you have will prevent the yaml file from loading and it will throw an error.
Now it seems to hang on Unpacking … but I leave it for some time to see whether it will come to live
Tool Manager: Installing espressif/toolchain-esp32ulp @ 2.35.0-20220830
INFO Installing espressif/toolchain-esp32ulp @ 2.35.0-20220830
Downloading [####################################] 100%
Unpacking [####################################] 100%
Tool Manager: [email protected] has been installed!
INFO [email protected] has been installed!
Tool Manager: Installing platformio/framework-espidf @ ~3.40406.0
INFO Installing platformio/framework-espidf @ ~3.40406.0
Downloading [####################################] 100%
Unpacking [####################################] 100%
If you don’t have this device, devils_ivy_moisture, in your HA setup, then it will throw an error.
Same for the other one.
I’m seeing the same loop on boot
I’ve updated the devils_ivy_moisture and outdoor_temperature to be valid sensors in my home assistant but still not working
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x400454d5
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x10 (RTCWDT_RTC_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x400454d5
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x1658
ets_loader.c 78
I got this screen working an even used the LVGL (BETA) component in ESPhome.
This is main workirng configuration without LVGL.
esphome:
name: esp32-4848s040
friendly_name: ESP32-4848S040
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
flash_size: 16MB
framework:
type: esp-idf
sdkconfig_options:
COMPILER_OPTIMIZATION_SIZE: y
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y
CONFIG_ESP32S3_DATA_CACHE_64KB: y
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
CONFIG_SPIRAM_RODATA: y
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "****"
ota:
password: "****"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-4848S040"
password: "****"
captive_portal:
psram:
mode: octal
speed: 80MHz
spi:
clk_pin: 48
mosi_pin: 47
# miso_pin: 41
i2c:
- id: bus_a
sda: 19
scl: 45
scan: false
#frequency: 100kHz
switch:
- platform: gpio
pin: 40
id: relay1
name: Relay 1
# - platform: gpio
# pin: 2
# id: relay2
# name: Relay 2
# - platform: gpio
# pin: 1
# id: relay3
# name: Relay 3
output:
- platform: ledc
pin: GPIO38
id: bl_led_pin
inverted: False
light:
- platform: monochromatic
output: bl_led_pin
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
binary_sensor:
- platform: status
id: status_sensor
internal: True
on_press:
then:
- component.update: display4inch
font:
- file: 'fonts/arial.ttf'
id: arial
size: 18
- file: 'fonts/arial.ttf'
id: arial_big
size: 96
display:
- platform: st7701s
id: display4inch
update_interval: never
auto_clear_enabled: False
spi_mode: MODE3
data_rate: 2MHz
color_order: RGB
invert_colors: False
dimensions:
width: 480
height: 480
cs_pin: 39
de_pin: 18
hsync_pin: 16
vsync_pin: 17
pclk_pin: 21
pclk_frequency: 12MHz
pclk_inverted: False
hsync_pulse_width: 8
hsync_front_porch: 10
hsync_back_porch: 20
vsync_pulse_width: 8
vsync_front_porch: 10
vsync_back_porch: 10
init_sequence:
- 1
# Custom sequences are an array, first byte is command, the rest are data.
- [ 0xFF, 0x77, 0x01, 0x00, 0x00, 0x10 ] # CMD2_BKSEL_BK0
- [0xCD, 0x00] # disable MDT flag
data_pins:
red:
- 11 #r1
- 12 #r2
- 13 #r3
- 14 #r4
- 0 #r5
green:
- 8 #g0
- 20 #g1
- 3 #g2
- 46 #g3
- 9 #g4
- 10 #g5
blue:
- 4 #b1
- 5 #b2
- 6 #b3
- 7 #b4
- 15 #b5
pages:
- id: deff
lambda: |-
// it.fill(COLOR_BLACK);
it.filled_rectangle(0, 0, 200, 200, id(my_black));
it.print(50, 50, id(arial), id(my_red), TextAlign::TOP_LEFT, "Hello World!");
it.printf(50, 70, id(arial), id(my_white), TextAlign::TOP_LEFT, "Brightness %.0f", id(back_light).current_values.get_brightness() * 100.0);
// test RGB pattern
//it.line(200, 99, 320, 99, id(my_white));
for(int i = 0; i < 256; i++) {
it.line(200, i + 100, 240, i + 100, Color(i, 0, 0));
it.line(240, i + 100, 280, i + 100, Color(0, i, 0));
it.line(280, i + 100, 320, i + 100, Color(0, 0, i));
}
touchscreen:
platform: gt911
id: touchscreen_4_inches
i2c_id: bus_a
on_touch:
then:
- component.update: display4inch
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]
- lambda: |-
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
touch.x,
touch.y,
touch.x_raw,
touch.y_raw
);
color:
- id: my_white
red: 100%
green: 100%
blue: 100%
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_black
red: 2%
green: 2%
blue: 0%
I found the root cause. It’s a USB port problem.
I’ve switch to another USB port and it now works. No more constant rebooting.
In another post I saw the work of Imre with this device and it looks awesome. Video and code included. Take a look!
@iMike78 Thanks for sharing!
I love that little screen. I now have a completely modular code system for it. You can add a button with one line of code.