# DLPilot — HDMI 源端调试 + 光机控制工具 > LT8619C(HDMI→RGB888)→ DLPC3421 投影转接板调试配套的 PC 端工具: > HDMI **源端**(EDID 查看、分辨率切换、纯色/测试图案投屏)+ **光机控制** > (RS485 直连板上 GD32 网关,开关光机/设光强/查温度电流)。 > > - **只想用工具**:到 [Gitea Releases](https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools/releases) > 下载 `DLPilot-vX.Y.Z-win64.zip`,解压双击 `DLPilot.exe` 即可(Windows 10/11 x64,免安装、无需 Python)。 > - **要改代码/重新打包**:见 §8、§9。 > > 更新:2026-09-11 --- ## 1. 功能总览 | 功能 | 说明 | |---|---| | EDID 查看 | 枚举各显示输出口,从注册表读取 EDID 原始数据,按 EDID 1.4/CEA-861 解算:厂商/型号/尺寸/Gamma/输入类型/支持模式(DTD/已建立/标准/CEA-VIC)/首选时序完整参数/校验和 | | EDID 逐字节解析 | "EDID 原始数据"框右上"逐字节解析"按钮:按偏移逐字段展开基础块与 CTA-861 扩展块,每字段附原始字节 hex;命令行等价 `--edid-fields` | | 分辨率切换 | "分辨率"下拉列出显卡按该屏 EDID 提供的全部模式;**应用**=临时切换(不写注册表,重启/恢复即还原),**恢复**=回到本次会话切改前的模式 | | 测试图案投屏 | 全屏投到所选显示器,测试卡区域可选 `640x360 / 800x600 / full 铺满`;内置 纯红/纯绿/纯蓝/黑白棋盘格/网格线 + R/G/B 三行 55/AA/FF 纯色值按钮 + 3 个自定义图片栏位 | | 界面 | CustomTkinter 深色双栏仪表盘(左列 HDMI 源端 / 右列 光机控制),顶栏可切换 Dark/Light/System | | 光机控制 | RS485 → 板载 GD32E230 网关 → DLPC3421:开关光机(可定时)、设光强、查电流/温度/版本、TEC 控制、软件重启;光强/定时提供快捷滑条;收发日志带协议译码(见 §5) | | 智能显示拓扑 | 仅当检测到转接板(EDID 厂商 "XLS")接入但未进入桌面(Windows 卡在"仅电脑屏幕")时才强制扩展把它拉回;你主动选的"仅第二屏幕"等拓扑不会被改动 | | 命令行模式 | 全部功能可脚本化调用,供自动化测试(见 §6、§7) | | 波形分析脚本 | 逻辑分析仪 CSV 波形按占空比签名分段,输出行结构/占空比/消隐明细(见 §7.3) | ## 2. 下载与安装 1. 打开 [Releases 页面](https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools/releases),取最新的 `DLPilot-vX.Y.Z-win64.zip`; 2. 解压到**任意可写目录**(自定义图片与栏位配置会写到 exe 旁边); 3. 双击 `DLPilot.exe`。首次启动比脚本慢一两秒(onefile 解压),属正常现象。 包内包含: ``` DLPilot/ ├── DLPilot.exe 主程序(单文件自包含, 光机控制的 pyserial 已内置) ├── pattern_slots.json 预置自定义栏位 + 串口记忆 ├── bw_*.png ×5 640x360 黑白测试图 ├── solid_*.png ×10 800x600 纯色测试图 └── README.md 本说明 ``` ## 3. GUI 使用 主窗口为双栏仪表盘(布局设计稿:`UI参考布局.svg`),默认深色外观,顶栏可切换 Dark/Light/System: ``` 左列(HDMI 源端) 右列(光机控制 RS485) ┌ 显示器选择区域 [刷新] ┐ ┌ 串口选择 + 波特率/8-N-1 参数/连接 ┐ ├ 支持的模式: 分辨率[应用][恢复] + 明细 ┐ ├ 串口数据 — 收发日志(译码+hex) ┤ ├ EDID 信息(表格) ┘ ├ 光机命令 — 快捷按钮+TEC │ ├ 测试图案 / 纯色 / 自定义 / 测试卡区域 │ 预设下拉 / 自定义 / 温度读取 │ ├ EDID 原始数据 [逐字节解析] ┘ └ 快捷滑条 — 光强/定时/TEC温度 ┘ ``` 1. 左上显示器下拉选择目标屏(多屏时注意别选成主屏),"刷新"重新枚举; 2. **切分辨率**:"支持的模式"卡片里选模式 → "应用";测完点"恢复"; 3. **投测试图**:"测试图案"卡片先选**测试卡区域**(640x360 / 800x600 / full)→ 点图案按钮全屏投放,按 **ESC** 或点击退出;R/G/B 纯色按钮(55/AA/FF,按通道着色) 用于 RGB 位交换类测试;自定义图片点齿轮按钮配置(图片自动复制到 exe 旁); 4. **光机控制**:右列选串口与参数(波特率/数据位/校验/停止位,默认 115200 8-N-1)→ 连接 → 快捷按钮/预设下拉/自定义输入(回车即发);"查DMD温度""查LAMP温度"读温度 (应答实时填入按钮旁的显示框);快捷滑条:光强拖动后"下发 M731S", 定时毫秒后"开光机(定时)"(0=不限时 M730S0),TEC 凝露点滑条/输入框 (200-350 即 20.0-35.0°C)后"下发 M8S";数值框输入后回车自动限幅同步; 5. 测试卡区域、自定义栏位与串口记忆(含参数)自动保存在 exe 旁的 `pattern_slots.json`。 ## 4. 典型测试场景 ``` 1. HDMI 接转接板 → 启动 DLPilot → 刷新 → 选中板卡显示器 2. 板卡 shadow EDID 首选 640x360@60 → 测试卡区域选 640x360(与光机面板原生 1:1) 3. "光机控制"连接串口 → M999 查版本确认链路通 → M730S0 开光机 4. 点 R/G/B 行纯色按钮投图 → 目视/逻辑分析仪核对 RGB888 输出 - 纯红/绿/蓝:验证通道映射(R=D[23:16], G=D[15:8], B=D[7:0]) - 55/AA 对:验证位交换(0x606E)——图像应为 50% 灰阶占空比 5. M731S100 设光强 → M732 查电流读回复核 → M730S1 关光机 ``` 寄存器语义(0x606E 位交换 / 0x606D 整组顺序)与光机协议的判读基线见上游主仓库 [LT8619C_DLPC3421_HDMI](https://gitea.hulk.wang/hulk/LT8619C_DLPC3421_HDMI) 的 `doc/architecture/`。 ## 5. 光机控制(RS485 → GD32 网关 → DLPC3421) 物理链路:PC 经 **USB-RS485 转换器**接板卡 A/B 端子,板上 GD32E230 做 RS485→I2C 网关 控制 DLPC3421(I2C 地址 0x1B)。串口参数 **115200, 8N1**,协议细节以上游固件仓 `protocols.md` 为准:命令帧 `D5 01 LEN CRC`、响应帧 `B5 TYPE LEN CRC`, CRC 为第 2 字节起累加和取低 8 位。 GUI"光机控制"区:选串口 → 连接 → 点快捷按钮或命令下拉/自定义输入发送;串口下拉显示 "COMx + 设备描述",CH344 等多路适配器每一路描述不同(如 serial-A/B/C/D),据此选口; 多口描述相同时自动附物理位置消歧。日志区实时显示 `→ 命令` / `← 译码结果 (原始 hex)`, 错误自动附释义(如 `err:3(I2C NACK)`)。 | 命令 | 功能 | 响应示例 | |---|---|---| | `M730S0` / `M730S1` | 开 / 关光机 | `ok` | | `M730S0T2000` | 开光机并定时 2000ms 自动关(≤32700) | `ok`(期间 M737 延迟应答) | | `M731S100` | 设光强 54-800(RGB 同值,写后读回复核) | `ok` / `err:R..G..B..` | | `M732` | 查三路电流设置值(0-65535) | `okR110G110B110` | | `M201` / `M202` | 查 DMD / LAMP 温度(0.1°C) | `okTL:246` = 24.6°C | | `M999` | 查固件版本 | `okv20.0.0.1` | | `M737` | 查投光是否结束(投光中延迟应答) | `ok` | | `M7S0` / `M7S1` | TEC 自动控温开 / 关(注意 S0=开) | `ok` | | `M8S330` | TEC 凝露点 33.0°C(200-350,0.1°C) | `ok` / `err:OL` | | `M1` | 协议握手 | `ok` | | `M888` | 软件重启 | `ok` 后 100ms 复位 | 注意:**DLPC3421 启动完成前 M730/M731/M732 被就绪门禁拒绝**(回 0xFF),上电后稍等几秒再发。 命令行等价(源码方式): ``` python hdmi_gui.py --port COM9 --dlpc-cmd M730S0 --dlpc-cmd M999 逐条发送并打印译码响应 ``` ## 6. 命令行模式(hdmi_gui.py) exe 版无控制台,`--dump/--edid-fields` 的输出不可见(`--dlpc-cmd` 仍可执行,靠退出码判断), 调试请用源码方式: ``` python hdmi_gui.py --dump 控制台输出 EDID 解算 python hdmi_gui.py --edid-fields 控制台输出 EDID 逐字节字段解析表 python hdmi_gui.py --test-pattern Blue --area 800x600 --seconds 5 出图 5 秒自动退出 python hdmi_gui.py --test-pattern Custom1 投自定义栏位 1 python hdmi_gui.py --port COM9 --dlpc-cmd M730S0 RS485 发光机命令(可多次) python hdmi_gui.py --seconds 5 GUI 冒烟测试, 5 秒自动关 --test-pattern {Red,Green,Blue,Checker,Grid,Custom1..3} --area {640x360,800x600,full} --monitor N --seconds S --port COMx --baud 115200 --dlpc-cmd CMD(可重复; 任一命令失败退出码 1) ``` ## 7. 辅助脚本(src/ 下) ### 7.1 hdmi_source.bat / .ps1 — 源端命令行工具 与 GUI 互补,适合脚本串联: ``` tools\hdmi_source.bat -List 枚举显示器与支持分辨率(验证 EDID) tools\hdmi_source.bat -Monitor 1 -Mode 800x600 切模式 tools\hdmi_source.bat -Mode 800x600 -Pattern -Restore 切模式→出图案→退出后自动恢复 ``` ### 7.2 gen_bw_patterns.py / gen_solid_colors.py — 测试图生成 需 Pillow(`py -m pip install pillow`)。重新生成 `assets/` 下全部图案: - `gen_bw_patterns.py` → 640x360 黑白图 ×5: `bw_star.png` 西门子星(极限分辨率)、`bw_sweep.png` 频率扫描条纹(24px→3px)、 `bw_checker_sweep.png` 渐变棋盘(2→32px)、`bw_zoneplate.png` 波带片(各向混叠)、 `bw_testcard.png` 综合测试卡(灰阶/刻度/细棋盘/线宽组); - `gen_solid_colors.py` → 800x600 纯色图 ×10(R/G/B 各 55/AA/FF + 三原色), 与 GUI 内置纯色按钮同源,供自定义栏位或其他工具加载。 ### 7.3 la_wave_analyzer.py / la_wave_analyzer3.py — 逻辑分析仪波形判读 分析 Kingst VIS 导出的边沿流 CSV(列:`Time[s], 通道A, 通道B[, 通道C]`, 10ns 分辨率),按 50ms 窗口占空比签名自动分段,输出每段的签名(FF/55/AA/00)、 时长、行周期/有效区宽度/消隐(按 40MHz 像素时钟折算): ``` python la_wave_analyzer.py # 2 通道(默认判读 B 口 D0/D1) python la_wave_analyzer3.py # 3 通道(RGB 三组同拍, ch8/9/10) ``` ### 7.4 selftest_rs485.py — 光机协议自检(无硬件) 对照上游 `protocols.md` 实测帧向量回归帧构造/解析/译码:`python selftest_rs485.py`, 全部通过退出码 0。改 `dlpc_rs485.py` 后必须跑一遍。 ## 8. 目录结构与从源码运行 ``` DLPilot/ ├── src/ # 源代码(人工维护区) │ ├── hdmi_gui.py # 入口与命令行模式(argparse 分发) │ ├── app_gui.py # CustomTkinter 主界面(双栏仪表盘) │ ├── display_win.py # Win32 显示器枚举/分辨率/智能拓扑(纯标准库) │ ├── edid_parse.py # EDID 1.4/CEA-861 解析(纯标准库) │ ├── patterns.py # 测试图案全屏投屏窗口 │ ├── config.py # 运行目录与 pattern_slots.json 配置 │ ├── dlpc_rs485.py # 光机 RS485 协议与串口链路 │ ├── selftest_rs485.py # 光机协议自检(无硬件回归) │ ├── build_exe.py # PyInstaller 打包 → release/ │ ├── package_release.py # 组装发布 zip(exe+图案+说明) │ ├── publish_gitea.py # 上传到 Gitea Release │ ├── hdmi_source.ps1/.bat # 源端分辨率/图案命令行工具 │ ├── gen_bw_patterns.py # 生成 assets/bw_*.png │ ├── gen_solid_colors.py # 生成 assets/solid_*.png │ ├── la_wave_analyzer*.py # 逻辑分析仪 CSV 波形判读 │ └── logos/ # 图标源(svg/png/ico + make_ico.py) ├── assets/ # 生成的测试图案(gen_*.py 产物, 随发布包分发) │ ├── bw_*.png ×5 # 640x360 黑白系列 │ └── solid_*.png ×10 # 800x600 纯色系列 ├── release/ # 构建与发布产物(机器生成区, 不手改) │ ├── DLPilot.exe # 打包单文件版(改动跟随源码提交入库) │ ├── pattern_slots.json # exe 运行配置(栏位预置 + 串口记忆) │ ├── *.png / README.md # 附属文件平铺副本(由 package_release.py 从 assets/ 同步) │ └── *.zip # 发布包(不入库, 上传 Gitea Release) ├── README.md # 本说明 ├── AGENTS.md # 面向 AI/Agent 的工程档案(结构/约定/构建规程) └── UI参考布局.svg/.png # 界面布局设计稿(app_gui.py 按此实现) ``` 从源码运行:`python src/hdmi_gui.py`,需 Python ≥3.10;EDID/命令行纯标准库; GUI 需 customtkinter(`py -m pip install customtkinter`);光机控制需 pyserial; 自定义图片要 JPG/BMP/WebP 需可选 Pillow。 ## 9. 构建与发布 ```powershell cd src python selftest_rs485.py # 光机协议回归(改 dlpc_rs485.py 后必跑) python build_exe.py # 打包 → ../release/DLPilot.exe(自动装 PyInstaller; # 内置 pyserial/customtkinter, CTk 主题数据自动收集) python build_exe.py --debug # 额外出一个带控制台的调试变体(--dump 可见输出) python package_release.py 0.2.0 # 组装 release/DLPilot-v0.2.0-win64.zip python publish_gitea.py DLPilot-v0.2.0-win64.zip --insecure # 上传 Gitea Release(需 GITEA_TOKEN) ``` ## 10. 注意事项 / FAQ - **光机没反应排查**:① 串口/波特率(115200 8N1)与 A/B 接线;② 先发 `M999` 验证链路; ③ 开光机回 0xFF 是 DLPC 就绪门禁——上电后等几秒;④ USB-RS485 转换器半双工, 发送时板上回包不会回环(正常); - **exe 放只读目录会怎样**:自定义图片与 `pattern_slots.json` 写在 exe 旁边,只读目录会导致配置存不下; - **重新打包后图标没变**:Windows 图标缓存,`ie4uinit -show` 或改个名即可; - **多屏序号**:切分辨率前先确认显示器序号(GUI 下拉框与 `hdmi_source.bat -List` 输出一致); - **残留进程**:修改源码重新打包前先结束残留的 DLPilot 进程(`build_exe.py` 会自动 taskkill); - **改 logo**:改 `src/logos/logo_ph_orange.svg` → `python src/logos/make_ico.py` → 重新打包; - **配置互不影响**:exe 与源码脚本各自按所在目录保存 `pattern_slots.json`,两份安装互不干扰。