由于测试工作的需要,在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或威纶触摸屏的数据吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)