树莓派在linux上层支持通用的串口接口,用linux上通用的串口编程即可操作。
树莓派3B的板载串口被蓝牙占用,但可以方便地使用USB串口模块。

概述

树莓派的板载串口是给系统登录使用的,我们要先把这个功能关掉。
sudo raspi-config
Advanced Options –> Serial –> 关闭串口 –> 重启

树莓派上有两个串口,一个硬件串口,工作稳定,但是分配给了蓝牙;还有一个“mini-uart”,这个串口的时钟是由内核提供,所以不太稳定 。 在树莓派3B上,蓝牙和硬件串口是不能兼得的。
这个链接(http://ukonline2000.com/?p=880)有介绍如何把硬件串口分配到GPIO14、GPIO15上,这里不做介绍了。

总之,在树莓派3B上,想要使用板载硬件串口是比较麻烦的,我们这里使用的是USB转串口模块,也能很方便地使用串口。

pypi库没有提供串口操作函数,我们使用串口的思路是通过linux上层通用的串口接口。

python通用串口库——pyserial

这里介绍的是第三方库 pyserial 的安装和使用。
ubuntu、mac和树莓派上,只要安装了python都可以用此方法操作串口。

官网:http://pyserial.sourceforge.net/
github主页:https://github.com/pyserial/pyserial

一、安装

网上有很多pip安装的方法,但那些好像都是针对python2的,python3安装不了,正确方法如下:
mac下也可以用这种方法安装,但mac需要先安装驱动,我用的是PL2303,从官网下载的驱动,安装完成后的节点是 /dev/tty.usbserial。

1、从github clone代码
git clone git@github.com:pyserial/pyserial.git

2、进入安装目录安装
sudo python3 setup.py install
(在mac下安装不用sudo权限也行)

3、python3中import模块
import serial
如果没有安装成功的话 import 会报错。

二、使用

首先要 import serial

1、打开串口并创建对象

[串口对象] = serial.Serial(‘[串口设备文件]’,
              baudrate=[波特率],
              bytesize=[数据位],
              parity=’[校验]’,
              stopbits=[停止位],
              timeout=[timeout])

  • 串口设备文件就是/dev/目录下的设备文件,传入的是一个字符串,比如 ‘/dev/ttyUSB0’。
  • budrate是波特率,传入的是数值。可以选择:
    2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200
  • bytesize是数据位,传入的是数值
    可以省略,默认是8。
  • parity是校验,传入的是字符串。可以设置为:
    ‘N’    不校验
    ‘O’    奇校验(ODD)
    ‘E’    偶校验(EVEN)

    可以省略,默认是’N’。
  • stopbits是停止位个数,传入的是数值,一般都是设成1。
    可以生录入,默认是1。
  • timeout是超时等待,在接收数据时,如果接收到的字符不满足返回条件则会等待,超时后返回。

  例1,指明所有参数:
  ser = serial.Serial(‘/dev/ttyUSB1’,
           baudrate=9600,
           bytesize=8,
           parity=’N’,
           stopbits=1,
           timeout=3)

  例2,只指定某些参数:
  ser = serial.Serial(‘/dev/ttyUSB1’, 9600, timeout=3)

2、缓冲区操作

  python对串口接收数据和单片机有所不同。
  单片机接收到数据后会产生中断,然后在中断中处理数据。
  python是不会产生串口中断的,接收到的数据会存放在缓冲区,然后python程序主动检查缓冲区读取数据。读取数据方法也有多种。
  每次新打开一个串口,之前的缓冲区就会被清空。
  缓冲区有输入缓冲区和输出缓冲区。
  缓冲区的大小是:

  [串口对象].flushInput()
  清除接收缓冲区,放弃接收到的所有内容。
  [串口对象].flushOutput()
  清除发送缓冲区,放弃输出。

  [串口对象].inWaiting()
  【功能】获取缓冲区里的字节数。
  【输出】返回一个数值,代表缓冲区里有多少数据。

3、波特率设置

  [串口对象].setBaudrate([波特率])
  设置已经打开的串口的波特率,传入的是数值,可以选择:
  2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200

4、从串口发送数据

  [串口对象].write([单字节数组])
  发送的数据必须是单字节数据,可以是单字节组成的list,也可以是单字节编码的字符串(如ASCII、UTF-8)。   返回的是写入的字节数。
  例1,发送16进制数据:
  list1 = [0x01,0x02,0x03,0x10]
  ser.write(list1)

  会把这几个16进制数依次通过串口发出,另一端会接收到一模一样的数据。
  例2,发送单字节编码的字符串:
  ser.write(b’abcdefg’)
  把字符串’abcdefg’的ascii码发出,另一端收到:0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67。

5、从串口接收数据

  [串口对象].read([长度])
  【功能】从缓冲区读取指定长度内容。
  【输入】
  [长度] 是一个数值,代表要从缓冲区读取的字节数。
  这个参数可以省略,默认是1。
  【输出】输出的是一连串单字节数据。
  【说明】如果缓冲区内容小于读取的长度则会等待,直到timeout后读取仅有的全部内容返回。

  [串口对象].readall()
  【功能】读取缓冲区的所有数据。
  【输出】输出的是一连串单字节数据。
  这个函数必然会等待一个timeout时间,把之前缓冲区里所有内容和等待阶段接收到的所有内容读出。

  [串口对象].readline()
  【功能】从缓冲区里读取一行。
  【输出】输出的是一连串单字节数据。
  【说明】
  读取时会找到第一个’\n’结束,如果缓冲区里的数据没有’\n’,则会等待,知道timeout后返回仅有的所有内容。

6、关闭串口

  [串口对象].close()


本站所有文章欢迎转载,但请保留作者信息和原文地址。

Comments