
一、说明
pyserial封装了python环境下对串口的访问,其兼容各种平台,并有统一的 *** 作接口。通过python属性访问串口设置,并可对串口的各种配置参数(如串口名,波特率、停止校验位、流控、超时等等)做修改,再进行串口通信的类与接口封装后,非常方便地被调用和移植。
二、模块安装
pip insatll pyserial
三、初始化与参数说明
import serial
ser = serial.Serial('COM3', 115200, timeout=0.5, ....................)
下面看看 serial.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口连接串行口
五、串口属性
ser.name #串口名称
ser.port #端口号
ser.baudrate #波特率
ser.bytesize #字节大小
ser.parity #校验位N-无校验,E-偶校验,O-奇校验
ser.stopbits #停止位
ser.timeout #读超时设置
ser.writeTimeout #写超时
ser.xonxoff #软件流控
ser.rtscts #硬件流控
ser.dsrdtr #硬件流控
ser.interCharTimeout #字符间隔超时
六、串口常用方法
isOpen():查看端口是否被打开。
open() :打开端口‘。
close():关闭端口。
read(size=1):从端口读字节数据。默认1个字节。
read_all():从端口接收全部数据。
write(data):向端口写数据。
readline():读一行数据。
readlines():读多行数据。
in_waiting():返回输入缓存中的字节数。
out_waiting():返回输出缓存中的字节数。
flush():等待所有数据写出。
flushInput():丢弃接收缓存中的所有数据。
flushOutput():终止当前写 *** 作,并丢弃发送缓存中的数据。
sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE
setBreak(level=True):根据level设置break条件。
setRTS(level=True):设置请求发送(RTS)的控制信号
setDTR(level=True):设置数据终端准备就绪的控制信号
七、类与接口封装
import time
import serial
import serial.tools.list_ports
# 串口 *** 作类
class serialCommunication(object):
def __init__(self, port, bps, timeout):# 可配置更多参数
port_list =self.show_usable_com()
if len(port_list) >0:
if portnot in port_list:
self.port = port_list[0]
else:
self.port = port
else:
print("no usable serial, please plugin your serial board")
return
self.bps = bps
self.timeout = timeout
try:
# 初始化串口,并得到串口对象,根据需要可拓展更多参数
self.ser = serial.Serial(self.port, self.bps, 8, 'N', 1, timeout=self.timeout, write_timeout=self.timeout)
except Exception as e:# 抛出异常
print("Exception={}".format(e))
# 显示可用串口列表
@staticmethod
def show_usable_com():
serialport_list = []
portInfo_list =list(serial.tools.list_ports.comports())
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_list.append(plist[0])
print(serialport_list)
return serialport_list
# 输出串口基本信息
def serial_infor(self):
print(self.ser.name)# 设备名字
print(self.ser.port)# 读或者写端口
print(self.ser.baudrate)# 波特率
print(self.ser.bytesize)# 字节大小
print(self.ser.parity)# 校验位
print(self.ser.stopbits)# 停止位
print(self.ser.timeout)# 读超时设置
print(self.ser.writeTimeout)# 写超时
print(self.ser.xonxoff)# 软件流控
print(self.ser.rtscts)# 软件流控
print(self.ser.dsrdtr)# 硬件流控
print(self.ser.interCharTimeout)# 字符间隔超时
# 打开串口
def serial_open(self):
try:
if not self.ser.isOpen():
self.ser.open()
except Exception as e:# 抛出异常
print("serial_open Exception={}".format(e))
self.ser.close()
# 读取指定大小的数据
# 从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。
def serial_read_with_size(self, size):
try:
self.serial_open()
return self.ser.read(size).decode("utf-8")
except Exception as e:
print("serial_read_all Exception={}".format(e))
self.ser.close()
# 读取当前串口缓存中的所有数据
def serial_read_data(self):
try:
self.serial_open()
datalen =self.ser.inWaiting()
if datalen ==0:
return None
return self.ser.read(datalen).decode("utf-8")
except Exception as e:
print("serial_read_data Exception={}".format(e))
self.ser.close()
# 读串口全部数据,注意timeout的设置
# 在设定的timeout时间范围内,如果读取的字节数据是有效的(就是非空)那就直接返回,
# 否则一直会等到设定的timeout时间并返回这段时间所读的全部字节数据。
def serial_read_all(self):
try:
self.serial_open()
return self.ser.read_all().decode("utf-8")
except Exception as e:
print("serial_read_all Exception={}".format(e))
self.ser.close()
# 读一行数据
# 使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。
# 如果没有超时,readline会报异常。
def serial_read_line(self):
try:
self.serial_open()
return self.ser.readline().decode("utf-8")
except Exception as e:
print("serial_read_line Exception={}".format(e))
self.ser.close()
# 读多行数据,返回行列表
def serial_read_lines(self):
try:
self.serial_open()
return self.ser.readlines().decode("utf-8")
except Exception as e:
print("serial_read_lines Exception={}".format(e))
self.ser.close()
# 写数据
def serial_write_data(self, data):
try:
self.serial_open()
self.ser.flushOutput()
data_len =self.ser.write(data.encode('utf-8'))
return data_len
except Exception as e:
print("serial_write_data Exception={}".format(e))
return 0
# 写行数据,注意参数差异
def serial_write_lines(self, lines):
self.ser.writelines(lines)
# 清除串口缓存
def serial_clean(self):
try:
if self.ser.isOpen():
self.ser.flush()
except Exception as e:
print("serial_clean Exception={}".format(e))
# 关闭串口
def serial_close(self):
try:
if self.ser.isOpen():
self.ser.close()
except Exception as e:
print("serial_clean Exception={}".format(e))
if __name__ =='__main__':
testSerial = serialCommunication("COM10", 1500000, 0.5)
testSerial.serial_open()
testSerial.serial_infor()
testSerial.serial_write_data("ifconfig eth0\n")
time.sleep(0.1)
data = testSerial.serial_read_all()
print(data)
testSerial.serial_close()
八、其他
1)ser.VERSION表示pyserial版本 另外,ser.name表示设备名称
2)端口设置可以被读入字典,也可从字典加载设置:
getSettingDict():返回当前串口设置的字典
applySettingDict(d):应用字典到串口设置
3) Readline()是读一行,以/n结束,要是没有/n就一直读,阻塞。注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。
4)serial.read_all 与 serial.read_all()区别
serial.read_all:读取串口所有的参数信息
serial.read_all():超时时间内从串口读取的所有数据
5) 异常信息
exception serial.SerialException
exception serial.SerialTimeoutException
可以,使用comm,jarclass SerialExample {
public static void main(String[] args) {
//TO DO: Add your JAVA codes here
long curTime = System.currentTimeMillis()
long serialtime = 8000
boolean state = true
SerialBean SB = new SerialBean(2)//设置端口号2
String Msg = "AD 01 0D"//发送命令
SB.Initialize(9600)//设置波率
SB.WritePort(Msg)//发送命令
/*for (int i = 5i <10i++) {
System.out.println( SB.ReadPort(3))//设置读取个数
}
*/
String readdata = SB.ReadPort("0D",4000)//读取以OD结束的数据,4000ms没有数据就返回空
if (readdata.length() >0) { //System.out.println(readdata.length())//如果有读到数据
System.out.println(readdata)//如果有读到数据
}
while (readdata.length() <1 &&state) {//如果没有读到数据
readdata = SB.ReadPort("0D",4000)
System.out.println(readdata)
if (System.currentTimeMillis() - curTime >serialtime) {
state = false//设置读取错误超时
}
System.out.println("readdaa:" + state)
System.out.println(System.currentTimeMillis() - curTime)
}
if (!state) {
System.out.println("数据读取超时")
}
SB.ClosePort()//关闭连接
}
}
public class SerialBuffer {
Convents cv = new Convents()
private String Content = ""
private String CurrentMsg, TempContent
private boolean available = false
private int LengthNeeded = 1
String str = ""
byte b
/**
*
* This function returns a string with a certain length from the incoming
* messages.
*
* @param Length The length of the string to be returned.
*
*/
public synchronized String GetMsg(int Length) {
LengthNeeded = Length
long timeout=2000
long curtime=System.currentTimeMillis()
notifyAll()
if (LengthNeeded >Content.length()) {
available = false
while (available == false) {
try {
if(System.currentTimeMillis()-curtime<timeout) wait()
} catch (InterruptedException e) {
}
}
}
CurrentMsg = Content.substring(0, LengthNeeded)
TempContent = Content.substring(LengthNeeded)
Content = TempContent
LengthNeeded = 1
notifyAll()
return CurrentMsg
}
public synchronized String GetMsg(String endstring,long timeout) {
LengthNeeded =Content.indexOf(endstring)
notifyAll()
if (LengthNeeded <0) {
available = false
while (available == false) {
try {
wait(timeout)
available=true
} catch (InterruptedException e) {
}
}
return ""
}
if (LengthNeeded >0) {
CurrentMsg = Content.substring(0, LengthNeeded+endstring.length())
TempContent = Content.substring(LengthNeeded+endstring.length())
Content = TempContent
}
LengthNeeded = -1
notifyAll()
return CurrentMsg
}
public synchronized void PutChar(int c) {
Content = Content.concat(cv.byteToHexString(c))
if (LengthNeeded <Content.length() &&Content.length() >0) {
available = true
}
notifyAll()
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package common.serial
/**
*
* @author Jason
*/
import java.io.*
import java.util.*
import javax.comm.*
import common.code.Convents
public class SerialBean {
Convents cv=new Convents()
String PortName = ""
CommPortIdentifier portId = null
SerialPort serialPort = null
OutputStream out
InputStream in
SerialBuffer SB
ReadSerial RT
int rate=9600
String endstring =""
long timeout=2000
public SerialBean(int PortID) {
PortName = "COM" + PortID
}
public int Initialize(int rate) {
int InitSuccess = 1
int InitFail = -1
try {
portId = CommPortIdentifier.getPortIdentifier(PortName)
try {
serialPort = (SerialPort) portId.open("Serial_Communication", 2000)
} catch (PortInUseException e) {
return InitFail
}
//Use InputStream in to read from the serial port, and OutputStream
//out to write to the serial port.
try {
in = serialPort.getInputStream()
out = serialPort.getOutputStream()
} catch (IOException e) {
return InitFail
}
//Initialize the communication parameters to 9600, 8, 1, none.
try {
serialPort.setSerialPortParams(rate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE)
} catch (UnsupportedCommOperationException e) {
return InitFail
}
} catch (NoSuchPortException e) {
return InitFail
}
SB = new SerialBuffer()
RT = new ReadSerial(SB, in)
RT.start()
return InitSuccess
}
public String ReadPort(int Length) {
String Msg
Msg = SB.GetMsg(Length)
return Msg
}
public String ReadPort(String endstring,long timeout) {
String Msg
Msg = SB.GetMsg(endstring,timeout)
return Msg
}
public void WritePort(String Msg) {
try {
out.write(cv.hexStringToByte(Msg))
} catch (IOException e) {
}
}
public void ClosePort() {
serialPort.close()
}
}
package common.serial
import java.io.*
public class ReadSerial extends Thread {
private SerialBuffer ComBuffer
private InputStream ComPort
char[] ch
public ReadSerial(SerialBuffer SB, InputStream Port) {
ComBuffer = SB
ComPort = Port
}
@Override
public void run() {
int c
try {
while (true) {
c=ComPort.read()
ComBuffer.PutChar(c)
}
} catch (IOException e) {
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package common.serial
/**
*
* @author Administrator
*/
public class PortOpreate {
private String sendtxt=""
private String recivetxt=""
private int comid = 1
private int comrate = 9600
private int timeout = 4000
private long waittime = 13000
private String endtxt = "0D"
private boolean pstate=false
private String massage=""
public void PortOpreate(boolean hasreturn) {
long curTime = System.currentTimeMillis()
long serialtime = getWaittime()
boolean state = true
int t=0
SerialBean SB = new SerialBean(getComid())//设置端口号2
t=SB.Initialize(getComrate())//设置波率
if(t>0){
SB.WritePort(getSendtxt())//发送命令
if (hasreturn) {
String readdata = SB.ReadPort(getEndtxt(), getTimeout())//读取以OD结束的数据,4000ms没有数据就返回空
if (readdata.length() >0) { //System.out.println(readdata.length())//如果有读到数据
System.out.println(readdata)//如果有读到数据
}
while (readdata.length() <1 &&state) {//如果没有读到数据
readdata = SB.ReadPort(getEndtxt(), getTimeout())
System.out.println(readdata)
if (System.currentTimeMillis() - curTime >serialtime) {
state = false//设置读取错误超时
}
System.out.println("readdaa:" + state)
System.out.println(System.currentTimeMillis() - curTime)
}
if (!state) {
System.out.println("数据读取超时")
setMassage("数据读取超时")
}
setRecivetxt(readdata)
setPstate(state)
}
SB.ClosePort()//关闭连接
}else{
System.out.println("端口号出现错误")
setMassage("端口号出现错误")
}
}
/**
* @return the sendtxt
*/
public String getSendtxt() {
return sendtxt
}
/**
* @param sendtxt the sendtxt to set
*/
public void setSendtxt(String sendtxt) {
this.sendtxt = sendtxt
}
/**
* @return the recivetxt
*/
public String getRecivetxt() {
return recivetxt
}
/**
* @param recivetxt the recivetxt to set
*/
public void setRecivetxt(String recivetxt) {
this.recivetxt = recivetxt
}
/**
* @return the comid
*/
public int getComid() {
return comid
}
public void setComid(int comid) {
this.comid = comid
}
public int getComrate() {
return comrate
}
public void setComrate(int comrate) {
this.comrate = comrate
}
public int getTimeout() {
return timeout
}
public void setTimeout(int timeout) {
this.timeout = timeout
}
public long getWaittime() {
return waittime
}
public void setWaittime(long waittime) {
this.waittime = waittime
}
public String getEndtxt() {
return endtxt
}
public void setEndtxt(String endtxt) {
this.endtxt = endtxt
}
public boolean isPstate() {
return pstate
}
public void setPstate(boolean pstate) {
this.pstate = pstate
}
public String getMassage() {
return massage
}
public void setMassage(String massage) {
this.massage = massage
}
}
package common.serial
import java.io.*
import javax.servlet.*
import javax.servlet.http.*
public class PortOperatorServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/htmlcharset=UTF-8")
PrintWriter out = response.getWriter()
try {
long curTime = System.currentTimeMillis()
long serialtime = 8000
boolean state = true
String Msg = "AD 01 0D"//发送命令
SerialBean SB = new SerialBean(10)//设置端口号2
SB.Initialize(9600)//设置波率
SB.WritePort(Msg)//发送命令
/*for (int i = 5i <10i++) {
System.out.println( SB.ReadPort(3))//设置读取个数
}
*/
String readdata = SB.ReadPort("0D",4000)//读取以OD结束的数据
if (readdata.length() >0) { //System.out.println(readdata.length())//如果有读到数据
System.out.println(readdata)//如果有读到数据
}
while (readdata.length() <1 &&state) {//如果没有读到数据
readdata = SB.ReadPort("0D",4000)
System.out.println(readdata)
out.println(readdata)
if (System.currentTimeMillis() - curTime >serialtime) {
state = false//设置读取错误超时
}
System.out.println("readdaa:" + state)
System.out.println(System.currentTimeMillis() - curTime)
}
if (!state) {
System.out.println("数据读取超时")
out.println("数据读取超时")
}
SB.ClosePort()//关闭连接
} finally {
out.close()
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response)
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response)
}
public String getServletInfo() {
return "Short description"
}
}
package common.code
public final class Convents {
public final static char[] BToA = "0123456789abcdef".toCharArray()
/**
* 把16进制字符串转换成字节数组A1 01 0D
* @param hex
* @return
*/
public byte[] hexStringToByte(String hex) {
String str[] = hex.split(" ")
int len = str.length
byte[] result = new byte[len]
char[] achar = hex.toCharArray()
for (int i = 0i <leni++) {
result[i] = (byte) (toByte(str[i].charAt(0)) * 16 + toByte(str[i].charAt(1)))
}
return result
}
private static byte toByte(char c) {
byte b = (byte) ("0123456789ABCDEF".indexOf(c))
return b
}
/**
* 把字节数组转换成16进制字符串
* @param bArray
* @return
*/
public String byteToHexString(int b){
String st=""
st=Integer.toHexString(b)
if (st.length() <2) {
st="0"+Integer.toHexString(b).toUpperCase()+" "
} else {
st=Integer.toHexString(b).toUpperCase()+" "
}
return st
}
public String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length)
String sTemp
for (int i = 0i <bArray.lengthi++) {
sTemp = Integer.toHexString(bArray[i]).toUpperCase()
}
return sb.toString()
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)