QY LED 二进制协议)
这个协议实现了什么功能QY LED 控制卡是一个 128×64 点阵屏的控制板通过 TCP 接收二进制指令帧来显示内容。通过这个协议我们实现了坐标定点显示在任意 X/Y 坐标显示文本发送即显示16 种动画滚动左移、右移、上下移、百叶窗、闪烁等多页面切换9 个独立显示页面互不干扰内码文字持久化通过 UID 绑定显示区域文本可保存在卡内存通信方式控制卡工作在网络服务器端模式单点监听 8888 端口。PC 端主动连接 → 发送二进制帧 → 断开PC (Flask) ──TCP Connect──→ 192.168.1.99:8888 (QY 卡) ──Send Frame──→ ──Close───────→配置工具界面设置通讯接口网络服务器端不是网络客户端IP 地址192.168.1.99端口8888⚠️ 如果设成网络客户端多点卡会主动连 PC现在这套代码就跑不通了。两种显示模式模式一坐标协议 SendAddr_Pro功能在指定 X/Y 坐标直接显示文本。发送即显示不持久化。适合临时显示、调试测试。帧结构逐字节偏移 字节 含义 0-3 FE 5C 4B 89 固定前导标记 4-7 XX XX XX XX 总长度 文本字节数 28小端序 8 60 消息类型0x60 坐标协议 9-12 00 00 00 00 发送ID 13-16 XX XX XX XX 指令长度 文本字节数 9 17 80 分隔符 18-19 XX XX X 坐标小端序 20-21 XX XX Y 坐标小端序 22 00 保留 23 XX 颜色 1红 2绿 3黄 4蓝 5紫 6青 7白 24 XX 字体字号高4位字体低4位字号 25 XX 文本字节长度 26 ... GB2312 编码文本 末尾 FF FF 后导标记Python 代码实现frame bytearray() frame bytes([0xFE, 0x5C, 0x4B, 0x89]) # 前导 frame (str_len 28).to_bytes(4, little) # 总长度 frame.append(0x60) # 消息类型 frame bytes([0x00, 0x00, 0x00, 0x00]) # ID frame (str_len 9).to_bytes(4, little) # 指令长度 frame.append(0x80) # 分隔符 frame x.to_bytes(2, little) # X坐标 frame y.to_bytes(2, little) # Y坐标 frame.append(0x00) # 保留 frame.append(colour) # 颜色 frame.append((font_code 4) | size_code) # 字体字号 frame.append(str_len) # 文本长度 frame text.encode(gb2312) # GB2312文本 frame bytes([0xFF, 0xFF]) # 后导 TCP 发送 sock.connect((192.168.1.99, 8888)) sock.send(frame) sock.close()模式二内码文字协议 SendGB2312_Pro功能通过 UID 绑定到卡上预设的显示区域支持 16 种动画效果。文本可持久化到卡内存RAM 或 Flash。帧结构逐字节偏移 字节 含义 0-3 FE 5C 4B 89 前导标记 4-7 XX XX XX XX 总长度 文本字节数 84 8 31 消息类型0x31 素材内容 9-12 00 00 00 00 发送ID 13-16 XX XX XX XX 指令长度 文本字节数 65 17-25 000000041 素材 UID9 位 ASCII 26 2C 分隔符 , 27 XX 显示方式1-16 28 08 速度0-8越小越快 29 00 停留时间0滚动不停 30-41 0101019931231 播放日期范围12 位 ASCII 42-45 13 00 00 00 素材属性长度 0x13 46-52 55 AA 00 00 37 32 32 素材属性字节串 53-57 31 32 31 30 30 起始标记 色彩 编码 保留 58-59 XX XX 像素宽度 128/8 16 60-61 XX XX 像素高度 12 62 XX 颜色 63 XX 字体字号 64 00 保留 65-68 XX XX XX XX 素材内容长度 文本字节数 10 69 ... GB2312 文本 末尾15 FF 00 01 00 ... 控制码 结束标记 FF FF16 种显示模式mode 参数mode效果实际表现1左移从右向左滚动✅ 稳定MCU 默认使用2右移从左向右滚动⚠️ 卡固件支持不完善有停顿3上移正常4下移正常5从右向左展开正常6从左向右展开正常9立即显示无动画10中间向两边展开正常11两边向中间展开正常14闪烁正常15右百叶窗正常Python 代码实现def _build_gb2312_frame(txt_bytes, dis_mode, clr): f bytearray() f bytes([0xFE, 0x5C, 0x4B, 0x89]) f (len(txt_bytes) 84).to_bytes(4, little) f.append(0x31) f bytes([0x00]*4) f (len(txt_bytes) 65).to_bytes(4, little) f f000000{uid:03d}.encode(ascii) # 素材UID f.append(0x2C) # , f.append(dis_mode) # 显示方式 f.append(0x08) # 速度 f.append(0x00) # 停留 0不停 f bytes([0x30,0x31,0x30,0x31,0x30,0x39, 0x39,0x33,0x31,0x32,0x33,0x31]) f bytes([0x13,0,0,0]) f bytes([0x55,0xAA,0,0,0x37,0x32,0x32]) f bytes([0x31,0x32,0x31,0x30,0x30]) f (16).to_bytes(2, little) # 128/8 f (12).to_bytes(2, little) # 高度 f.append(clr) f.append((0x01 4) | 0x02) # 宋体24号 f.append(0x00) f (len(txt_bytes) 10).to_bytes(4, little) f txt_bytes f bytes([0xFF,0,0x01,0,0x01,0,0x01,0,0,0,0x2D,0x31,0x2C]) f bytes([0xFF, 0xFF]) return f实战踩坑坑 1右移模式卡住左移正常右移停顿。逐字节对比帧发现仅 mode 字节不同0x01 vs 0x02最终确认是卡固件对 mode 2 支持不完善。MCU 源码也从没用过 mode 2。解决方案左移为主力动效。坑 2null文本导致崩溃API 收到{text: null}时data.get(text, )返回NonePython 的 .get() 只在 key 不存在时用默认值然后None.encode()直接崩。修复data.get(text) or 。坑 3帧字节数与 MCU 源码对齐开发时先用 MCU 的 C 源码逐字节对比 Python 实现确保帧完全一致。有一个字节0xFF写成0x00导致滚动出不来的经历。跨平台通用性这个二进制协议跟平台无关。掌握了帧结构任何语言都能实现Python→bytearrayto_bytes(little)Java→ByteBufferorder(ByteOrder.LITTLE_ENDIAN)JS/Node→BufferwriteUInt32LEC#→BitConverter.GetBytes注意小端序小结QY LED 二进制协议的核心就是按固定格式填字节、GB2312 编码文本、小端序排列数字、TCP 发送。两个协议共用一套前导/后导标记区别在于消息类型0x60 vs 0x31和帧内容。理解了这个就能从任意平台控制 LED 大屏。