WLED pixels_dice_tray Usermod:BLE 支持要求、library.json 禁用机制与自定义构建实践
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
本文围绕 WLED 仓库中 BLE_REQUIREMENT.md 展开,讲解pixels_dice_trayUsermod 为何无法随标准 WLED 固件一起编译、为什么它的library.json被改名为library.json.disabled,以及如何通过platformio_override.ini自定义构建环境为 ESP32-S3 烧录一个支持 ESP32 BLE(Bluetooth Low Energy)的定制固件。读完本篇,你可以独立完成从复制示例配置、修改构建参数到执行pio run出固件的完整流程,并理解 WLED 构建系统自动发现 Usermod 的底层机制。
为什么这个 Usermod 需要特殊的 BLE 配置
pixels_dice_tray是一个让 WLED 作为 BLE 主机(BLE Central)连接 Pixels Dice。骰子作为 BLE 外设(Peripheral)广播掷骰结果,ESP32 负责扫描、连接并把结果转化为 LED 效果、TFT 菜单和 MQTT 事件。
BLE 支持不是所有 WLED 构建都具备的:
- WLED 的 ESP32 构建默认使用Tasmota Arduino ESP32 平台(
platform-espressif32),例如 platformio.ini 中[esp32_idf_V4]使用的平台包,以及 platformio.ini 中[esp32_idf_V5]使用的更新版本。 - 该 Tasmota 平台默认不包含 Arduino BLE 库。如果把
pixels_dice_tray自动纳入构建,编译会直接失败,因为它的源码依赖ESP32 BLE Arduino库(见 platformio_override.ini.sample 中的lib_deps)。
因此该 Usermod不能简单地用custom_usermods = *纳入通用构建,必须走自定义构建环境(见下文操作)。
library.json 为什么被禁用:构建系统的自动发现机制
library.json已被重命名为 library.json.disabled。要理解这个操作的必要性,需要看 WLED 的 Usermod 加载脚本 pio-scripts/load_usermods.py:
for token in line.split(): if token == '*': for mod_path in sorted(usermod_dir.iterdir()): if mod_path.is_dir() and (mod_path / 'library.json').exists(): _custom_usermod_names.add(mod_path.name) usermods_libdeps.append(f"symlink://{mod_path.resolve()}")pio-scripts/load_usermods.py 显示:当构建配置中custom_usermods = *(platformio.ini 中的usermods等环境即采用此写法,含义是"展开为 usermods 文件夹中的所有 Usermod")时,脚本会遍历usermods/目录,凡是目录内存在library.json的 Usermod 都会被以symlink://形式自动加入lib_deps参与编译。
也就是说,只要pixels_dice_tray目录下有library.json,所有custom_usermods = *的构建环境都会自动拉入它,随即因为缺少 BLE 库而编译失败。把文件改名为library.json.disabled后,load_usermods.py的目录扫描就找不到它,从而安全地把它排除在通用构建之外——这是一个用"命名约定"实现的构建级开关。
自定义构建操作步骤
文档给出的完整流程如下,全部步骤均可复现。
第一步:复制示例配置到构建根目录
在usermods/pixels_dice_tray/目录下执行:
cp platformio_override.ini.sample ../../../platformio_override.ini即把示例文件复制到仓库根目录、重命名为platformio_override.ini,与 platformio.ini 同目录(PlatformIO 会自动将其与主配置合并)。随后按你所用的 ESP32 开发板修改该文件。
第二步:理解示例配置中的两个构建环境
platformio_override.ini.sample 定义了default_envs = t_qt_pro_8MB_dice, esp32s3dev_8MB_qspi_dice,两个环境的共同点:
| 配置项 | 取值 | 说明 |
|---|---|---|
board | esp32-s3-devkitc-1 | 通用 ESP32-S3 开发板板型 |
platform | ${esp32s3.platform} | 复用 WLED 主配置的 ESP32-S3 平台定义(Tasmota 平台包) |
board_build.partitions | ${esp32.large_partitions} | 大容量分区布局 |
board_build.f_flash/flash_mode | 80000000L/qio | 80MHz QIO 闪存 |
build_flags | ${common.build_flags} ${esp32s3.build_flags}等 | 在 WLED 通用构建参数之上追加 Usermod 宏 |
lib_deps | ${esp32s3.lib_deps}+ESP32 BLE Arduino+axlan/pixels-dice-interface @ 1.2.0 | 关键:显式引入 Arduino BLE 库,这正是标准构建缺失的部分 |
Usermod 相关的关键编译宏(t_qt_pro_8MB_dice环境):
-D USERMOD_PIXELS_DICE_TRAY ;; Enables this UserMod -D USERMOD_PIXELS_DICE_TRAY_BL_ACTIVE_LOW=1 -D USERMOD_PIXELS_DICE_TRAY_ROTATION=2这些宏在 pixels_dice_tray.cpp 中均有#ifndef默认值兜底(如USERMOD_PIXELS_DICE_TRAY_ROTATION默认 0,USERMOD_PIXELS_DICE_TRAY_REFRESH_RATE_MS默认 200ms),因此最简构建只需-D USERMOD_PIXELS_DICE_TRAY一个宏即可启用。
t_qt_pro_8MB_dice(带 128x128 TFT 屏的 LILYGO T-QT Pro,8MB 闪存):在 Usermod 宏之外还引入bodmer/TFT_eSPI @ 2.5.43,并携带一组 TFT_eSPI 编译期参数,例如USER_SETUP_ID=211、GC9A01_DRIVER=1、TFT_WIDTH=128/TFT_HEIGHT=128、TFT_ROTATION=3、引脚定义TFT_MOSI=2、TFT_SCLK=3、TFT_CS=5、TFT_DC=6、TFT_RST=1、TFT_BL=10,以及 SPI 频率(SPI_FREQUENCY=40000000等)。注意 TFT_eSPI 要求引脚在编译期固定,运行时修改无效——这一点在 Usermod 源码注释中也有强调(见 pixels_dice_tray.cpp 的NOTE: THIS MOD DOES NOT SUPPORT CHANGING THE SPI PINS FROM THE UI!)。
esp32s3dev_8MB_qspi_dice(无屏幕的 ESP32-S3 开发板,8MB 闪存):只追加-D USERMOD_PIXELS_DICE_TRAY,不引入 TFT_eSPI,是验证 BLE 功能的最小构建。
第三步:用自定义环境构建
pio run -e t_qt_pro_8MB_dice # 或 pio run -e esp32s3dev_8MB_qspi_dice构建产物即可通过 PlatformIO 常规方式烧录(pio run -t upload);示例配置中还设置了upload_speed = 921600和monitor_filters = esp32_exception_decoder(便于解析崩溃回溯)。
平台要求与适用边界
文档明确列出的平台要求:
- ESP32-S3 或兼容的、具备 BLE 能力的 ESP32 开发板;
- 必须使用自定义 PlatformIO 环境(参考 platformio_override.ini.sample);
- 不能用于 ESP8266 和 ESP32-S2(二者不具备该 Usermod 所需的 BLE 支持/组合)。
从源码与示例配置还能补充两点边界:
- 原始 ESP32(非 S3)实测不可用。platformio_override.ini.sample 中保留了一个被整体注释掉的
esp32dev_dice环境,作者记录:该环境可以编译和烧录,但启动后在 AP 初始化之后即出现内存分配异常(回溯指向 UDP 栈的new[]),从源码结构看是BLE 扫描任务与 WiFi 网络任务并行运行时的竞争问题,作者将其标记为 "THIS DOES NOT WORK!!!!!!"。这与 README.md 中 "I found that the original ESP32 did not work" 的结论一致。 - BLE 协议栈占用大量闪存。README.md 给出实测体积:含 TFT 代码约 1.9MB,不含则约 1.85MB,已无法放入 WLED 默认的 4MB 分区布局(
tools/WLED_ESP32_4MB_256KB_FS.csv),4MB 设备只能用本目录专门制作的 WLED_ESP32_4MB_64KB_FS.csv(文件系统仅 64KB,预设较多时会捉襟见肘)。因此要发挥完整功能建议使用 8MB 及以上闪存——这也解释了示例环境为什么都命名为..._8MB_...。
BLE 支持在源码中的落地方式
以下细节可与文档要求互相印证,帮助排查"BLE 没连上"一类问题。
强制开启 WiFi 休眠。ESP32 上 BLE 与 WiFi 共存时,WiFi 模组休眠是协议栈的硬性要求。pixels_dice_tray.cpp 的
setup()中:// Need to enable WiFi sleep: // "E (1513) wifi:Error! Should enable WiFi modem sleep when both WiFi and Bluetooth are enabled!!!!!!" noWifiSleep = false;若漏掉这一行,日志中会持续打印上述 IDF 错误,BLE 行为会变得不可预期。README.md 提到这是该 Usermod 需要的"唯一特殊行为"。
周期性 BLE 扫描与自动恢复。
setup()中调用pixels::ScanForDice(ble_scan_duration_sec, BLE_TIME_BETWEEN_SCANS_SEC)启动后台扫描任务(pixels_dice_tray.cpp)。两个周期均有编译期默认值(pixels_dice_tray.cpp):单次扫描时长BLE_SCAN_DURATION_SEC = 4秒,两轮扫描间隔BLE_TIME_BETWEEN_SCANS_SEC = 5秒;ble_scan_duration_sec可经 Web 配置页调整(设置项ble_scan_duration,见 pixels_dice_tray.cpp 的addToConfig)。loop()中还实现了扫描状态的自动切换:所有配置的骰子都连上就StopScanning(),有骰子掉线则重新ScanForDice()(pixels_dice_tray.cpp)。骰子槽位与通配符匹配。
loop()通过pixels::ListDice()获取已连接设备,先按已记录 ID 匹配,再按配置名称匹配,最后尝试*通配槽位并把通配符替换为该骰子的实际名称(pixels_dice_tray.cpp,配合UpdateDieNames的"锁定"逻辑,pixels_dice_tray.cpp)。这正是文档所说"保存配置时若通配槽已连接骰子,*会被替换为该骰子名称"的实现。掷骰结果的 MQTT 上报。每收到一条掷骰更新,若 MQTT 已连接则向
$mqttDeviceTopic/dice/roll发布 JSON,字段包括骰子名name、状态state、点数val、时间戳time(pixels_dice_tray.cpp)。TFT 构建的闲置断电。带 TFT 的构建还定义了
USERMOD_PIXELS_DICE_TRAY_TIMEOUT_MS(默认 5 分钟),若配置了骰子却长时间扫不到任何设备,Usermod 会关闭背光并调用esp_deep_sleep_start()进入深睡(pixels_dice_tray.cpp)。
在自己的构建中重新启用 library.json
如果你希望把这个 Usermod 纳入自己的自定义构建(而不是每次依赖示例文件),文档给出的步骤是:
- 把
library.json.disabled改回library.json(恢复 usermods/pixels_dice_tray/library.json 文件); - 在你的自定义环境中显式将
pixels_dice_tray加入custom_usermods列表; - 确认该环境的
lib_deps包含 BLE 支持(ESP32 BLE Arduino库及axlan/pixels-dice-interface @ 1.2.0,参考 platformio_override.ini.sample)。
需要注意第 1 步的影响面:一旦library.json恢复,pio-scripts/load_usermods.py 的*通配逻辑会重新把它拖进所有custom_usermods = *的环境,导致这些环境缺 BLE 库而编译失败。因此该文件保持.disabled状态是上游仓库有意为之的默认选择,除非你确认所有通配构建环境都已补齐 BLE 依赖。
小结与进一步阅读
- 需求文档:usermods/pixels_dice_tray/BLE_REQUIREMENT.md(本篇的主体来源)
- 构建配置示例:usermods/pixels_dice_tray/platformio_override.ini.sample(含两个可用环境与一个已废弃的原始 ESP32 环境记录)
- Usermod 完整文档:usermods/pixels_dice_tray/README.md(效果参数、TFT GUI、MQTT 事件、骰子连接配置)
- 核心实现:usermods/pixels_dice_tray/pixels_dice_tray.cpp
- 自动加载机制:pio-scripts/load_usermods.py 与 platformio.ini
核心要点回顾:pixels_dice_tray的 BLE 依赖是"平台级"缺口——Tasmota 平台默认不含 Arduino BLE 库,而custom_usermods = *的目录扫描机制又会无条件纳入带library.json的 Usermod,两者叠加决定了必须library.json.disabled+ 自定义环境(ESP32 BLE Arduino库 +USERMOD_PIXELS_DICE_TRAY宏)的双保险方案。构建时认准esp32s3dev_8MB_qspi_dice或t_qt_pro_8MB_dice两个环境即可。
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考