Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何仅在新样本可用时读取线程缓冲区?_Python_Serial Port_Sampling - Fatal编程技术网

Python 如何仅在新样本可用时读取线程缓冲区?

Python 如何仅在新样本可用时读取线程缓冲区?,python,serial-port,sampling,Python,Serial Port,Sampling,以下代码应将串行接口读取到日志文件中。代码可能会以非常高的采样率记录(是的,串行同步丢失)。但由于该代码比串行设备的数据速率快(应该是这样),因此它读取重复点 澄清编辑:正如我们从源代码中看到的,线程正在读取串行端口并将其写入缓冲区rawData。另一个函数getSerialData()应该将rawData解压为4个变量并写入日志文件。但由于它比串行设备的数据速率快,所以即使没有新的读数可用,它也会读取rawData。我想使函数getSerialData()unpackrawData仅在线程将新

以下代码应将串行接口读取到日志文件中。代码可能会以非常高的采样率记录(是的,串行同步丢失)。但由于该代码比串行设备的数据速率快(应该是这样),因此它读取重复点

澄清编辑:正如我们从源代码中看到的,线程正在读取串行端口并将其写入缓冲区
rawData
。另一个函数
getSerialData()
应该将
rawData
解压为4个变量并写入日志文件。但由于它比串行设备的数据速率快,所以即使没有新的读数可用,它也会读取
rawData
。我想使函数
getSerialData()
unpack
rawData
仅在线程将新数据写入
rawData
时使用

我想确保代码只从串行设备获取最后一个样本。这可以通过将新样本与以前的样本进行比较来实现,但速度太慢了

有许多示例说明了如何实现这一点,但不适用于原始连接


您似乎误解了串行端口的工作原理。串行端口只能读取发送给它的数据,并且该数据只提供给应用程序一次(假设您的操作系统工作正常)。串行端口没有“采样”(以您认为的方式)。如果您正在“读取”重复数据,则应怀疑程序错误或生成/发送该数据的源。如果复制的数据实际上是有效的,那么您的程序必须处理它。顺便说一句,你过度使用了“it”这个词,你不清楚你指的是什么。对不起,英语不是我的第一语言。轮询(或采样)在这里不是正确的术语。我修改了我的问题。
#!/usr/bin/env python
from threading import Thread
import serial
import time
import collections
import struct
import copy
import pandas as pd
import numpy as np
import sys
import os
import h5py


class serialPlot:
    def __init__(self, serialPort, serialBaud, bufferLength, dataNumBytes, numVal):
        self.port = serialPort
        self.baud = serialBaud
        #self.plotMaxLength = bufferLength
        self.dataNumBytes = dataNumBytes  # number of bytes for single value
        self.numVal = numVal
        self.rawData = bytearray(numVal * dataNumBytes)
        self.data = []
        for i in range(numVal):   # give an array for each type of data and store them in a list
            self.data.append(collections.deque(
                [0] * bufferLength, maxlen=bufferLength))
        self.isRun = True
        self.isReceiving = False
        self.thread = None
        self.plotTimer = 0
        self.previousTimer = 0

        print('Trying to connect to: ' + str(serialPort) +
              ' at ' + str(serialBaud) + ' BAUD.')
        try:
            self.serialConnection = serial.Serial(
                serialPort, serialBaud, timeout=4)
            print('Connected to ' + str(serialPort) +
                  ' at ' + str(serialBaud) + ' BAUD.')
        except:
            print("Failed to connect with " + str(serialPort) +
                  ' at ' + str(serialBaud) + ' BAUD.')

    def readSerialStart(self):
        # start thread if not started yet
        if self.thread == None:
            self.thread = Thread(target=self.retrieveData)
            self.thread.start()
            # Block till we start receiving values
            while self.isReceiving != True:
                time.sleep(0.01)

    def getSerialData(self, bufferLength):
        hdf5Buffer = [[0 for x in range(self.numVal)] for y in range(
            bufferLength)]  # Create array to hold data
        # Calculate time delta between data points
        currentTimer = time.perf_counter_ns()
        # the first reading will be erroneous
        self.plotTimer = int((currentTimer - self.previousTimer) / 1000)
        self.previousTimer = currentTimer

        for e in range(bufferLength):
            privateCopy = copy.deepcopy(self.rawData[:])
            for i in range(self.numVal):
                bytedata = privateCopy[(i * self.dataNumBytes):
                                       (self.dataNumBytes + i * self.dataNumBytes)]
                value, = struct.unpack('f', bytedata)
                # get the latest data point and append it to our array
                self.data[i] = value
            for f in range(self.numVal):
                hdf5Buffer[e][f] = self.data[f]
            hdf5Buffer[e].insert(0, self.plotTimer)
        return hdf5Buffer

    def retrieveData(self):    # retrieve data
        time.sleep(0.1)  # give some buffer time for retrieving data
        self.serialConnection.reset_input_buffer()  # flush input buffer
        while (self.isRun):
            # read n bytes into array (rawData) and return num of bytes read
            self.serialConnection.readinto(self.rawData)
            self.isReceiving = True

    def close(self):
        self.isRun = False
        self.thread.join()
        self.serialConnection.close()
        print('Disconnected...')


def main():
    time.sleep(0.1)
    portName = 'COM15'
    baudRate = 230400
    bufferLength = 10     # number of samples buffered before saving it to HDF5
    dataNumBytes = 4      # number of bytes for single data point
    numData = 4     # number of data points in single sample
    rawData = bytearray(numData * dataNumBytes)

    s = serialPlot(portName, baudRate, bufferLength,
                   dataNumBytes, numData)   # initializes all required variables
    # Starts background thread
    s.readSerialStart()

    dataArray = s.getSerialData(bufferLength)
    while(True):
        # Prepare data to write
        dataArray = s.getSerialData(bufferLength)
        '''
        PROCEDURE FOR WRITING LATEST DATA INTO HDF5
        '''
        # TESTING
        print(str(dataArray[-1]), end='                                 \r')

    s.close()


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('Interrupted')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)