内容如题,研究了1天了,在串口控制不同类型的机械臂时碰到命令发出后,等待机械臂对指令、状态的反馈问题,直接上代码,供参考:
# -*- coding: utf-8 -*-
"""
Created on Sun Jul 11 10:19:11 2021
@author: JamesFei
"""
import serial
import time
import threading
import logging
class serial_client:
ser=None #串口句柄
exval={
"com":"COM10",
"baud":115200,
"port":6666,
"host":"localhost"
}
recv_data=None
def __init__(self, **kwargs):
"""
初始化类:
串口:com="COM7"
波特率:baud=115200
web端口:port=6666
主机地址:host="localhost"
"""
self.mathods=dir(self)
for k,v in kwargs.items():
if k in self.exval.keys():
self.exval[k]=v
if self.arm_initialize():
print("com started")
#print(self.exval["com"])
def arm_initialize(self):
try:
self.ser=serial.Serial(self.exval["com"],self.exval["baud"],timeout=0.5)#winsows系统使用com1口连接串行口
if self.ser:
return True
else:
return False
except Exception as e:
return False
logging.error("机械手com---异常---:",e)
def sendHex_and_receive(self,sendstr,maxt,**kwargs):
"""
sendstr:发送的16进制字符串'10'=b'\x10',
maxt:最大接收时间,超时强制返回接收
onreceive:异步回调自定义函数,自定义返回
stopbyte:接收到指定byte,v,如'\n'即返回接收
stopword:接收到指定字符,v,如'stop',即返回接收
stopline:接收到指定行,v,如'EXIT'即返回接收
"""
d=bytes.fromhex(sendstr)
# 串口发送数据
result=self.ser.write(d)
#print('send result:',result)
# 停止、等待数据,这一步非常关键。timeout压根没用
#time.sleep(t)
data=b''
if kwargs:
for k,v in kwargs.items():
if k=="onreceive":
try:
self.recv_data=b''
print("start receive job!")
t0 = threading.Thread(target=v,args=(self,),name="serial_receive")
t0.setDaemon(True) # 随着主线程结束而结束
t0.start()
#t0.join()
return True,t0
except Exception as e:
return False,b''
logging.error("串口接收---异常---:",e)
elif k=="stopbyte":
ti=0
dt=0.1
if type(v)!=type(b''):
v=b'\n'
while ti<maxt:
count=self.ser.inWaiting()
while count > 0:
byte=self.ser.read(1)
data += byte
if byte==v:
return True,data
count-=1
time.sleep(dt)
ti+=dt
print("on receive...",ti)
if len(data)>0:
return True,data
else:
return False,b''
elif k=="stopword":
tword=b''
ti=0
dt=0.1
if type(v)!=type(b'') :
if type(v)==type(''):
v=v.encode("utf-8")
logging.warning("wrong type, stopword must be b''!")
else:
logging.error("wrong type, stopword must be b''!")
return False,b''
while ti<maxt:
count=self.ser.inWaiting()
while count > 0:
byte=self.ser.read(1)
data += byte
if byte==b' 'or byte==b'\n' or byte==b'\r' :
if tword==v:
return True,data
else:
tword=b''
else:
tword+=byte
count-=1
time.sleep(dt)
ti+=dt
print("on receive...",ti)
if len(data)>0:
print("receive time out !")
return True,data
else:
return False,b''
elif k=="stopline":
twords=b''
ti=0
dt=0.1
if type(v)!=type(b'') :
if type(v)==type(''):
v=v.encode("utf-8")
logging.warning("wrong type, stopword must be b''!")
else:
logging.error("wrong type, stopword must be b''!")
return False,b''
while ti<maxt:
count=self.ser.inWaiting()
while count > 0:
byte=self.ser.read(1)
data += byte
if byte==b'\n' or byte==b'\r' :
if twords==v:
return True,data
else:
twords=b''
else:
twords+=byte
count-=1
time.sleep(dt)
ti+=dt
print("on receive...",ti)
if len(data)>0:
print("receive time out !")
return True,data
else:
return False,b''
else:
# 数据的接收超时返回接收
ti=0
dt=0.1
while ti<maxt:
count=self.ser.inWaiting()
if count > 0:
data += self.ser.read(count)
ti+=dt
time.sleep(dt)
print("on receive...",ti)
if len(data)>0:
return True,data
else:
return False,b''
def on_recv(cl):
data=b''
re_outime=5
ti=0
dt=1
while ti<re_outime:
count=cl.ser.inWaiting()
if count > 0:
data += cl.ser.read(count)
ti+=dt
print("on_recv...",ti)
time.sleep(dt)
cl.recv_data=data
if __name__ == "__main__":
cl=serial_client(com="COM10")
#异步接收
res,t0=cl.sendHex_and_receive('10',5,onreceive=on_recv)
print("do something other!")
t0.join()
print("receive data",cl.recv_data)
"""
#接收到指定字符,v,如'stop',即返回接收
print("receive data:",cl.sendHex_and_receive("10",5,stopword='stop'))
#接收到指定byte,v,如'\n'即返回接收
print("receive data:",cl.sendHex_and_receive("10",5,stopbyte='\n'))
#接收到指定行,v,如'end of line'即返回接收
print("receive data:",cl.sendHex_and_receive("10",10,stopline='End of line !'))
"""
cl.ser.close()
print("closed!")