树莓派--uart通信python实现

前言:

树莓派上通过UART通信的Python实现通常涉及到使用串口设备来进行数据传输。UART(Universal Asynchronous Receiver/Transmitter)是一种串行通信接口,通常用于与其他设备(如传感器、显示器、其他微控制器等)进行通信。

step1:安转pyserial

树莓派默认是有安装的好像,不确定的话,可以再安装一次。

pip install pyserial

step2:确定串口号

import serial
import serial.tools.list_ports
# 获取所有串口设备实例。
# 如果没找到串口设备,则输出:“无串口设备。”
# 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。
ports_list = list(serial.tools.list_ports.comports())
if len(ports_list) <= 0:
    print("无串口设备。")
else:
    print("可用的串口设备如下:")
    for comport in ports_list:
        print(list(comport)[0], list(comport)[1])

运行结果如下 :/dev/ttyUSB0与/dev/ttyAMA10为我们所要使用的端口,相当于Windows中的COM1、COM2。

step3:配置端口

import serial
 ser = serial.Serial("/dev/ttyAMA10", 115200)    # 打开/dev/ttyAMA10,将波特率配置为115200,其余参数使用默认值
if ser.isOpen():                        # 判断串口是否成功打开
    print("打开串口成功。")
    print(ser.name)    # 输出串口号
else:
    print("打开串口失败。")
 

注:在使用 serial.Serial() 创建串口实例时,可以传入的参数很多,常用的参数如下:

        (1)port - 串口设备名或 None。
       (2) baudrate - 波特率,可以是50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000。
        (3)bytesize - 数据位,可取值为:FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS。
parity - 校验位,可取值为:PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE。
        (4)stopbits - 停止位,可取值为:STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TOW。
        (5)xonxoff - 软件流控,可取值为 True, False。
        (6)rtscts - 硬件(RTS/CTS)流控,可取值为 True, False。
        (7)dsr/dtr - 硬件(DSR/DTR)流控,可取值为 True, False。
        (8)timeout - 读超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。当设置为 None 时,表示阻塞式读取,一直读到期望的所有数据才返回;当设置为 0 时,表示非阻塞式读取,无论读取到多少数据都立即返回;当设置为其他数值时,表示设置具体的超时时间(以秒为单位),如果在该时间内没有读取到所有数据,则直接返回。
        (9)write_timeout: 写超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。参数值起到的效果参考 timeout 参数。

相关操作1关闭串口

ser = serial.Serial("COM17", 115200)    # 打开 COM17,将波特率配置为115200,其余参数使用默认值
if ser.isOpen():                        # 判断串口是否成功打开
    print("打开串口成功。")
else:
    print("打开串口失败。")
 
ser.close()
if ser.isOpen():                        # 判断串口是否关闭
    print("串口未关闭。")
else:
    print("串口已关闭。")

相关操作2: 发送数据 write()

关于write() 方法,需要了解如下几点:
① write() 方法只能发送 bytes 类型的数据,所以需要对字符串进行 encode 编码。
② write() 方法执行完成后,会将发送的字节数作为返回值。
③ 在打开串口时,可以为 write() 方法配置超时时间

import serial
# 打开 /dev/ttyAMA10,将波特率配置为115200.
ser = serial.Serial(port="/dev/ttyAMA10", baudrate=115200)
# 串口发送 ABCDEFG,并输出发送的字节数。
write_len = ser.write("ABCDEFG".encode('utf-8'))
print("串口发出{}个字节。".format(write_len))
 
ser.close()

相关操作3:读取数据 read()

import serial
 
# 打开 /dev/ttyAMA10,将波特率配置为115200, 读超时时间为1秒
ser = serial.Serial(port="/dev/ttyAMA10", baudrate=115200, timeout=1)
 
# 读取串口输入信息并输出。
while True:
    com_input = ser.read(10)
    if com_input:   # 如果读取结果非空,则输出
        print(com_input)
 
ser.close()

相关操作4:发送十六进制信息

使用Python的 bytes.fromhex() 方法将16进制字符串转换为字节序列,并使用 serial.write() 方法发送数据。 

import serial

# 打开串口
ser = serial.Serial(port="/dev/ttyAMA10", baudrate=115200)

# 构造要发送的16进制数据
hex_data = bytes.fromhex("55 00 01 01 57")

# 发送数据并获取发送字节数
write_len = ser.write(hex_data)

# 输出发送的字节数
print("串口发送了{}个字节。".format(write_len))

# 关闭串口
ser.close()

相关操作5:接收十六进制信息

方法与相关操作4基本一致。

    # 持续读取串口输入信息并输出
    while True:
        com_input = ser.read(10)  # 读取最多10个字节
        if com_input:  # 如果读取结果非空,则输出
            hex_data = com_input.hex()  # 将字节序列转换为十六进制字符串
            print("接收到的十六进制数据:", hex_data)

相关操作6,:函数封装 

import serial
import time

def serial_communication(send_data):
    try:
        # 打开串口
        ser = serial.Serial(port="/dev/ttyUSB1", baudrate=115200, timeout=1)

        # 构造要发送的十六进制数据
        hex_data = bytes.fromhex(send_data)

        # 发送数据并获取发送字节数
        write_len = ser.write(hex_data)
        print("串口发送了{}个字节。".format(write_len))

        # 读取串口输入信息并返回接收到的数据
        timeout = 10  # 设置超时时间为10秒
        start_time = time.time()
        while (time.time() - start_time) < timeout:
            com_input = ser.read(60)
            if com_input:  # 如果读取结果非空,则返回接收到的数据
                hex_data_received = com_input.hex()  # 将字节序列转换为十六进制字符串
                return hex_data_received

    except serial.SerialException as e:
        print(f"串口通信错误: {e}")

    finally:
        # 关闭串口
        if ser.is_open:
            ser.close()
            print("串口已关闭。")

    return None  # 如果出现异常或超时,返回None

# 测试函数调用
send_data = "5500010157"  # 要发送的十六进制数据,例如 "5500010157"
received_data = serial_communication(send_data)
if received_data:
    print("接收到的十六进制数据:", received_data)
else:
    print("未接收到数据或出现错误。")

本文参考:用 Python 玩转串口(基于 pySerial)

应用参考:树莓派--uart通信python实现2

### 树莓派 Python 串口通信教程 #### 准备工作 为了使树莓派能够通过USB转TTL串口与其他设备进行通信,需调整配置以确保GPIO上的UART接口不被用作Linux控制台。这可以通过停止并禁用`serial-getty@ttyAMA0.service`服务来实现[^4]。 ```bash sudo systemctl stop serial-getty@ttyAMA0.service sudo systemctl disable serial-getty@ttyAMA0.service ``` 接着编辑启动参数文件 `/boot/cmdline.txt` ,移除其中有关于 `console=serial0,115200` 的设定(如果存在)。完成上述操作之后保存更改并重启系统以便新设置生效。 #### 安装依赖库 安装PySerial库可以方便地处理串行端口的数据传输: ```bash pip install pyserial ``` #### 编写Python代码 下面是一个简单的例子展示怎样利用Python脚本来读取来自其他设备的信息以及向其发送指令。这里假设波特率为9600bps,并且连接到名为`ttyUSB0`的虚拟COM端口上;对于某些情况可能需要更改为其他的名称比如`ttyS0`或`ttyAMA0`取决于具体的接线方式和操作系统版本。 ```python import time import serial ser = serial.Serial( port='/dev/ttyUSB0', # 替换成实际使用的串口号 baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1 # 设置超时时间 ) if ser.isOpen(): try: while True: if ser.in_waiting > 0: data_raw = ser.read(ser.in_waiting).hex() # 将收到的数据转换成十六进制字符串表示形式 print(f"Received: {data_raw}") send_data_hex = 'aabbccdd' # 要发送的数据,这里是示例值 ser.write(bytes.fromhex(send_data_hex)) # 发送前将十六进制字符串转化为字节流 time.sleep(1) # 延迟一秒再继续循环 except KeyboardInterrupt: pass finally: ser.close() else: print('Failed to open the serial port.') ``` 这段程序会持续监听是否有新的输入到达指定的串行端口,并打印出来自外部装置的消息作为调试信息。同时每隔一秒钟它还会尝试向外设发出一组预定义好的16进制编码后的消息。 #### 注意事项 - 如果遇到权限问题无法访问串行端口,则考虑给当前用户添加至dialout组或者临时给予root权限运行该应用程序。 - 对于不同的应用场景,请根据实际情况调整串行端口路径、波特率以及其他初始化选项。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值