本帖最后由 gasment 于 2026-3-23 16:54 编辑
最近跟ESPHOME LCD较上劲了,陆续搞了一些LCD屏来学习研究,方便扩展后续DIY项目,
没想到遇到的坑比想象的大得多,这里总结下学习经验,帮助大家少走弯路。
一、开发板选型
- 2~5寸屏幕建议搭配ESP32-S3,最好是N16R8型号,16MB Flash可以刷入更大的固件,在LVGL资源多了之后,固件很容易超过2M,再加上OTA分区,至少选择8MB Flash 型号。8 MB PSRAM 对 LVGL运行更是必须项目
- 5~10寸屏幕建议搭配ESP32-P4,需要无线功能的,选择带C6协处理器的版本。32MB Flash +32MB PSRAM,基本是顶配了,P4有MIPI显示专用接口,能接入更大速率更高的屏幕
- 更低配的型号不建议选择
二、触控屏幕选型
- IPS屏幕首选,屏幕总成要带玻璃面板的,裸LCD的最好不要搞
- 屏幕接口:
1、SPI:速率低(有速率高一些的QSPI),刷屏效率低,适合小尺寸低分辨率屏幕,宜使用静态页面和局部动画。SPI协议好处是GPIO占用少,留给外设的余量大。
显示主控需要选择esphome支持的(或者外部库组件):MIPI SPI Display Driver - ESPHome - Smart Home Made Simple
2、RGB: 速率比SPI高一两倍,适合中尺寸标清分辨率屏幕,刷屏效率能好一些,最大缺点是占用很多的GPIO,单单RGB565就要占用16个,加上一些屏幕控制引脚和一些保留引脚,S3基本就剩下一两个IO可自由分配。RGB屏幕一般不带主控。
3、DSI:DSI目前只esp32上只有P4配备,DSI速率很高,适合大尺寸高清分辨率屏幕,刷屏效率基本会卡在P4上,走专用接口连接屏幕,剩下的IO很富裕。
显示主控需要选择esphome支持的(或者外部库组件):MIPI DSI Display Driver - ESPHome - Smart Home Made Simple
三、具体案例
1、ESP32-S3 + SPI 3.5寸屏
屏幕型号:微雪 3.5 inch Capacitive Touch LCD,320x480,IPS,ST7796S 显示IC + FT6336U触控IC(官方两个都支持)这个屏幕基本没什么坑,按esphome和微雪的文档(3.5inch Capacitive Touch LCD - Waveshare Wiki) 配置好SPI总线,基本一次点亮
需要注意的配置:
需要反转颜色:
display:
- platform: mipi_spi
invert_colors: true
屏幕偏色(我的就是蓝色偏,浅蓝偏到深蓝),尝试用以下初始化序列修正:
display:
- platform: mipi_spi
init_sequence:
- [0xF0, 0xC3]
- [0xF0, 0x96]
- [0xE0, 0x00, 0x02, 0x03, 0x05, 0x05, 0x02, 0x25, 0x33, 0x3F, 0x04, 0x10, 0x0E, 0x28, 0x30, 0x0F]
2、ESP32-S3 + RGB 4.3寸屏
屏幕型号:微雪 4.3inch Capacitive Touch LCD,800x480,IPS,无显示IC + GT911触控IC(官方支持),这个屏有一些坑
ESP32-S3端口分配:尽量不要分配使用GPIO3/46/37/36/35/0/45/21/20这个特殊引脚
vsync和hsync参数需要指定,否则会出现屏幕抖动:
display:
- platform: mipi_rgb
id: display1
model: RPI
auto_clear_enabled: false
update_interval: never
color_order: rgb
pclk_frequency: 16MHz
dimensions:
height: 480
width: 800
data_pins:
red:
green:
blue:
de_pin:
pclk_pin:
hsync_pin:
vsync_pin:
reset_pin:
hsync_back_porch: 40
hsync_front_porch: 40
hsync_pulse_width: 48
vsync_back_porch: 20
vsync_front_porch: 12
vsync_pulse_width: 10
这个屏支持PWM调整背光亮度,如果使用PWM引脚,可以不接DISP引脚
增加一个调整背光的实体:
output:
- platform: ledc
pin: GPIO13 # ← 改成你的实际背光 PWM 引脚,例如 GPIO10、GPIO9 等
id: backlight_pwm
frequency: 1000Hz
inverted: true
# ======================
light:
- platform: monochromatic
name: "屏幕背光"
id: screen_backlight
output: backlight_pwm
restore_mode: RESTORE_DEFAULT_ON # 可选:开机自动恢复上次亮度,或改成 RESTORE_AND_ON / ALWAYS_OFF
default_transition_length: 0.3s # 可选:调节亮度时的渐变时间
gamma_correct: 1.0
3、ESP32-P4-WIFI6 + DSI 10.1寸屏
屏幕型号:微雪 10.1-DSI-TOUCH-A,800×1280,IPS,显示IC为JD9365,触摸 IC为GT9271(官方两个都未支持)这个屏幕坑巨大
JD9365显示IC,微雪官方提供了BSP组件驱动(waveshare/esp32_p4_nano • v1.2.0 • ESP Component Registry),但是无法用于ESPHOME,不过有解
GT9271触摸 IC,使用官方支持的GT911可以兼容
单P4模组是不带无线功能(wifi/bt)的,需要带无线的,要选择带协处理器的模组,比如P4+C6,我用的是微雪的ESP32-P4-WIFI6开发板
坑1:P4与C6的连接问题
esphome支持P4的协处理器功能,需要使用esp32_hosted组件:
esp32_hosted:
variant: ESP32C6
active_high: true
reset_pin: GPIO54
cmd_pin: GPIO19
clk_pin: GPIO18
d0_pin: GPIO14
d1_pin: GPIO15
d2_pin: GPIO16
d3_pin: GPIO17
*以上GPIO都是内部定义的,不可修改。
但是,单单这样无法让P4通过SDIO连接到C6,因为ESPHOME需要C6上使用ESP-Hosted-MCU固件内协议来通讯,而这个开发版出厂带的是ESP-Hosted-NG固件,两者不论是通讯协议还是固件分区都不兼容,需要为C6刷入完整的ESP-Hosted-MCU固件(包含bootloader、分区表等部分)才能完成P4的通讯
我自己编译了一份截稿前最新的ESP-Hosted-MCU全量固件(2.12.1),你需要的话,按照flash-cmd里面的命令,使用esphome 附带的esptool 刷入即可
对于ESP32-P4-WIFI6开发板刷写C6的方法:
1、板子断电,将c6模块下方的TXD引脚,连接到外部串口工具(比如CH340等USB转串口工具)的RX脚
2、将c6模块下方的RXD引脚,连接到外部串口工具的TX脚
3、将c6模块下方的GND引脚,连接到外部串口工具的GND脚
4、将c6模块下方的IO9引脚,连接到开发板上任意一个GND,用于拉低进入烧录模式,烧录完成前不要断开IO9<->GND
5、将外部串口工具连接到电脑,此时应检测到对应的COM口
6、保持上述连接状态,按住开发板的BOOT按钮,给开发板通电(单通电不要USB通讯)
7、使用esptool工具执行 esptool chip-id 命令,检查串口工具的COM口信息是否为C6,如果仍为P4或检测不大到,重新 由第一步开始,或者尝试,不按住BOOT通电
8、检测为C6后,即可使用flash-cmd内命令刷入全量固件
C6固件更新,可以使用update组件,从网络在线更新,新建实体配置:
http_request:
update:
- platform: esp32_hosted
id: update_for_c6
name: "C6 Module Ver"
icon: "mdi:chip"
entity_category: "diagnostic"
type: http
source: https://esphome.github.io/esp-hosted-firmware/manifest/esp32c6.json
update_interval: never
button:
- platform: template #c6检查更新
name: "C6 Update Check"
entity_category: "diagnostic"
icon: "mdi:cellphone-arrow-down"
on_press:
then:
- update.check:
id: update_for_c6
坑2:esphome 2026.3.0更新
2026.3.0更新对P4添加了一个破坏性更新:
esp32:
variant: esp32p4
engineering_sample: true
对于P4芯片版本低于3的编译,必须配置 engineering_sample: true,否则刷入后会无限重启
当前芯片版本会在启动日志中显示,我的为1.3
坑3:板载音频解码和功放问题
这个开发板板载了ES8311音频解码和一个2W功放,esphome支持ES8311,测试音频播放会存在高音量破音,首次播放破音等问题,暂时未找到解决办法
坑4:显示屏驱动问题
虽然esphome 2026.3.0更新支持了WAVESHARE-10.1-DSI-TOUCH-A这块屏的配置,但是只是复用了P4-NANO-10.1的配置,而NANO-10的配置用在TOUCH-A上存在严重问题。
翻查微雪官方的驱动C文件,对比esphome P4-NANO-10.1 的配置,缺少了一些很重要的初始化序列,
WAVESHARE-10.1-DSI-TOUCH-A这块屏,必须在通电后往其i2c的特定寄存器写入特定数据,才会使能显示IC,如果没有在esphome的mipi_setup前使能这个IC,mipi_setup就会因通讯超时而触发看门狗,导致循环重启
另外vsync和hsync与微雪驱动也有些出入,一同修正,其余参数一致无需重复配置:
display:
- platform: mipi_dsi
id: main_display
model: WAVESHARE-10.1-DSI-TOUCH-A
rotation: 270
hsync_pulse_width: 20
hsync_back_porch: 20
hsync_front_porch: 40
vsync_pulse_width: 4
vsync_back_porch: 10
vsync_front_porch: 30
update_interval: never
auto_clear_enabled: false
esphome:
on_boot:
priority: 800 #必须在最高优先级操作i2c,早于mipi_setup
then:
- lambda: |-
uint8_t d1[2] = {0x95, 0x11};
uint8_t d2[2] = {0x95, 0x17};
uint8_t d3[2] = {0x96, 0x00};
id(bus_a).write(0x45, d1, 2);
id(bus_a).write(0x45, d2, 2);
id(bus_a).write(0x45, d3, 2);
- delay: 100ms
- lambda: |-
uint8_t d4[2] = {0x96, 0xFF};
id(bus_a).write(0x45, d4, 2);
- delay: 300ms
进行了一些反复测试,发现on_boot方法并不稳定,会被其他组件的执行时间影响,导致未能在mipi_setup前运行,引发循环重启
为了稳定这个i2c操作的执行时机,只能修改官方mipi_dsi的源码,在setup方法前注入i2c操作,为此我基于esphome 2026.3.0版本的mipi_dsi组件,Patch了一份专门针对这块屏的外部组件,在yaml内直接引用即可,不再需要on_boot配置:
external_components:
- source:
type: git
url: https://github.com/gasment/esphome_mipi_dsi_patch_for_jd9365_10_1_dsi_touch_a
ref: main
components: [ mipi_dsi ]
refresh: always
display:
- platform: mipi_dsi
id: main_display
model: WAVESHARE-10.1-DSI-TOUCH-A
power_i2c: bus_a #此为新增的配置,配置为你的屏幕所在的i2c总线id
rotation: 270
hsync_pulse_width: 20
hsync_back_porch: 20
hsync_front_porch: 40
vsync_pulse_width: 4
vsync_back_porch: 10
vsync_front_porch: 30
update_interval: never
auto_clear_enabled: false
坑5:ESp32-P4 LDO配置
P4有4个低压差线性稳压器,可用于为片上和片外外设供电
1、2路分配给了内置组件,3、4路开放给外设
这个配置会影响GPIO的输出电压,如果你想用GPIO点灯或点继电器,需要3.3V的话,需要配置为:
esp_ldo:
- channel: 3
voltage: passthrough
- channel: 4
voltage: passthrough
*非passthrough只支持0.5-2.7V,esp_ldo同时也是display的必要组件
坑6: LVGL颜色配置
默认的RGB颜色顺序是不对的,需要配置为:
lvgl:
byte_order: little_endian #颜色修正
坑7:屏幕背光亮度调整
这个屏没有配备PWM接口用于亮度调整,但是可以操作它的i2c特定寄存器来实现亮度调整.
新建灯实体用于模拟背光调整:
light:
- platform: monochromatic
id: lcd_backlight
name: "LCD Backlight"
output: lcd_backlight_output
default_transition_length: 400ms
restore_mode: ALWAYS_ON
output:
- platform: template
id: lcd_backlight_output
type: float
write_action:
- lambda: |-
float brightness = state;
uint8_t value = (uint8_t)(brightness * 255.0f);
id(lcd_backlight_value) = value;
uint8_t d[2] = {0x96, value};
id(bus_a).write(0x45, d, 2);
PS: 这个开发板带串口芯片,走的UART0转USB,所以USB接口看启动日志需要配置为
logger:
hardware_uart: UART0
level: debug
✅以上~
|