- Python 99.8%
- Batchfile 0.2%
| .forgejo/workflows | ||
| .github/workflows | ||
| supplier_debug_tool | ||
| tools | ||
| build_windows.bat | ||
| DNTCLightDebug.spec | ||
| DNTCLightDebug_User_Guide.md | ||
| README.md | ||
| requirements.txt | ||
| test_matrix_frame.py | ||
| test_measure.py | ||
| test_test_page.py | ||
| verify_ch347.py | ||
| 更新日志.md | ||
DNTC Light Debug Tool
一个独立的 Windows 灯带调试工具项目,用于给供应商调试 USB → CH347 → SPI/串口 → 灯效开发板链路。
当前版本重点支持:
- GUI 双标签:灯带 Strip 与 点阵 Matrix;
- 同时启动:一个工作线程使用独立 Matrix/Strip FPS,同时下发 Matrix 和 1~5 路灯带;
- 灯带:内置本地静态预设灯效,ALPK V1
STRIP_FRAME (0x21),同一frame_id下发 1~5 路、每路 LED 数量独立配置; - 点阵:内置预渲染动画,ALPK V1
MATRIX_FRAME (0x20),内置30×16/60×32面板尺寸; - RGB24 帧流;
- Mock 传输、串口传输、CH347 SPI DLL 传输。
点阵动画资产(Matrix)
点阵标签的动画是离线预渲染帧,打包在 supplier_debug_tool/assets/matrix_animations.json,exe 内只回放,
不携带 numpy/脚本沙箱。当前内置矩阵尺寸只有 30×16 和 60×32 两种;如需新增/更换面板尺寸或动画,在 light 后端环境重新烘焙后再出包:
# 在 light 后端的 Python 环境(需 numpy/scipy/perlin_noise/opensimplex)
python supplier_debug_tool/tools/bake_matrix_animations.py --sizes 30x16,60x32
烘焙脚本复用 light 的 matrix_service 沙箱渲染,输出字节与服务端推流完全一致。
运行
cd supplier_debug_tool
python -m pip install -r requirements.txt
python -m supplier_debug_tool
打包 EXE
推荐:Windows 一键打包
不接入硬件也可以先打包:
build_windows.bat
它会依次执行:
- 安装
requirements.txt - 跳过硬件验证
- 用 PyInstaller 打包 exe
如果已接入 CH347,并希望打包前强制验证硬件:
build_windows.bat --verify-hardware
此模式会在打包前运行 verify_ch347.py 验证:
CH347DLLA64.DLL是否能加载CH347OpenDevice(0)是否成功CH347StreamSPI4(...)是否返回成功
如果只想单独验证 CH347:
python verify_ch347.py
可选参数示例:
python verify_ch347.py --dll drivers\CH347DLLA64.DLL --index 0 --chip-select 0x80 --payload 414c504b
payload=414c504b 即 ASCII ALPK,便于用逻辑分析仪/示波器确认 MOSI 输出。
手动打包
cd supplier_debug_tool
python -m pip install -r requirements.txt
python -m PyInstaller --noconfirm --onefile --windowed --name DNTCLightDebug supplier_debug_tool\__main__.py
或使用仓库内置 spec:
pyinstaller --noconfirm DNTCLightDebug.spec
生成文件:
dist/DNTCLightDebug.exe
传输方式
Mock
不连接硬件,只在日志窗口显示发送行为,用于 GUI 和协议自测。
Serial
通过 pyserial 打开串口设备并写入 ALPK 帧。适合 CH347 VCP/串口桥接调试,或供应商板先用串口口径验证协议。
CH347 SPI DLL
接口:supplier_debug_tool/transports/ch347_spi.py。
当前实现使用经公开头文件/示例确认的基础函数:
CH347OpenDeviceCH347CloseDeviceCH347SPI_InitCH347SPI_WriteCH347StreamSPI4
GUI 会通过 CH347SPI_Init 配置 SPI 时钟;连续大帧通过 CH347SPI_Write 分块写入并保持一次传输语义,避免 CH347StreamSPI4 单次约 4KB 限制影响长灯带或大矩阵帧。
CH347 默认使用 7.5 MHz。每次完整 CH347SPI_Write(即一个 PacketHeader + payload)结束后,传输层会保证下一包开始前至少空闲 500 us,满足 MCU 大于 400 us 的重新装载时间。这个间隔只存在于完整 ALPK 包之间;同一次 CH347SPI_Write 内部的 507-byte Matrix 分段保持连续,不插入间隔。
MATRIX_FRAME 与 STRIP_FRAME 相互切换时,间隔放宽到至少 2500 us。供应商在 60×34 面板上实测:MCU 处理一帧约 900 us,该数据长度重新装载 SPI 接收约 1200 us,共约 2100 us;只留 500 us 会让下一包的 CS 落在 MCU 仍然忙的时候,表现为灯带丢帧。传输层按 ALPK 头里的 msg_type 自动判断该用哪个间隔,同一条流内部(例如一个批次里的 strip:1..3)仍是 500 us——Matrix 单发和灯带单发在 500 us 下已实测无丢帧,只有交界处需要放宽。
Matrix 使用高精度单调时钟按帧起始时间节拍发送,并在 deadline 前完成 RGB 缩放、元数据、CRC 和完整 ALPK 封包;deadline 到达后只执行 DLL 写。Matrix 工作线程使用高优先级。30 FPS 的目标周期为 33.333333 ms;若 Windows、USB 或 DLL 偶发阻塞,工具不会快速补发过期帧,而是从实际发送时刻恢复完整周期,避免产生异常短的 Vsync 间隔。
需要灯带和 Matrix 同时点亮时,使用 同时启动。该模式只创建一个高优先级工作线程,Matrix 使用 Matrix 页 FPS,Strip 使用灯带页 FPS,两个 deadline 独立调度。Matrix deadline 优先;Strip 批次只在完整批次能够安全发完时才开始,绝不中途暂停,也不排队补发过期帧。Matrix 和 Strip 使用各自的 frame_id,同一个 Strip 批次的 strip:1..N 共享 frame_id 并保持连续,Matrix 不会插入批次中间。因此不存在两个发送线程争抢客户端/SPI 锁的问题;各个完整包之间仍由 CH347 传输层保证间隔:同一条流 500 us,Matrix 与 Strip 交界 2500 us。Strip 批次的准入判断把批次后面那段 2500 us 交界间隔一并算进去,所以放宽间隔不会把 Matrix 的 deadline 顶后(Matrix 周期抖动正是之前看到的闪烁来源)。独立的“启动灯带”和“启动点阵”仍用于单项调试,不允许与其他推流任务重叠。
SPI 是主机主动时钟。连续灯带帧使用 ALPK STRIP_FRAME 单向下发;灯带尺寸不通过 HELLO 握手校验。点阵使用 HELLO/HELLO_ACK 确认矩阵面板尺寸,再下发 MATRIX_FRAME;控制包可通过 Require ACK 做可靠握手诊断。最终物理时序应以逻辑分析仪测得的 CS/SCLK 为准。
官方 DLL / 驱动放置方式
如果使用 CH347 SPI DLL 后端,需要供应商或调试电脑具备 WCH 官方 CH347/CH341PAR 驱动与 DLL。建议从 WCH 官网下载对应驱动包,例如:
https://www.wch.cn/downloads/category/67.html
当前本地交付目录已按官方 CH341PAR.ZIP 提取必要文件到:
supplier_debug_tool/drivers/CH347DLLA64.DLL
supplier_debug_tool/drivers/CH347DLL_EN.H
drivers/ 目录只用于供应商本地调试交付,已加入根 .gitignore,不要上传 GitHub。
推荐两种部署方式:
- 安装官方驱动包:安装后 Windows 可从系统路径加载
CH347DLLA64.dll,GUI 中 DLL 字段保持默认CH347DLLA64。 - 随 exe 放置 DLL:将官方包里的
CH347DLLA64.DLL放到DNTCLightDebug.exe同目录,或放到drivers/目录。GUI 默认会优先使用本项目drivers/CH347DLLA64.DLL。
不建议把未知来源 DLL 提交进源码仓库;如果要随安装包分发,应先确认 WCH 驱动/DLL 的授权条款。
若要把 DLL 打进 PyInstaller 产物,可在 Windows 打包机上使用:
pyinstaller --noconfirm --onefile --windowed \
--name DNTCLightDebug \
--add-binary "drivers/CH347DLLA64.dll;." \
supplier_debug_tool/__main__.py
协议
工具的连续帧流使用 ALPK V1 STRIP_FRAME:
ALPK Header(20B, magic=`ALPK`, Big-Endian, CRC32 payload)
+ StripFramePayloadV1(frame_id, channel_id, led_count, duration_ms, rgb_len, rgb)
关键字段:
| 字段 | 说明 |
|---|---|
msg_type |
0x21 = STRIP_FRAME |
frame_id |
同一发送 tick 的 1~5 路灯带使用相同值,用于固件侧同步刷新 |
channel_id |
strip:1..5,保持固定座舱通道映射 |
led_count |
当前通道 LED 数量 |
duration_ms |
当前帧建议持续时间,按 GUI FPS 计算 |
rgb_len |
led_count * 3 |
rgb |
RGB24 数据 |
GUI 的 Strip Channels 滑条配置下发灯带数量(1~5),并按数量显示 strip:N LED Count 输入框。
供应商建议先跑两组:
Strip Channels=5,strip:1..5LED Count 全部相同,确认 5 路同frame_id刷新。Strip Channels=5,strip:1=140,strip:2..5=70,确认变长 ALPK packet 可按channel_id/led_count/rgb_len路由。
点阵 MATRIX_FRAME (0x20)
ALPK Header(20B) + MatrixFramePayloadV1(frame_id, width, height, duration_ms, rgb_len, rgb)
| 字段 | 说明 |
|---|---|
msg_type |
0x20 = MATRIX_FRAME(不逐帧 ACK) |
| 元数据 struct | >IHHII = frame_id, width, height, duration_ms, rgb_len(大端) |
rgb_len |
width * height * 3 |
rgb |
RGB24,行优先(左到右、上到下),左上角原点 |
当前 Debug Tool 内置 30×16 和 60×32 两种点阵资产。点阵启动时通过 HELLO/HELLO_ACK 确认板端矩阵尺寸;灯带启动不发送 140×1 之类的尺寸握手。
完整定义见 hardware/docs/USB_CH347_SPI_MATRIX_PROTOCOL_V1.md 第 7 章。与服务端 main.py 的 ALPK_MATRIX_FRAME_META_STRUCT 一致。
建议联调顺序
- 使用 Mock 模式确认 GUI、ALPK header、
frame_id和变长 payload; - 使用 Serial 模式确认开发板 ALPK
STRIP_FRAME解析; - 接入 CH347 SPI DLL,确认 5 路灯带连续帧;
- 再做
strip:1=140、strip:2..5=70的变长联调。