python - serial communication(串口通信)

python - serial communication(串口通信),第1张

由于测试工作的需要,在C端产品上经常使用串口进行通信,而测试脚本大部分时候又采用python编写,于是就不得不了解并熟悉python下的串口通信实现方法了,整理如下以备随时使用:

一、说明

pyserial封装了python环境下对串口的访问,其兼容各种平台,并有统一的 *** 作接口。通过python属性访问串口设置,并可对串口的各种配置参数(如串口名,波特率、停止校验位、流控、超时等等)做修改,再进行串口通信的类与接口封装后,非常方便地被调用和移植。

二、模块安装

pip insatll pyserial

三、初始化与参数说明

import serial

ser = serialSerial('COM3', 115200, timeout=05, )

下面看看 serialSerial 原生类

四、不同平台下初始化

ser=serialSerial("/dev/ttyUSB0",9600,timeout=05)#使用USB连接串行口ser=serialSerial("/dev/ttyAMA0",9600,timeout=05)#使用树莓派的GPIO口连接串行口ser=serialSerial(1,9600,timeout=05)#winsows系统使用COM1口连接串行口ser=serialSerial("COM1",9600,timeout=05)#winsows系统使用COM1口连接串行口ser=serialSerial("/dev/ttyS1",9600,timeout=05)#Linux系统使用COM1口连接串行口

五、串口属性

sername #串口名称

serport #端口号

serbaudrate #波特率

serbytesize #字节大小

serparity #校验位N-无校验,E-偶校验,O-奇校验

serstopbits #停止位

sertimeout #读超时设置

serwriteTimeout #写超时

serxonxoff #软件流控

serrtscts #硬件流控

serdsrdtr #硬件流控

serinterCharTimeout #字符间隔超时 

六、串口常用方法

isOpen():查看端口是否被打开。

open() :打开端口‘。

close():关闭端口。

read(size=1):从端口读字节数据。默认1个字节。

read_all():从端口接收全部数据。

write(data):向端口写数据。

readline():读一行数据。

readlines():读多行数据。

in_waiting():返回输入缓存中的字节数。

out_waiting():返回输出缓存中的字节数。

flush():等待所有数据写出。

flushInput():丢弃接收缓存中的所有数据。

flushOutput():终止当前写 *** 作,并丢弃发送缓存中的数据。

sendBreadk(duration=025):发送BREAK条件,并于duration时间之后返回IDLE

setBreak(level=True):根据level设置break条件。

setRTS(level=True):设置请求发送(RTS)的控制信号

setDTR(level=True):设置数据终端准备就绪的控制信号

七、类与接口封装

import time

import serial

import serialtoolslist_ports

# 串口 *** 作类

class serialCommunication(object):

    def __init__(self, port, bps, timeout):# 可配置更多参数

        port_list =selfshow_usable_com()

        if len(port_list) >0:

            if portnot in port_list:

                selfport = port_list[0]

            else:

                selfport = port

        else:

            print("no usable serial, please plugin your serial board")

            return

        selfbps = bps

        selftimeout = timeout

        try:

            # 初始化串口,并得到串口对象,根据需要可拓展更多参数

            selfser = serialSerial(selfport, selfbps, 8, 'N', 1, timeout=selftimeout, write_timeout=selftimeout)

        except Exception as e:# 抛出异常

            print("Exception={}"format(e))

    # 显示可用串口列表

    @staticmethod

    def show_usable_com():

        serialport_list = []

        portInfo_list =list(serialtoolslist_portscomports())

        if len(portInfo_list) <=0:

            print("can not find any serial port!")

        else:

            print(portInfo_list)

            for i in range(len(portInfo_list)):

                plist =list(portInfo_list[i])

                print(plist)

                serialport_listappend(plist[0])

            print(serialport_list)

            return serialport_list

# 输出串口基本信息

    def serial_infor(self):

        print(selfsername)# 设备名字

        print(selfserport)# 读或者写端口

        print(selfserbaudrate)# 波特率

        print(selfserbytesize)# 字节大小

        print(selfserparity)# 校验位

        print(selfserstopbits)# 停止位

        print(selfsertimeout)# 读超时设置

        print(selfserwriteTimeout)# 写超时

        print(selfserxonxoff)# 软件流控

        print(selfserrtscts)# 软件流控

        print(selfserdsrdtr)# 硬件流控

        print(selfserinterCharTimeout)# 字符间隔超时

    # 打开串口

    def serial_open(self):

        try:

            if not selfserisOpen():

                selfseropen()

        except Exception as e:# 抛出异常

            print("serial_open Exception={}"format(e))

            selfserclose()

    # 读取指定大小的数据

    # 从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。

    def serial_read_with_size(self, size):

        try:

            selfserial_open()

            return selfserread(size)decode("utf-8")

        except Exception as e:

            print("serial_read_all Exception={}"format(e))

            selfserclose()

    # 读取当前串口缓存中的所有数据

    def serial_read_data(self):

        try:

            selfserial_open()

            datalen =selfserinWaiting()

            if datalen ==0:

                return None

            return selfserread(datalen)decode("utf-8")

        except Exception as e:

            print("serial_read_data Exception={}"format(e))

            selfserclose()

    # 读串口全部数据,注意timeout的设置

    # 在设定的timeout时间范围内,如果读取的字节数据是有效的(就是非空)那就直接返回,

    # 否则一直会等到设定的timeout时间并返回这段时间所读的全部字节数据。

    def serial_read_all(self):

        try:

            selfserial_open()

            return selfserread_all()decode("utf-8")

        except Exception as e:

            print("serial_read_all Exception={}"format(e))

            selfserclose()

    # 读一行数据

    # 使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。

    # 如果没有超时,readline会报异常。

    def serial_read_line(self):

        try:

            selfserial_open()

            return selfserreadline()decode("utf-8")

        except Exception as e:

            print("serial_read_line Exception={}"format(e))

            selfserclose()

    # 读多行数据,返回行列表

    def serial_read_lines(self):

        try:

            selfserial_open()

            return selfserreadlines()decode("utf-8")

        except Exception as e:

            print("serial_read_lines Exception={}"format(e))

            selfserclose()

    # 写数据

    def serial_write_data(self, data):

        try:

            selfserial_open()

            selfserflushOutput()

            data_len =selfserwrite(dataencode('utf-8'))

            return data_len

        except Exception as e:

            print("serial_write_data Exception={}"format(e))

            return 0

    # 写行数据,注意参数差异

    def serial_write_lines(self, lines):

        selfserwritelines(lines)

    # 清除串口缓存

    def serial_clean(self):

        try:

            if selfserisOpen():

                selfserflush()

        except Exception as e:

            print("serial_clean Exception={}"format(e))

    # 关闭串口

    def serial_close(self):

        try:

            if selfserisOpen():

                selfserclose()

        except Exception as e:

            print("serial_clean Exception={}"format(e))

if __name__ =='__main__':

    testSerial = serialCommunication("COM10", 1500000, 05)

    testSerialserial_open()

    testSerialserial_infor()

    testSerialserial_write_data("ifconfig eth0\n")

    timesleep(01)

    data = testSerialserial_read_all()

    print(data)

    testSerialserial_close()

八、其他

1)serVERSION表示pyserial版本; 另外,sername表示设备名称

2)端口设置可以被读入字典,也可从字典加载设置:

    getSettingDict():返回当前串口设置的字典

    applySettingDict(d):应用字典到串口设置

3) Readline()是读一行,以/n结束,要是没有/n就一直读,阻塞。注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。

4)serialread_all 与 serialread_all()区别

    serialread_all:读取串口所有的参数信息

    serialread_all():超时时间内从串口读取的所有数据

5) 异常信息

    exception serialSerialException

    exception serialSerialTimeoutException

USB连接即可。硬件设备仍然是Arduino的USB转串口,设备文件/dev/ttyUSB0。烧录下载仍然是在树莓派上执行Arduino IDE。 树莓派和Arduino也可以用串口平行连接,但必须做33V和5V电平的转换,否则烧IO口! 另外

不能。

松下PLC和威纶版本过高,树莓派软件时间过于久,版本低,树莓派无法识别其中的数据。

在树莓派上采集数据,将其传递到本地sqlserver数据库,用Python编写数据采集脚本。这就涉及几个问题:网络中断、断电、工控机重启等异常出现时,为保证出现这几个异常情况,依然可以自动采集数据,需要做到以下两个方案:

1、开机自动启动。

2、脚本未运行时,自动运行。

用的是“线程轮寻”方式。 客户的原程序不能给你。 就是打开串口后,启动一个线程来监听串口数据的进入,不过我给你改一下吧,有数据时,就做数据的处理(也可以发送一个事件,并携带接收到的数据)。 里面的一。 我没有用到串口处理太深的东西

1、串口连接

这种方式在我树莓派的第一篇博客有讲,这里我简单介绍。

连接树莓派,树莓派GPIO串口的GND,txd,rxd分别与转接口的GND,rxd,txd相连,用的什么转接模块我不管,反正最后得变成一个USB的接口接在电脑上,并在电脑设备管理器上的端口选项可以发现它,用Serial登录。

可以用PUTTY登录,我用的是新版的secureCRT。

2、ssh登录

在我的树莓派第一篇博客中,有让你们新建一个不带后缀名的文档文件,这下派上用场了。

直接看我的另一篇博客设置好树莓派的静态ID,用网线将树莓派和路由器LAN口相连,然后我们就可以远程 *** 作我们的树莓派了。

但是得注意,我们得和树莓派在同一个wifi频段上。也就是我们电脑得连接树莓派所连接的路由器的wifi,不然连不上。

3、网线直连

因为树莓派3B只有一个能用的串口,另外一个串口还是虚拟的,这就很揪心了。

你可以通过ssh登录,然后使用其串口。

这里介绍另外一种登录,树莓派和电脑通过一根网线连接即可。

这张图也是我从其他网页所copy过来的,先完成上面的 *** 作,允许其他用户连接什么什么的:

在dos界面输入arp -a,会奇怪地多出个1921681371,而且每台电脑都一样,这是本地连接的IP地址,你就把你电脑看成一个路由器,地址为1921681371,然后你树莓派的IP在其频段下设置。

因为我在树莓派上开启的wlan0,eth0没有被自动打开,我直接暴力地打开一个。

输入:sudo ifconfig eth0 19216813710

然后你打开secureCRT或者PUTTY,通过SSH2登录进去,发现竟然可以登录,而且ping了ping网络还是通的

我这种做法有个很致命的问题,就是每次要用这种方法登录时,都得先通过上面两种方式登录然后强制打开我的eth0。

其实我并不是在通过网线连接电脑再连接Internet,而是直接连接wifi,但我想要树莓派通过网线上网。

那我要怎样只通过一根网线上网呢???

也就是说我们不强制地设置eth0的地址,而是让树莓派一启动就获取到自己的IP然后SSH登录,之后树莓派一直通过静态网络也就是网线上网。

我们把之前关于wifi的设置全部注释掉,就开一个有用的eth0:

输入 sudo vim /etc/resolvconf

在这里我们设置一下DNS,它起到解析域名的作用,不容小觑

第一个nameserver是我路由的,我们添加第二个nameserver,填的是电脑的。我刚才说了,我们把电脑看成路由器时,它就变成了1921681371,它反而要开始分配地址了。

设置好之后,输入sudo reboot重启,然后直接SSH登录,完美连接上。

而现在我们是通过eth0上网而不是wifi了。

4、网线直连(重修订)

今天重新看了下自己的博客,发现写得有点乱,这里重新编辑一下,以方便大家。新购买树莓派的各位,在只有一根网线的前提下,可以直接先看这一部分。

首先完成如下的 *** 作。我是通过无线连接网络,然后网线口连接树莓派的。

如果遇到下图这样的问题,请迅速win+R然后敲入servicesmsc进入服务选项,将Windows Firewall服务打开。

在cmd窗口敲入arp -a的时候,如果没有显示自己树莓派的地址(0-254)之间,可以尝试重新拔插。

如果还是找不到,就在cmd下敲入这个,ping137下所有的IP地址,这样就能得到ip以及mac等地址。

for /l %i in (1,1,255) do ping -n 1 -w 60 192168137%i | find "回复" >> pingalltxt

这个192就是我们树莓派所获得的地址,使用CRT或者putty登录它即可。

1树莓派的第一排的第三,四,五个分别,也就是下图的6,8,10三个端口分别是地,TX与RX,与被连接设备连接起来。注意树莓派的TX要连接从设备的RX,树莓派的RX要连接树莓派的TX

2树莓派上只有一个串口,系统默认将它作为调试口,所以不能直接当成普通串口进行编程和使用,需要先将调试口的配置去掉,再使用。此处需要修改两处文件

21 修改/boot/cmdlinetxt

在终端输入如下指令

[plain] view plain copy

sudo nano /boot/cmdlinetxt

打开后将红色部分删除

dwc_otglpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

删除后,变成如下结果保存退出

dwc_otglpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

22 修改 /etc/inittab

在终端输入如下指令

[plain] view plain copy

sudo nano /etc/inittab

打开后将最后一行注释掉 在前面加上一个#号即可

#T0:23:respawn:/sbin/getty

-L ttyAMA0 115200 vt100

3修改完毕后,需要在树莓派上安装一个minicom,这里的minicom是Linux平台的串口调试工具,相当于Windows上的串口调试助手

31 安装minicom,输入以下命令

[plain] view plain copy

sudo apt-get install minicom

32 安装完毕后需要对minicom进行配置,此处配置文件需要root权限,不然无法保存配置的参数,那么在命令行中输入如下命令

[plain] view plain copy

sudo passwd root

执行此命令后系统会提示输入两遍的root密码,输入你想设的密码即可,然后在执行

[plain] view plain copy

sudo passwd --unlock root

这样就解锁了root账户

33 切换到root账户,再次打开命令行,输入minicom参数配置命令

[plain] view plain copy

minicom -s

在主菜单的第三项Serial Port Setup,进入下一级菜单,根据菜单项的提示字母选择,按A将串口设备修改为 /dev/ttyAMA0 ,按E将波特率修改为9600或者自己需要的数值,设置好以后返回主菜单,选择Save Setup as Dfl

然后选择Exit,此时如果正常的话就可以进行串口收发了,这里我的树莓派是连接到一台PC上去的,我利用PC的串口调试软件成功进行了收发

tips: 按CTRL+A,接着按Z可以查看minicom的帮助

以上就是关于python - serial communication(串口通信)全部的内容,包括:python - serial communication(串口通信)、树莓派和Arduino怎么串口通信、树莓派能采集松下PLC或威纶触摸屏的数据吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10163584.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存