通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示

通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示

  • 说明
  • PC端 串口调试助手
  • 树莓派接收
    • 树莓派文件创建
    • 树莓派收数据 python2.7 代码
  • 打印结果调试
  • 待补充部分

说明

本博客阐述如何通过两个USB转TTL模块,实现PC与树莓派的串口通信。许多博客都是从电脑上用一个USB转TTL模块连到树莓派GPIO口上,这样造成引线过杂,杜邦线连接长度不够等问题。针对这样些痛点,本博客多用一个USB转TTL模块,直接通过树莓派上USB插口进行数据接收。PC是用XCOM串口调试助手进行数据发送,但接收到的数据格式有些异常。
下图为连接示意图:

通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示_第1张图片

PC端 串口调试助手

PC端通过XCOM串口调试助手模拟其他模块进行数据传送。USB转TTL模块连接电脑后,选择最新出现的COM端口,波特率设为9600(可自己调 但代码里相应地方需要更改)。模拟水电站串口发送第18条数据:转速123 型号321 XXXXX
通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示_第2张图片

树莓派接收

将USB插到树莓派上的任意USB接口上,然后在终端输入命令查看。USB0是否正确安装

~$ ls -l /dev/tty*

在这里插入图片描述

树莓派文件创建

在home/pi中直接创建config.py文件,打开并编写代码。或在PC中编写完后直接copy到树莓派文件内。通过终端python config.py进行编译
通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示_第3张图片

树莓派收数据 python2.7 代码

如下图所示,直接打印串口调试助手给的数据后会出现ת��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()



打印结果调试

各个print打印出来的结果
通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示_第4张图片

最终结果
通过两个USB转TTL模块 实现PC发送数据到树莓派 并且传输的中文数据正常显示_第5张图片

待补充部分

本代码仅调试了PC对树莓派的数据发送,并未实现树莓派对PC的数据返回。
但PC对树莓派数据传输后的格式问题提出了比较完整的解决方案。
至此,通过树莓派读取串口信息的程序就完成了。

谢谢阅读!
在这里插入图片描述

你可能感兴趣的:(树莓派,unicode,python,串口通信)