树莓派玩转树莓派张国平玩树莓派

树莓派基础实验37:pyserial模块通信实验

2020-09-05  本文已影响0人  Maker张

一、介绍

  串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。串口是计算机上一种非常通用的设备通信协议,pyserial模块封装了python对串口的访问,为多平台的使用提供了统一的接口。

  在树莓派基础实验35:USB TO TTL模块实验中学习了通过串口对树莓派进行控制台控制,让串口作为控制终端调试口即 serial console。

  在树莓派基础实验36:通用串口通信实验中学习了设置树莓派的串口为通用串口与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提供了后端。名为“串行”的模块会自动选择适当的后端。

功能:

(二)pyserial介绍

1.本地端口
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()

port是设备名称:取决于操作系统。

打开串口0, 9600,8N1,连接超时0.5秒:

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:字符间隔超时

属性的使用方法:

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.设置串行口状态
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方法:
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库
data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
data = ser.readlines()和ser.xreadlines()#都需要设置超时时间

使用readline()时要小心。在打开串行端口时,请务必指定一个超时时间,否则如果没有收到换行符,它将永远阻塞。另请注意,readlines()仅适用于超时。 readlines()取决于是否存在超时,并将其解释为EOF(文件末尾)。如果未正确打开端口,则会引发异常。

7.EOL

要为指定EOL字符或使用通用换行模式,建议使用io.TextIOWrapper

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:通用串口通信实验一样设置树莓派的串口为通用串口,与PC上的串口调试工具通信。

树莓派(name) T型转接板(BCM) USB TO TTL模块
TXD TXO RXD
RXD RXI TXD
GND GND GND

下图中的USB要插到笔记本电脑上哈,为方便拍照就没插上。连线很简单,电路图就没画了。


USB TO TTL模块实物接线图

  第2步: 向串口发送简单数据程序。PC串口调试工具上将收到字符串“Send string by serial”。

import serial

ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=0.5)
ser.write('Send string by serial'.encode("gbk"))

  第3步: 树莓派接收PC串口调试工具发送的字符,打印出来,再发送回PC串口调试工具。手动设置读取字符的数量。

#!/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
    sleep(0.02) 
  return data 
 
while True:  
  data =recv(ser) 
  if data != '': 
    print data
    ser.write(data)

  第4步: 树莓派接收PC串口调试工具发送的字符,打印出来,再发送回PC串口调试工具。通过inWaiting()函数自动获得接收缓冲区字符数。

# -*- 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.sleep(0.1)   # 必要的软件延时

if __name__ == '__main__':
    try:
        rec_tra()
    except KeyboardInterrupt:
        if ser != None:
            ser.close()
上一篇下一篇

猜你喜欢

热点阅读