
本文详解在 Python 3.x 中将含 ASCII 与十六进制转义字符(如 \xAE、\xC7\xB4)的 AT 命令字典安全、准确地编码为字节流并通过 pyserial 发送至微控制器的方法,涵盖三种主流编码策略及类型安全实践。
本文详解在 python 3.x 中将含 ascii 与十六进制转义字符(如 `\xae`、`\xc7\xb4`)的 at 命令字典安全、准确地编码为字节流并通过 `pyserial` 发送至微控制器的方法,涵盖三种主流编码策略及类型安全实践。
在使用 pyserial 与嵌入式设备(如 GSM 模块、ESP32 等)通信时,AT 命令常需嵌入非 ASCII 字符(例如厂商自定义扩展指令中的十六进制控制码 \xAE 或 \xC7\xB4)。但 Python 3 的 Serial.write() 方法仅接受 bytes 类型参数,直接传入普通字符串(str)会引发 TypeError: expected bytes, got str 错误。因此,关键在于确保字典中存储的命令值最终以正确的字节序列形式传递。
以下是三种经过验证、生产可用的实现方式,按推荐度排序:
✅ 方法一:运行时动态编码(最灵活,推荐)
适用于命令内容可能动态生成或需统一编码策略的场景。使用 .encode('utf-8') 将 Unicode 字符串安全转换为字节:
import serial
command = {
"cmd_a": 'AT\r',
"cmd_b": 'AT+HTTPINIT\xAE\r',
"cmd_c": 'AT+CGMM\xC7\xB4\r',
}
comport = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
cmd_to_send = command.get("cmd_c")
if isinstance(cmd_to_send, str):
comport.write(cmd_to_send.encode('utf-8')) # ✅ 正确:转为 bytes
else:
raise TypeError(f"Expected str, got {type(cmd_to_send).__name__}")
⚠️ 注意:
utf-8编码能正确处理\xXX转义(因其在 Python 字符串字面量中已被解释为对应 Unicode 码点),但务必确认目标 MCU 接收端期望的是 UTF-8 字节流而非 Latin-1。若 MCU 严格按单字节处理(如多数 AT 固件),且\xC7\xB4表示原始字节0xC7 0xB4,则该方法完全适用——因为 UTF-8 对U+00C7(Ç)和U+00B4(´)的编码恰好是0xC7和0xB4,与预期一致。
✅ 方法二:字典预定义为字节字面量(最高效,推荐用于静态命令)
直接在字典中使用 b'' 前缀声明字节字符串,避免运行时编码开销,语义清晰且零歧义:
command = {
"cmd_a": b'AT\r',
"cmd_b": b'AT+HTTPINIT\xAE\r', # \xAE → 单字节 0xAE
"cmd_c": b'AT+CGMM\xC7\xB4\r', # \xC7\xB4 → 连续两字节 0xC7 0xB4
}
cmd_to_send = command.get("cmd_c")
if isinstance(cmd_to_send, bytes):
comport.write(cmd_to_send) # ✅ 直接写入,无需转换
else:
raise TypeError("Dictionary values must be bytes")
? 提示:此方式杜绝了编码错误风险,尤其适合固件协议明确要求特定字节序列的场景(如 Modbus RTU、自定义二进制指令)。注意
\xAE在字节字面量中即表示十六进制值0xAE,而非 Unicode 字符。
✅ 方法三:显式调用 bytes() 构造器(兼容性好)
与方法一类似,但显式指定编码,适合需精细控制编码参数的场合:
cmd_to_send = command.get("cmd_c")
comport.write(bytes(cmd_to_send, 'latin-1')) # 若需 1:1 映射(\xC7 → 0xC7),可用 latin-1
? 对比说明:
'latin-1'编码可将0x00–0xFF的每个字节直接映射为对应 Unicode 码点,再反向编码时完全保真,是处理“伪字符串”十六进制数据的可靠选择。但对含真正 Unicode 字符(如中文)的命令不适用。
? 关键总结与最佳实践
-
永远检查类型:在
write()前使用isinstance(..., bytes)防御性校验,避免运行时异常; -
优先选用方法二:若命令集固定,
b''字面量最安全、最直观、性能最优; -
避免混用:不要在同一个字典中混合
str和bytes值,保持类型一致性; -
验证实际字节:调试时可用
print(repr(cmd_to_send))或print(list(cmd_to_send))查看真实字节序列; -
注意换行符:
\r在字节字面量中仍为0x0D,符合绝大多数 AT 模块要求;如需\r\n,请显式写为b'\r\n'。
遵循以上任一方法,即可确保含十六进制字节的 AT 命令被精准、无损地送达微控制器,为稳定可靠的串口通信打下坚实基础。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











