我有套接字将Prologixx GPIB查询为ETH0。我得到了 friend 执行此操作的代码。在Win 10中,套接字随机获得超时,有时计算机似乎关闭了连接。我想认识到,套接字有问题,无法再次启动它。
有两条消息:
这只会产生无效的结果,我正在检查结果是否合理。也只是暂时的
这是永久的。该程序像以前一样运行,只是死了没有得到新的结果。测试新结果很困难,因为它们是温度,而且我会稳定一段时间。
import socket
from numpy import nan
from time import sleep
class PrologixGPIBEthernet:
PORT = 1234
def __init__(self, host, timeout=1):
self.host = host
self.timeout = timeout
self.socket = socket.socket(socket.AF_INET,
socket.SOCK_STREAM,
socket.IPPROTO_TCP)
self.socket.settimeout(self.timeout)
def connect(self):
self.socket.connect((self.host, self.PORT))
self._setup()
def close(self):
self.socket.close()
def select(self, addr):
self._send('++addr %i' % int(addr))
def write(self, cmd):
self._send(cmd)
def read(self, num_bytes=1024):
self._send('++read eoi')
return self._recv(num_bytes)
def query(self, cmd, buffer_size=1024*1024):
self.write(cmd)
return self.read(buffer_size)
def _send(self, value):
encoded_value = ('%s\n' % value).encode('ascii')
try:
s = self.socket.send(encoded_value)
except Exception as e:
print('_send', e)
def _recv(self, byte_num):
try:
value = self.socket.recv(byte_num).decode('ascii')
except Exception as e:
print (',_recv', e)
value = 'ERROR'
return value
def _setup(self):
# set device to CONTROLLER mode
self._send('++mode 1')
# disable read after write
self._send('++auto 1')
# set GPIB timeout
# self._send('++read_tmo_ms %i' % int(self.timeout*1e3))
# do not require CR or LF appended to GPIB data
# self._send('++eos 3')
最佳答案
我不确定错误消息,但这听起来与我的经验相似。
我将prologix设备称为“解释器”,因为它无法与SCPI无缝配合使用。
例如,对于普通的SCPI仪器,我可以要求设备进行测量,然后可以要求读取该测量值,完成后它会给我一个响应。只要超时时间长,它就会挂起,直到缓冲区被填满,然后返回结果。 (注意:这不是您应该采取的方式。使用轮询或中断是实现设备查询的好方法。)
prologix设备可能会与时间混淆。如果我尝试通过发送读取测量值的命令来复制SCPI的工作方式(如上所述),但是这次进行该测量并将其放入缓冲区需要5秒钟。在5秒钟过去之前,我问prologix结果是什么,它将尝试查找结果,但是缓冲区为空,因此没有任何返回值。 5秒钟后,缓冲区被填满,但是prologix不知道这一点,并停留在此状态。这是您获得套接字超时的地方。
解决此问题的正确方法是使用prologix中的轮询功能在缓冲区有结果时进行计算。但这不是我要做的事情。
技巧1)确保有足够大的延迟,但是您并不总是知道需要多长时间,并且会增加脚本延迟。
哈克2)故意强制您的脚本超时并重试。这就是我已经实现的。我知道这很丑陋,但是当我试图找出问题所在时,这是一个快速的技巧。
def read_timeout_poll(self, repeat):
# start_time = time.time() # Used if you want to see how long it takes
mesg = ""
for _ in range(repeat):
try:
sendData = "++read\n"
self.prolSock.send(sendData.encode())
mesg = self.prolSock.recv(self.BUFSIZ)
break
except socket.timeout:
time.sleep(1)
except socket.error as e:
return "Python Error sending data: " + str(e)
break
# print(f"read poll operation took {:.0f} seconds".format(time.time() - start_time)) # This is a guide to see how long it takes to get a result in the buffer
return mesg