本博客阐述如何通过两个USB转TTL模块,实现PC与树莓派的串口通信。许多博客都是从电脑上用一个USB转TTL模块连到树莓派GPIO口上,这样造成引线过杂,杜邦线连接长度不够等问题。针对这样些痛点,本博客多用一个USB转TTL模块,直接通过树莓派上USB插口进行数据接收。PC是用XCOM串口调试助手进行数据发送,但接收到的数据格式有些异常。
下图为连接示意图:
PC端通过XCOM串口调试助手模拟其他模块进行数据传送。USB转TTL模块连接电脑后,选择最新出现的COM端口,波特率设为9600(可自己调 但代码里相应地方需要更改)。模拟水电站串口发送第18条数据:转速123 型号321 XXXXX
将USB插到树莓派上的任意USB接口上,然后在终端输入命令查看。USB0是否正确安装
~$ ls -l /dev/tty*
在home/pi中直接创建config.py文件,打开并编写代码。或在PC中编写完后直接copy到树莓派文件内。通过终端python config.py进行编译
如下图所示,直接打印串口调试助手给的数据后会出现ת��123 �ͺ�321 XXXXX中文的乱码,通过查找各个博客的方法与代码,终于用4个步骤将该乱码转化成正常的字符:
1:将读到的内容用十六进制编码
2:通过HextoHanzi()函数将字符串按\xXX形式分类
3:将\xXX形式内容转为r’\xXX形式 此时"“无法转义
4:通过eval()将r”\xXX"转为u\xXX形式 此时可以转义
注意:若XCOM发送新行勾选时,代码中需对\r\n去除处理
# -*- coding: utf-8 -*
import binascii
import serial
import time
def HextoHanzi(hex_string):
unicode_Hanzi = '' #定义一个空字符串
for i in range(len(hex_string)/2): # 每2个一组
Hex_char = hex_string[i*2: i*2+2] # 每次取出两个字符
unicode_char = '\\x' + Hex_char # 在字符前加\\x 此时无法转义
unicode_Hanzi = unicode_Hanzi + unicode_char # 将所有字符聚合
return unicode_Hanzi.encode('utf-8') # 以字节形式返回
def main():
while True:
# 获得接收缓冲区字符
count = ser.inWaiting()
if count != 0:
# 读取内容并显示 例如发数据:转速123 型号321 XXXXX
recv = ser.read(count) # 读到的数据中中文为乱码
recv = recv.replace('\n','') # 移除数据中回车符号
recv = recv.replace('\r','') # 移除数据中长空格符号
# print(recv) # ת��123 �ͺ�321 XXXXX
# print(type(recv)) # <type 'str'>
recv1 = binascii.hexlify(recv).decode('utf-8') # 将读到的内容用十六进制编码
# print(recv1) # "d7aacbd931323320d0cdbac5333231205858585858"
# print(type(recv1)) # <type 'unicode'>
recv2 = HextoHanzi(recv1) # 通过HextoHanzi()函数将字符串按\\xXX形式分类
# print(recv2) # \\xd7\\xaa\\xcb\\xd9\\x31\\x32\\x33\\x20\\xd0\\xcd\\xba\\xc5\\x33\\x32\\x31\\x20\\x58\\x58\\x58\\x58\\x58
# print(type(recv2)) # <type 'str'>
recv3 = recv2.encode("raw_unicode_escape").decode('utf-8') # 将\\xXX形式内容转为r'\xXX形式 此时"\"无法转义 (用unicode编码)
# print(recv3) # \xd7\xaa\xcb\xd9\x31\x32\x33\x20\xd0\xcd\xba\xc5\x33\x32\x31\x20\x58\x58\x58\x58\x58
# print(type(recv3)) # <type 'unicode'>
recv4 = eval("u"+"\'" + recv3 + "\'") # 将r"\xXX"转为u\xXX形式 此时可以转义
# print(recv4) # תËÙ123 ÐͺÅ321 XXXXX
# print(type(recv4)) # <type 'unicode'>
print(recv4.encode("raw_unicode_escape").decode('GB2312')) # 将u'\xXX'形式内容转为中文 (用unicode编码)
# 清空接收缓冲区
ser.flushInput()
# 必要的软件延时
time.sleep(0.1)
if __name__ == '__main__':
try:
# 打开串口
ser = serial.Serial('/dev/ttyUSB0', 9600) # 树莓派以USB转串口模块 通过另一个串口转USB模块 连接PC
if ser.isOpen == False:
ser.open() # 打开串口
main()
except KeyboardInterrupt:
if ser != None:
ser.close()
本代码仅调试了PC对树莓派的数据发送,并未实现树莓派对PC的数据返回。
但PC对树莓派数据传输后的格式问题提出了比较完整的解决方案。
至此,通过树莓派读取串口信息的程序就完成了。
谢谢阅读!