电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
树莓派基础实验37:pyserial模块通信实验
分 享
扫描二维码分享
树莓派基础实验37:pyserial模块通信实验
树莓派
python
pyserial
张国平
关注
发布时间: 2020-09-07
丨
阅读: 1548
## 一、介绍 串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。串口是计算机上一种非常通用的设备通信协议,pyserial模块封装了python对串口的访问,为多平台的使用提供了统一的接口。 在[树莓派基础实验35:USB TO TTL模块实验](https://www.icxbk.com/article/detail?aid=1674)中学习了通过串口对树莓派进行控制台控制,让串口作为控制终端调试口即 serial console。 在[树莓派基础实验36:通用串口通信实验](https://www.icxbk.com/article/detail?aid=1697)中学习了设置树莓派的串口为通用串口与PC电脑的串口调试工具进行通信。 本实验中学习树莓派中使用Python的pyserial模块,通过串口与PC电脑的串口调试工具进行通信。 ## 二、组件 ★Raspberry Pi 3 B+主板*1 ★树莓派电源*1 ★USB TO TTL模块*1 ★面包板*1(可选) ★40P软排线*1 ★跳线若干 ## 三、实验原理 ####(一)pyserial概述 该模块封装了对串行端口的访问。它为Windows,OSX,Linux,BSD(可能是任何POSIX兼容系统)和IronPython上运行的[Python](http://python.org/)提供了后端。名为“串行”的模块会自动选择适当的后端。 功能: * 在所有支持的平台上基于相同类的接口。 * 通过Python属性访问端口设置。 * 通过RTS / CTS和/或Xon / Xoff支持不同的字节大小,停止位,奇偶校验和流控制。 * 有无超时都可以使用。 * 带有“读”和“写”的API之类的文件(也支持“ readline”等)。 * 该软件包中的文件是100%纯Python。 * 该端口已设置为二进制传输。没有NULL字节剥离,CR-LF转换等(对于POSIX启用了很多次)。这使该模块具有通用性。 * 与io库兼容 * 示例中提供的RFC 2217客户端(实验)。 ####(二)pyserial介绍 ##### 1.本地端口 ```python class serial.Serial __init__(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, write_timeout=None, dsrdtr=False, inter_byte_timeout=None) ``` 其中: **port**:设备名称或None。如COM1,COM2,COM3,COM4......如果port设置为0对应的为COM1。 **baudrate**(int):设置波特率,如9600或115200等。 **bytesize**:数据位,可能的值:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS。 **parity**:奇偶校验, 启用奇偶校验。PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE。 **stopbits**:停止位,可能的值:STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO。 **timeout**(float):设置读取超时值,timeout = None: 长时间等待;timeout = 0: 不阻塞形式 (读完之后就返回);timeout = x: x秒后超时 (float allowed)。 **xonxoff**(bool):启用软件流控制。 **rtscts**(bool):启用硬件(RTS / CTS)流量控制。 **dsrdtr**(bool):启用硬件(DSR / DTR)流控制。 **write_timeout**(float):设置写超时值。 **inter_byte_timeout**(float):字符间超时,None禁用(默认)。 ##### 2.打开串口 在给出端口时,在创建对象时立即打开端口。当端口是`None`并且需要连续调用时它不会打开[`open()`](https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.open)。 *port*是设备名称:取决于操作系统。 打开串口0, 9600,8,N,1,连接超时0.5秒: ```python import serial #导入pyserial模块 ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5) #使用USB连接串行口 ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) #使用树莓派的GPIO口连接串行口 ser=serial.Serial(1,9600,timeout=0.5)#winsows系统使用com1口连接串行口 ser=serial.Serial("com1",9600,timeout=0.5)#winsows系统使用com1口连接串行口 ser=serial.Serial("/dev/ttyS1",9600,timeout=0.5)#Linux系统使用com1口连接串行口 print ser.name#打印设备名称 print ser.port#打印设备名 ser.open() #打开端口 s = ser.read(10)#从端口读10个字节 ser.write("hello")#向端口些数据 ser.close()#关闭端口 ``` #####3.获得串行口状态 串行口的属性: name:设备名字 portstr:已废弃,用name代替 port:读或者写端口 baudrate:波特率 bytesize:字节大小 parity:校验位 stopbits:停止位 timeout:读超时设置 writeTimeout:写超时 xonxoff:软件流控 rtscts:硬件流控 dsrdtr:硬件流控 interCharTimeout:字符间隔超时 属性的使用方法: ```python ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) ser.open() print ser.name#设备名字 print ser.port#读或者写端口 print ser.baudrate#波特率 print ser.bytesize#字节大小 print ser.parity#校验位N-无校验,E-偶校验,O-奇校验 print ser.stopbits#停止位 print ser.timeout#读超时设置 print ser.writeTimeout#写超时 print ser.xonxoff#软件流控 print ser.rtscts#硬件流控 print ser.dsrdtr#硬件流控 print ser.interCharTimeout#字符间隔超时 ser.close() ``` #####4.设置串行口状态 ```python ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) ser.baudrate=9600#设置波特率 ser.bytesize=8#字节大小 ser.bytesize=serial.EiGHTBITS#8位数据位 ser.parity=serial.PARITY_EVEN#偶校验 ser.parity=serial.PARITY_NONE#无校验 ser.parity=serial.PARITY_ODD#奇校验 ser.stopbits=1#停止位 ser.timeout=0.5#读超时设置 ser.writeTimeout=0.5#写超时 ser.xonxoff=False#软件流控 ser.rtscts=False#硬件流控 ser.dsrdtr=False#硬件流控 ser.interCharTimeout=0.5#字符间隔超时 ``` #####5.serial方法: ```python open() # 打开串口 close() # 立即关闭串口 isOpen() #看看这个串口是否已经被打开 setBaudrate(baudrate) # change baud rate on an open port inWaiting() # 返回接收缓存中的字节数 read(size=1) # 从串口读size个字节。如果指定超时, # 则可能在超时后返回较少的字节; # 如果没有指定超时,则会一直等到收完指定的字节数。 write(s) # 发送s,并返回发送字节数。如果bytes和bytearray可用, #则接受其作为参数;否则接受str作为参数。 flushInput() # 丢弃接收缓存中的所有数据 flushOutput() # 终止当前写操作,并丢弃发送缓存中的数据。 sendBreak(duration=0.25)# 发送BREAK条件,并于duration时间之后返回IDLE setRTS(level=1) # 将RTS行设置为指定的逻辑级别 setDTR(level=1) # 将DTR行设置为指定逻辑级别 getCTS() # 返回CTS行的状态 getDSR() # 返回DSR行的状态 getRI() # 返回RI行的状态 getCD() # 返回CD行的状态 ``` #####6.Readline库 ```python data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。 data = ser.readlines()和ser.xreadlines()#都需要设置超时时间 ``` 使用readline()时要小心。在打开串行端口时,请务必指定一个超时时间,否则如果没有收到换行符,它将永远阻塞。另请注意,readlines()仅适用于超时。 readlines()取决于是否存在超时,并将其解释为EOF(文件末尾)。如果未正确打开端口,则会引发异常。 #####7.EOL 要为指定EOL字符或使用通用换行模式,建议使用[io.TextIOWrapper](http://docs.python.org/library/io.html#io.TextIOWrapper): ```python import serial import io ser = serial.serial_for_url('loop://', timeout=1) sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) sio.write(unicode("hello\n")) sio.flush() # it is buffering. required to get the data out *now* hello = sio.readline() print(hello == unicode("hello\n")) ``` ## 四、实验步骤 **第1步:** 连接电路。与[树莓派基础实验36:通用串口通信实验](https://www.icxbk.com/article/detail?aid=1697)一样设置树莓派的串口为通用串口,与PC上的串口调试工具通信。 | 树莓派(name) | T型转接板(BCM) | USB TO TTL模块 | |:-:|:-:|:-:| |TXD|TXO|RXD| |RXD|RXI|TXD| |GND|GND|GND| 下图中的USB要插到笔记本电脑上哈,为方便拍照就没插上。连线很简单,电路图就没画了。 ![USB TO TTL模块实物接线图](https://upload-images.jianshu.io/upload_images/12472291-5cd8712dc2cd7ff7.jpg) **第2步:** 向串口发送简单数据程序。PC串口调试工具上将收到字符串“Send string by serial”。 ```python import serial ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=0.5) ser.write('Send string by serial'.encode("gbk")) ``` **第3步:** 树莓派接收PC串口调试工具发送的字符,打印出来,再发送回PC串口调试工具。手动设置读取字符的数量。 ```python #!/usr/bin/python import serial from time import sleep ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=0.5) print ser.port print ser.baudrate def recv(serial): while True: data =serial.read(10) #手动设置读取字符的数量为10 if data == '': continue else: break sl
eep(0.02) return data while True: data =recv(ser) if data != '': print data ser.write(data) ``` **第4步:** 树莓派接收PC串口调试工具发送的字符,打印出来,再发送回PC串口调试工具。通过inWaiting()函数自动获得接收缓冲区字符数。 ```python # -*- coding: utf-8 -* import serial import time ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=0.5) def rec_tra(): while True: count = ser.inWaiting() # 获得接收缓冲区字符 if count != 0: recv = ser.read(count) # 读取内容 ser.write(recv) # 发送回PC print recv ser.flushInput() # 清空接收缓冲区 time.sl
eep(0.1) # 必要的软件延时 if __name__ == '__main__': try: rec_tra() except KeyboardInterrupt: if ser != None: ser.close() ``` ![](https://upload-images.jianshu.io/upload_images/12472291-356c1b070e49c3c0.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
张国平
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交