0 Serial方法
1、导入pyserial模块
import serial
2、打开串行口
// 打开串口0, 9600,8N1,连接超时0.5秒
import serial
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()#关闭端口
data = ser.read(20) #是读20个字符
data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
data = ser.readlines()和ser.xreadlines()#都需要设置超时时间
ser.baudrate = 9600 #设置波特率
ser.isOpen() #看看这个串口是否已经被打开
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、设置串行口状态
需要用的常量
bytesize:FIVE BITS、SIXBITS、SEVENBITS、EIGHTBITS
parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
异常:
ValueError:参数错误
SerialException:找不到设备或不能配置
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#软件流控
ser.rtscts#硬件流控
ser.dsrdtr#硬件流控
ser.interCharTimeout#字符间隔超时
5、Readline方法的使用
是读一行,以/n结束,要是没有/n就一直读,阻塞。
使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。如果没有超时,readline会报异常。
6、serial.Serial类——原生端口
class serial.Serial
{
init(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)
#其中:
# 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
#异常:
#ValueError:参数错误
#SerialException:找不到设备或不能配置
open():打开串口
close():立即关闭串口
del():析构函数
read(size=1):从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。
write(data):发送data,并返回发送字节数。如果bytes和bytearray可用(python 2.6以上),则接受其作为参数;否则接受str作为参数。
#异常:SerialTimeoutException——配置了写超时并发生超时时发生此异常。
inWaiting():返回接收缓存中的字节数
flush():等待所有数据写出。
flushInput():丢弃接收缓存中的所有数据
flushOutput():终止当前写操作,并丢弃发送缓存中的数据。
sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE
setBreak(level=True):根据level设置break条件。
setRTS(level=True)
setDTR(level=True)
getCTS()
getDSR()
getRI()
getCD()
#只读属性:
name:设备名字
portstr:已废弃,用name代替
port:读或者写端口
baudrate:波特率
bytesize:字节大小
parity:校验位
stopbits:停止位
timeout:读超时设置
writeTimeout:写超时
xonxoff:软件流控
rtscts:硬件流控
dsrdtr:硬件流控
interCharTimeout:字符间隔超时
#端口设置可以被读入字典,也可从字典加载设置:
getSettingDict():返回当前串口设置的字典
applySettingDict(d):应用字典到串口设置
#对提供io库的系统(python 2.6或以上),Serial从io.RawIOBase派生。对其它系统,从FileLike派生。
#异常:
exception serial.SerialException
exception serial.SerialTimeoutException
#常量:
serial.VERSION:pyserial版本
#模块函数和属性:
serial.device(number)
serial.serial_for_url(url, *args, **kwargs)
serial.protocol_handler_packages()
serial.to_bytes(sequence):接收一个字符串或整数列表sequence,返回bytes实例
1 确定串口名称
1.1 WINDOWS
获取可用串口列表
#!/usr/bin/env python
#-*- coding: utf-8 -*
import serial
import serial.tools.list_ports
plist = list(serial.tools.list_ports.comports())
if len(plist) <= 0:
print ("The Serial port can't find!")
else:
plist_0 =list(plist[0])
serialName = plist_0[0]
serialFd = serial.Serial(serialName,9600,timeout = 60)
print ("check which port was really used >",serialFd.name)
import serial #导入模块
import serial.tools.list_ports
port_list = list(serial.tools.list_ports.comports())
print(port_list)
if len(port_list) == 0:
print('无可用串口')
else:
for i in range(0,len(port_list)):
print(port_list[i])
1.2 LINUX
查询从系统启动到现在串口插拔的信息,显示串口Ubuntu连接的端口号:
在终端输入:
dmesg | grep ttyS*
在Ubuntu下装了CuteCom,但当打开 /dev/ttyUSB0 时,总提示错误,打开失败时:
用 Minicom 可以正常读取 ttyUSB0。
sudo chmod 666 /dev/ttyUSB0
这样修改后, CuteCom 就可以正常打开 USB 串口了
1,pycharm程序端代码。
#usr/bin/python3
# -*- coding: utf-8 -*-
import serial
from time import sleep
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5)
def recv(serial):
global data
while True:
data = serial.read(30)
if data == '':
continue
else:
break
sleep(0.02)
return data
while True:
data = recv(ser)
ser.write(data)
在pycharm上的程序:
程序效果为: 运行后,在CuteCom发生的代码, 程序这边会原文返回发给CuteCom。
1.3 Python(Linux下)获取串口的idv和idp以及serial序列号
串口端口的获取脚本
# coding=utf-8
#
__author__ = 'Haleydu'
__editTime__ = '2018.12.7'
import serial.tools.list_ports
import serial
import os
import re
class AutoMatchSerialPort:
#一.获取串口 or 判断是否存在该串口
def getSerial(self,needdev=''):
needSerial=''
port_list = list(serial.tools.list_ports.comports())
if len(port_list) <= 0:
print ("The Serial port can't find!")
else:
#1.过滤,获取需要的串口
for i in list(port_list):
if i.name==needdev:
needSerial=i.name
print(i.name,end=',')
print('\n')
#2.返回获取的目的串口为了绑定
return needSerial
# 二.根据端口号返回ID号和硬件号
def getSerialIDAndSer(self,dev):
cmd = "udevadm info --attribute-walk --name=" + dev
result = self.execCmd(cmd)
pat1 = "ATTRS{idVendor}==.?(\d\d\d\d).?"
pat2 = "ATTRS{idProduct}==.?(\d\d\d\d).?"
pat3 = 'ATTRS{serial}==.([A-Za-z0-9]+).'
ret1 = re.search(pat1,result)
ret2 = re.search(pat2,result)
ret3 = re.search(pat3,result)
idv = ret1.group(1)
idp = ret2.group(1)
ser = ret3.group(1)
return idv,idp,ser
# 三.根据ID号或者序列号返回串口的端口号,也可以用别名直接调用该串口(运行后需要拔插目的串口后生效)
def getSerialPort(self,idv='',idp='',ser='',alias='ttyUSB_test'):
if idv==''or idp=='':
contentID = 'ATTRS{serial}=="'+ser+', MODE:="0777", SYMLINK+="'+ alias +'" \n'
elif ser=='':
contentID = '", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n'
else:
contentID = 'ATTRS{serial}=="'+ser+'", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n'
path='/etc/udev/rules.d/getSerialPort_'+alias+'.rules'
if os.path.exists(path):
#print('存在文件')
f = open(path,"w")
f.write(contentID)
f.flush()
f.close()
#print('创建成功')
#print('重新拔插串口后生效')
else:
#print('不存在文件,开始创建getSerialPort_'+alias+'.rules的udev规则文件')
f = open(path,"w")
f.write(contentID)
f.flush()
f.close()
#print('创建成功')
#print('重新拔插串口后生效')
#重启udev规则
#sudo /etc/init.d/udev restart
#根据ID获得端口号
cmd = "udevadm info --attribute-walk --name=" + alias
result = self.execCmd(cmd)
pat = '(ttyUSB.)'
ret = re.search(pat,result)
dev=''
try:
dev = ret.group(1)
except AttributeError:
if dev=='':
print('重新拔插串口后生效')
return dev
#调用终端,获取终端输出
def execCmd(self,cmd):
r = os.popen(cmd)
result = r.read()
r.close()
return result
if __name__ == '__main__':
am=AutoMatchSerialPort()
am.getSerial()
print('ttyUSB0:' + str(am.getSerialIDAndSer("ttyUSB0")))
print('ttyUSB1:' + str(am.getSerialIDAndSer("ttyUSB1")))
print('0403:6002,FT2NPXY4,ttyUSB_1:' + am.getSerialPort('0403','6002','FT2NPXY4','ttyUSB_1'))
print('0403:6001,FTSYWCXZ,ttyUSB_2:' + am.getSerialPort('0403','6001','FTSYWCXZ','ttyUSB_2'))
2 SERIAL 串口操作
参考文档:
https://blog.csdn.net/qq_14997473/article/details/80875722:Python学习笔记——串口配置以及发送数据
https://blog.csdn.net/ubuntu14/article/details/75335106:python实现串口自动触发工作
(1) 安装pyserial库
pip install pyserial
serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux
(2) pyserial库常用函数介绍
serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux
print serial .portstr 能看到第一个串口的标识
serial .write(“hello”) 往串口里面写数据
serial .close() 关闭serial 表示的串口
serial .open() 打开串口
data = serial .read(num) 读num个字符
data = serial .readline() 读一行数据,以/n结束,要是没有/n就一直读,阻塞。
serial .baudrate = 9600 设置波特率
print serial 可查看当前串口的状态信息
serial .isOpen() 当前串口是否已经打开
serial.inWaiting() 判断当前接收的数据
serial.flushInput() 清除输入缓冲区数据
serial.flushOutput() 中止当前输出并清除输出缓冲区数据
(3) 实例: 获取从其他串口发送来的数据并回显
#!/usr/bin/python
# coding=UTF-8
import serial
###################################################
#
# 功 能: 将接收到的数据已hex显示
# 参 数: 串口接受到的数据
# 返 回: 转换后的数据
#
###################################################
def hexshow(data):
hex_data = '' hLen = len(data)
for i in xrange(hLen):
hvol = ord(data[i])
hhex = '%02x' % hvol
hex_data += hhex+' '
print 'hexshow:', hex_data
###################################################
#
# 功 能: 将需要发送的字符串以hex形式发送
# 参 数: 待发送的数据
# 返 回: 转换后的数据
#
###################################################
def hexsend(string_data=''):
hex_data = string_data.decode("hex")
return hex_data
if __name__ == '__main__':
serial = serial.Serial('/dev/ttyS0', 115200)
print serial
if serial.isOpen():
print("open success")
else:
print("open failed")
try:
while True:
count = serial.inWaiting()
if count > 0:
data = serial.read(count)
if data != b'':
print("receive:", data)
serial.write(data)
else:
serial.write(hexsend(data))
except KeyboardInterrupt:
if serial != None:
serial.close()
16进制处理
import serial #导入模块
try:
portx="COM3"
bps=115200
#超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
timex=None
ser=serial.Serial(portx,bps,timeout=timex)
print("串口详情参数:", ser)
#十六进制的发送
result=ser.write(chr(0x06).encode("utf-8"))#写数据
print("写总字节数:",result)
#十六进制的读取
print(ser.read().hex())#读一个字节
print("---------------")
ser.close()#关闭串口
except Exception as e:
print("---异常---:",e)
其他
import serial #导入模块
try:
#端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
portx="COM3"
#波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
bps=115200
#超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
timex=5
# 打开串口,并得到串口对象
ser=serial.Serial(portx,bps,timeout=timex)
print("串口详情参数:", ser)
print(ser.port)#获取到当前打开的串口名
print(ser.baudrate)#获取波特率
result=ser.write("我是东小东".encode("gbk"))#写数据
print("写总字节数:",result)
#print(ser.read())#读一个字节
# print(ser.read(10).decode("gbk"))#读十个字节
#print(ser.readline().decode("gbk"))#读一行
#print(ser.readlines())#读取多行,返回列表,必须匹配超时(timeout)使用
#print(ser.in_waiting)#获取输入缓冲区的剩余字节数
#print(ser.out_waiting)#获取输出缓冲区的字节数
#循环接收数据,此为死循环,可用线程实现
while True:
if ser.in_waiting:
str=ser.read(ser.in_waiting ).decode("gbk")
if(str=="exit"):#退出标志
break
else:
print("收到数据:",str)
print("---------------")
ser.close()#关闭串口
except Exception as e:
print("---异常---:",e)
3 解决 ImportError: No module named ‘serial’ 问题
在pycharm里编写Python串口程序的时候,编译时提示 ImportError: No module named ‘serial’
解决办法:
安装 serial module
这里区分python2和 python3:
首先需要在终端输入:
sudo apt install python-pip //python2
sudo apt install python3-pip //python3
安装python3的 pip3的时候,如果时国内的软件源可能安装不上,(当时用中国科学技术大学的软件源,python3-pip下载有问题),换成ubuntu官网成功下载。
如果系统已经安装过了pip,就不需要这一步了。
然后通过:
pip install pyserial //python2
pip3 install pyserial //python3
可以从pyserial下载这里去获取源码进行熟悉和学习。
4 PYCHARM 里面的no module name serial错误
错误原因在于:==interpreter的选择==
安装目录下的python,其模块只有一个setuptools,所以找不到serial
ANACONDA下的python.exe里面包含了多个模块,所以应该将interpreter改为该目录下的python.exe
5 TypeError: ‘bool’ object is not callable
因为 isOpen是属性所以有如下做法
def isOpen(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
不是方法,将sOpen()括号去掉,完美解决!