串口通信脚本转字节数组时转义字符异常问题咨询
解决串口发送数据库返回含控制字符数据的问题
问题核心是你拿到的字符串里的转义序列(比如\x1b)被当成了字面量字符(实际存储的是\、x、1、b四个字符),而非对应的控制字节(ESC字符,ASCII码27)。直接调用.encode()会把这些字面量逐个转成字节,导致设备收到无效的转后数据。
两种解决思路:
1. 直接处理二进制数据(推荐)
如果数据库返回的是原始二进制数据,全程用bytes类型处理,跳过字符串转换环节:
# 假设从数据库获取的是bytes类型响应 db_response_bytes = b"00000011D88A\x1b[2JSome text answer\x1b[1q\x1b[1q\x0d" # 直接发送到串口 serial_port.write(db_response_bytes)
这种方式完全规避字符串转义问题,控制字符会被原样发送。
2. 解析字符串中的转义序列
如果已经拿到带字面量转义序列的字符串(比如示例中的\\x1b形式),需先把转义序列转换成对应控制字符,再编码成字节:
方法一:用ast.literal_eval解析
import ast # 你实际拿到的带字面量转义符的字符串 raw_str = "00000011D88A\\x1b[2JSome text answer\\x1b[1q\\x1b[1q\\x0d" # 解析转义序列为实际字符 parsed_str = ast.literal_eval(f'"{raw_str}"') # 编码为字节,用latin-1确保每个字符对应一个字节(兼容ASCII控制字符) serial_bytes = parsed_str.encode('latin-1') # 发送到串口 serial_port.write(serial_bytes)
方法二:用codecs.decode的unicode_escape编码
import codecs raw_str = "00000011D88A\\x1b[2JSome text answer\\x1b[1q\\x1b[1q\\x0d" # 解析转义序列 parsed_str = codecs.decode(raw_str, 'unicode_escape') # 编码为字节 serial_bytes = parsed_str.encode('latin-1') serial_port.write(serial_bytes)
关键说明
unicode_escape和ast.literal_eval都会将字符串中的\xXX转义序列转换成对应ASCII字符,比如\x1b会转为ESC控制字节。- 使用
latin-1编码是因为它的每个字符对应一个字节,不会像utf-8那样对控制字符做额外编码,能保证控制字符的原始值被保留。
内容的提问来源于stack exchange,提问作者Urbis
相关产品推荐
相关产品推荐

