MDC 是二进制协议,不是文本
MDC(Multiple Display Control)是三星商用标牌显示器的控制协议。和多数投影机协议不同,它是二进制的。 没有 ASCII 单词可敲,每条消息都是一小串原始字节,末尾跟一个你必须自己算的校验和。
听起来比实际难。 一个包就五个字段,校验和就是求和,理解了结构以后你可以自己拼出任意命令,而不用满世界找现成的表。
注意: MDC 用于三星的商用显示器(QM、QB、UD、ME 等系列)。三星消费级电视用的是完全不同的协议,叫 Ex-Link,走 3.5mm 接口——如果你手上是电视,请看 三星 Ex-Link 指令。
包结构
┌──────┬─────────┬──────┬─────────────┬──────────┬──────────┐
│ 包头 │ 命令 │ ID │ 数据长度 │ 数据… │ 校验和 │
│ 0xAA │ 1字节 │1字节 │ 1字节 │ N字节 │ 1字节 │
└──────┴─────────┴──────┴─────────────┴──────────┴──────────┘| 字段 | 说明 |
|---|---|
| 包头 | 固定 0xAA。不参与校验和计算。 |
| 命令 | 做什么——0x11 电源,0x14 输入源,0x12 音量,0x00 状态读取 |
| ID | 哪一台。0x00–0xFD 指定单台,0xFE = 广播 |
| 数据长度 | 后面跟几个数据字节(通常 0x01,查询时为 0x00) |
| 数据 | 取值——比如开机是 0x01 |
| 校验和 | 除包头外所有字节之和,取模 256 |
校验和规则
把除包头外的每个字节相加,只保留低位字节。
实算示例,广播开机:
命令 0x11
ID 0xFE
数据长度 0x01
数据 0x01
─────
和 = 0x111
& 0xFF = 0x11 ← 校验和完整包:AA 11 FE 01 01 11
三星自己的文档把这条规则表述为"超过两位时,丢弃第一位数字"——和取低字节是同一件事。0x111 变成 0x11。
整个协议用六行代码就能写完:
def mdc_packet(cmd, dev_id, data=b''):
body = bytes([cmd, dev_id, len(data)]) + data
return b'\xAA' + body + bytes([sum(body) & 0xFF])
mdc_packet(0x11, 0xFE, b'\x01') # AA 11 FE 01 01 11 开机
mdc_packet(0x11, 0xFE, b'\x00') # AA 11 FE 01 00 10 关机现成的指令包
下面这些全部用上面的规则算出来,你可以随手验算任意一条:
| 动作 | ID | 数据包 |
|---|---|---|
| 开机 | 广播 | AA 11 FE 01 01 11 |
| 关机 | 广播 | AA 11 FE 01 00 10 |
| 开机 | 0xFF | AA 11 FF 01 01 12 |
| 关机 | 0xFF | AA 11 FF 01 00 11 |
| 开机 | 0x01 | AA 11 01 01 01 14 |
| 状态读取 | 广播 | AA 00 FE 00 FE |
注意最后一条:查询不带数据字节,所以数据长度是 0x00,校验和是 0x00 + 0xFE + 0x00 = 0xFE。
要发原始字节。 一个高频错误是把 ASCII 字符串 "AA11FE010111" 发出去——那是十二个文本字符,不是六个字节。在调试工具里要把发送模式切成 HEX。另外不要追加回车:MDC 帧靠长度定界,末尾多一个 0x0D 会把下一个包搞坏。
接线与串口参数
| 参数 | 值 |
|---|---|
| 波特率 | 9600 |
| 数据位 | 8 |
| 校验位 | 无 |
| 停止位 | 1 |
只用三根信号线:
| 信号 | 针脚 |
|---|---|
| RxD | 2 |
| TxD | 3 |
| GND | 5 |
三星规定线长上限是 4 米。 这比大家默认的 RS-232 可以拉 15 米短得多,在标牌墙场景里是个真约束——控制主机往往在房间另一头的机柜里。需要距离就用 RS-232 转 IP 的网关,别硬拉长串口线:一根勉强够长的线产生的是时好时坏的故障,看起来像固件 bug。
广播 ID 0xFE:调试陷阱
把 ID 字节设成 0xFE,会寻址链路上的每一台显示器,无视它们各自配置的 ID。做"闭馆时全部关屏"确实好用。
但广播包不会有任何应答。 每台显示器都执行命令,而没有一台会回复。
这就制造了一个很难受的调试体验:你发出 AA 11 FE 01 01 11,看不到任何响应,于是断定链路是死的——而背后那四块屏正在悄悄亮起来。
调试阶段请用真实 ID 点名单台设备,这样你能收到 ACK。 确认链路通了之后再切到广播。把这个顺序搞反,会白白花掉一小时去查一根根本没问题的线。
那个会让一切失效的菜单设置
这是"MDC 完全不工作"的头号原因,而且跟你的代码毫无关系。
在显示器上:Home → ID Settings → PC Connection Cable → 选择 "RS232C cable"。
在你做这一步之前,显示器会完全无视串口。 很多三星商用面板默认期待通过另一条路径控制,于是 RS-232 口电气上是活的、逻辑上是断开的。再正确的数据包也换不来一个响应。
三星显示器没反应而你的校验和是对的,先去查这个设置,再查别的。
为什么关机能用、开机不行
这是三星最经典的症状,值得直说:关机容易,开机才是难的那个。
原因在所有显示品牌上都一样——深度待机时面板会给控制接收器断电,于是根本没有东西在监听唤醒命令。必须把显示器配置成待机时仍保持 RS-232/网络接收器工作。
去显示器上找待机或电源模式的设置,把它从最深的节能档调开。症状非常好认:AA 11 FE 01 00 10 关屏干脆利落,之后 AA 11 FE 01 01 11 毫无反应。
为什么你的 MDC 命令没有回应
1. PC Connection Cable 没设成 RS232C。 见上。
2. 你用了广播 ID 0xFE 却在等 ACK。 广播永远不回复。
3. 你发的是 ASCII 文本而不是原始字节。 "AA11..." 是十二个字符。
4. 校验和算错了。 重算——记住包头不参与。
5. 你追加了回车。 MDC 帧没有结束符。
6. 线超过 4 米,或者该用交叉线的地方用了直通线。
7. 显示器处于深度待机。 不改待机模式,开机命令永远不会成功。
8. 协议族选错了。 如果那是台消费级电视,你要的是 Ex-Link,不是 MDC。
用 SoftControl 控制
MDC 的校验和正是那种"手算很烦、软件算很轻松"的东西。 SoftControl 用十六进制输入发送裸 TCP、UDP 或串口字节,你把包粘进去它就按字节发出去;指令测试页同时显示发出的十六进制和原始回复——这正是你用来分辨"因为广播所以没 ACK"和"因为没人在听所以没 ACK"的手段。