我有一个生成ASCII数据的数据采集系统。数据通过USB采用串行通信协议(虚拟串行,作为盒子声称的制造商)获得。我有一个Python程序/脚本,它使用PySerial和PySide GUI绘制采集的数据并将其保存到HDF5文件。我有一个非常奇怪的问题,我不知道如何解决它。我希望你们能帮助我,并就如何调试这个问题提供建议。
问题如何显示:问题是,如果我使用像Eltima Data Logger这样的软件,获取的数据看起来很好。但是,如果我使用我的软件(使用PySerial),似乎缺少一些数据块。奇怪的是,丢失的数据块与读取方法不兼容。我逐行阅读,数据中缺少的是100字节或64字节块,有时包括换行!我知道丢失了什么,因为设备在将数据发送到计算机之前将数据缓冲在SD卡上。这使我相信很长一段时间硬件都有问题,直到我使用这个软件Eltima,它表明它正在获取数据。
以下是Eltima的配置:
我的配置:
这一切都在QThread
。
以下是我在我的代码中使用的方法(通过一些小的抛光使其可重复使用):
self.obj = serial.Serial()
self.obj.port = instrumentName
self.obj.baudrate = 115200
self.obj.bytesize = serial.EIGHTBITS
self.obj.parity = serial.PARITY_ODD
self.obj.stopbits = serial.STOPBITS_ONE
self.obj.timeout = 1
self.obj.xonxoff = False
self.obj.rtscts = False
self.obj.dsrdtr = False
self.obj.writeTimeout = 2
self.obj.open()
我用来读取的算法是,我有一个寻找特定标题行的循环,一旦找到,它就会一直将行推入缓冲区,直到找到特定的结束行;并且最终处理这些数据。以下是我的代码:
try:
# keep reading until a header line is found that indicates the beginning of a batch of data
while not self.stopped:
self.line = self.readLine()
self.writeDumpFileLine(self.line)
if self.line == DataBatch.d_startString:
print("Acquiring batch, line by line...")
self.dataStrQueue.append(self.line)
break
# after the header line, keep reading until a specific string is found
while not self.stopped:
self.line = self.readLine()
self.writeDumpFileLine(self.line)
self.dataStrQueue.append(self.line)
if self.line == DataBatch.d_endString:
break
except Exception as e1:
print("Exception while trying to read. Error: " + str(e1))
self.writeDumpFileLine()
从设备获取该行并在处理之前直接将其转储到文件中以进行调试。这些转储文件已经确认了丢失块的问题。
self.readLine()
的实施非常简单:
def readLine(self):
lineData = decodeString(self.obj.readline())
lineData = lineData.replace(acquisitionEndlineChar, "")
return lineData
我想指出,我还有一个实现可以提取数千行并根据inWaiting()
解析它们,这个方法也有同样的问题!
现在我开始怀疑:它是PySerial吗?还有什么可能导致这个问题?
非常感谢您的努力。如果您需要任何其他信息,请询问!
更新:
实际上我刚刚确认可以通过让系统稍微滞后来重现问题。我使用PyCharm对该软件进行编程,当程序运行时,如果按Ctrl+S
进行保存,PyCharm的GUI会冻结一点(因此它的终端)。多次重复会以可重复的方式导致问题!!!!