JoshuaEngine7/grandwell-ksu

GitHub: JoshuaEngine7/grandwell-ksu

通过逆向工程完全解码 Grandwell LED 显示屏的 KSU 串口协议,用纯 Python 库替代已失效的原厂 16 位软件,让老旧显示屏在现代系统上恢复可用。

Stars: 0 | Forks: 0

# grandwell-ksu **针对 Grandwell LED 显示屏的开源控制方案 —— MIM!Plus (2003) 的现代替代品。** 成千上万台产自 2000 年代初的 Grandwell LED 信息屏至今仍是 完好的硬件:亮度高、可靠性强,专为 7x24 小时运行而打造。让它们 沦为废品的却是软件。最初的控制程序 **MIM!Plus** 是一款发布于 2003 年的 16 位 Windows 应用程序 —— 它根本无法在任何现代的 64 位 Windows 上运行,且 Grandwell 采用 RS-232 接口的显示屏时代早已停产。那些还能正常工作的 显示屏只能被拔下电源并报废,因为再也没有设备能与它们通信了。 本项目正是为了解决这一问题。这款显示屏的串口协议(内部标记为 `KSU`)已被**逐字节完全逆向工程**,并重新实现为 一个小巧的纯 Python 库,可在 Windows 11、Linux 或任何 带有 USB 串口适配器的设备上运行。 这绝不是一个玩具:这段代码目前正驱动着墨西哥一家繁忙的 公共健康诊所的患者排队叫号显示屏,在每一天的工作时间里稳定运行,所使用的正是一台有着约 20 年历史的 Grandwell Flash FL-TLR-2420 显示屏。 ## 功能特性 - **文本消息** — 最多支持 3 行同时显示,可自由定位 (X, Y) - **轮播页面** — 多个屏幕只需进行*一次*写入操作,即可在显示屏上循环 显示(显示屏会自动播放动画;您可以断开 PC 连接) - **颜色** — 在三色型号上支持 红色 / 绿色 / 黄色 / 熄灭 - **入场效果** — 即时出现、拉开帷幕、随机像素、闪烁 - **滚动跑马灯** — 任意长度的文本,通过真实字体进行渲染 - **大字体文本** — 全高度比例文本,自动适应面板大小 - **自动更新时钟** — 日期/时间块会让显示屏自行持续计时, 此外还有一个 `SetClock` 命令用于同步显示屏的内部时钟 (这一点连 MIM!Plus 本身都没能在我们的硬件上成功实现传输) - **页面持续时间 (`Delay`)** 以及单页特效设置 ## 所需硬件 | 部件 | 说明 | |---|---| | 带有 `RS232 IN` (4P4C) 插孔的 Grandwell 显示屏 | 已验证:Flash FL-TLR-2420。其他 MIM!Plus 时代的型号极有可能使用相同协议 —— 欢迎反馈! | | DB9 母口转 4P4C 线缆 | 在网上便宜即可买到(通常标记为“4nb”)。详见 [HARDWARE.md](HARDWARE.md) | | USB 转 DB9 串口适配器 | 已使用 Prolific PL2303 验证;FTDI 理论上也可行 | 完整的接线细节、注意事项与校准说明:**[HARDWARE.md](HARDWARE.md)** ## 快速开始 ``` pip install pyserial pillow # pillow only needed for marquee/big text git clone https://github.com/JoshuaEngine7/grandwell-ksu cd grandwell-ksu # 每个示例都是一次 dry run,直到你给它指定一个 port — # 它会打印出确切的 frame bytes 而不是发送: python examples/send_text.py "HELLO WORLD" python examples/send_text.py "HELLO WORLD" COM3 # now it sends python examples/send_text.py "HELLO" /dev/ttyUSB0 # Linux works too ``` 更多示例请见 [examples/](examples/) 目录:`three_lines.py`、 `rotating_pages.py`、`clock.py`、`set_clock.py`、`marquee.py`、 `big_text.py`。 作为库使用: ``` from grandwell import pages_frame, send_frame frame = pages_frame([ {"text": "WELCOME", "effect": "open_horizontal", "delay_ms": 3000}, {"lines": ["MON-FRI", "8:00-16:00"], "delay_ms": 4000}, {"text": "OUT OF SERVICE", "color": "red", "effect": "flash", "delay_ms": 5000}, ]) ok, msg = send_frame(frame, port="COM3") # one write; the sign rotates alone print(msg) ``` 离线测试套件(无需硬件,基于原始 MIM!Plus 抓取数据的大小和 校验和进行验证): ``` python tests/test_frames.py ``` ## 针对此硬件的黄金法则 这些经验来之不易 —— 详见 [REVERSE_ENGINEERING.md](REVERSE_ENGINEERING.md): 1. **显示屏的闪存写入次数有限。** 每次用户操作仅允许 写入一次。切勿循环写入:显示屏会自行轮播页面、播放滚动动画并 在接收到单帧数据后*自行*更新时钟。 2. **普通文本帧:正文 ≤255 字节**(长度字段占用 1 个 字节)。跑马灯和大字体格式使用 16 位长度,因此没有 此限制。 3. **跑马灯仅限 8 像素高度。** 在我们的显示屏上,24 像素滚动会导致其卡死在 "WAITING..." 状态,直到重新通电。 4. **显示屏是只写的。** 它从不在线路上进行应答;唯一的 ACK 就是观察 LED 的变化。 ## 文档说明 - **[PROTOCOL.md](PROTOCOL.md)** — 完整解码的通信格式: 帧结构、每一项已确认的命令、校验和、位图格式 - **[HARDWARE.md](HARDWARE.md)** — 线缆、适配器、串口设置, 以及其他面板尺寸的校准 - **[REVERSE_ENGINEERING.md](REVERSE_ENGINEERING.md)** — 在毫无文档的情况下 解码该协议的过程:差分抓取、针对 16 位 原版的模拟器,以及大量的字节差异对比 ## 状态与路线图 已解码并在硬件上验证:TEXT、ClearScr、ChgColor、Position、 Display Modes (22 种中的 5 种)、Delay、YScroll、Time/Date/Day、SetClock、 多页面、marquee ("Long")、位图图像 (0x1B) 以及两种校验和 变体。 尚未映射(欢迎提供抓取数据!):剩余的 display modes、非位图特效的 speed 字节、`Show` (.bmp 播放)、`Schedule`、 独立显示屏寻址 (multi-drop RS-485),以及 `Bar`/`Box` 绘图 命令。 ## 参与贡献 最有价值的贡献是**硬件反馈**:如果您有任何 Grandwell(或贴牌)显示屏,请尝试运行 `examples/send_text.py` 并提交一个 issue,附上您的设备型号及运行结果 —— 就算出错,最坏的情况也不过是显示屏忽略该 数据帧。MIM!Plus 的 `Capture` 文件(包含未映射命令的 .TXD)对我们来说如同珍宝。 ## 法律声明 这是一个独立的互操作性项目,通过黑盒 逆向工程开发,旨在让自有硬件保持可用状态。它**不包含来自 MIM!Plus 或 Grandwell 的任何 代码、字体、手册或资产**。 “Grandwell”和“MIM!Plus”是其各自所有者的商标,他们 与本项目的开发没有任何关联。 许可证:[MIT](LICENSE)
标签:LED显示屏, Python, 串口通信, 云资产清单, 无后门, 物联网, 硬件控制, 逆向工具, 逆向工程