No description
  • Python 99.8%
  • Batchfile 0.2%
Find a file
2026-10-15 15:23:18 +08:00
.forgejo/workflows 放宽 Matrix 与灯带 SPI 交界间隔 v1.8.2 2026-08-13 11:30:40 +08:00
.github/workflows 放宽 Matrix 与灯带 SPI 交界间隔 v1.8.2 2026-08-13 11:30:40 +08:00
supplier_debug_tool feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00
tools feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00
build_windows.bat 初始化 DNTC 灯效调试工具 2026-06-30 17:10:38 +08:00
DNTCLightDebug.spec feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00
DNTCLightDebug_User_Guide.md feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00
README.md 放宽 Matrix 与灯带 SPI 交界间隔 v1.8.2 2026-08-13 11:30:40 +08:00
requirements.txt 初始化 DNTC 灯效调试工具 2026-06-30 17:10:38 +08:00
test_matrix_frame.py 放宽 Matrix 与灯带 SPI 交界间隔 v1.8.2 2026-08-13 11:30:40 +08:00
test_measure.py feat: 新增「颜色测量」页(点阵 149 个测量点 + 读数表导出),界面精简,调试工具 2.4.1 2026-10-10 18:00:43 +08:00
test_test_page.py feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00
verify_ch347.py 初始化 DNTC 灯效调试工具 2026-06-30 17:10:38 +08:00
更新日志.md feat: 测试页新增「场景图片」(雪山极光、草原长颈鹿),调试工具 2.4.2 2026-10-15 15:23:18 +08:00

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

它会依次执行:

  1. 安装 requirements.txt
  2. 跳过硬件验证
  3. 用 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。

当前实现使用经公开头文件/示例确认的基础函数:

  • CH347OpenDevice
  • CH347CloseDevice
  • CH347SPI_Init
  • CH347SPI_Write
  • CH347StreamSPI4

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。

推荐两种部署方式:

  1. 安装官方驱动包:安装后 Windows 可从系统路径加载 CH347DLLA64.dll,GUI 中 DLL 字段保持默认 CH347DLLA64。
  2. 随 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 输入框。

供应商建议先跑两组:

  1. Strip Channels=5,strip:1..5 LED Count 全部相同,确认 5 路同 frame_id 刷新。
  2. 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 一致。

建议联调顺序

  1. 使用 Mock 模式确认 GUI、ALPK header、frame_id 和变长 payload;
  2. 使用 Serial 模式确认开发板 ALPK STRIP_FRAME 解析;
  3. 接入 CH347 SPI DLL,确认 5 路灯带连续帧;
  4. 再做 strip:1=140、strip:2..5=70 的变长联调。