0

我无法让我的代码按照我想要的方式运行。该代码应该从传感器获取数据并将其存储在带有时间戳的文件中。使用其中一个传感器值控制直线电机。我使用带有 nidaqmx 包的 NI cDAQ 9184 和 Python。出现的第一个问题是数据传输延迟。结果,发动机的控制过程非常缓慢。我创建了一个 nidaqmx.task 并在循环中通过 task.read() 请求当前传感器值。此方法有几秒钟的延迟。在我看来,cDAQ 和 task.read() 方法不断地记录数据,缓存它并根据请求弹出缓存的数据(如在队列中)。但是,我希望仅在请求时查看值,并且没有要存储的数据,因为它将保存到 csv 文件中。如果我每次调用任务方法时都重新创建任务,我会得到适当且非延迟的值。但是,创建一个新任务大约需要 20 毫秒,在我看来,这不是我的请求的预期解决方案。当然,这也会减慢数据记录的速度,我想避免这种情况。

请参阅以下两个代码片段,它们描述了我为 DataAcquisition 编写的过程: 

def DAQ_Monitoring(c,condition,ExChange,sample_rate):        

with nidaqmx.Task() as task:
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai0")
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai1")
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai2")
    task.timing.cfg_samp_clk_timing(1000)
    
    sample_RateSeconds = (sample_rate)*(10**(-3))    #convert sampleRate from [ms] to [s]
    startTime = datetime.now().timestamp()
    oldTime = 0
    while condition.value == 3:
        while ((datetime.now().timestamp()-startTime)-oldTime) < sample_RateSeconds:
            pass
        timeData = datetime.now().timestamp()-startTime
        oldTime = timeData
        pressureIn,pressureVessel,volumeFlow = task.read()
        position, force = pullData(c)
        accousticEmission1 = 999
        vibration = 999
        pressureIn = (1000000/16)*(pressureIn-0.004)
        pressureVessel = (200000/16)*(pressureVessel-0.004)
        volumeFlow = 3250*volumeFlow            
        ExChange[:] = [timeData,pressureIn,pressureVessel,volumeFlow,accousticEmission1,vibration,position,force]
    

def DAQ_Monitoring(c,condition,ExChange,sample_rate):        
    
sample_RateSeconds = (sample_rate)*(10**(-3))    #convert sampleRate from [ms] to [s] 
startTime = datetime.now().timestamp()
oldTime = 0
while condition.value == 3:
    while ((datetime.now().timestamp()-startTime)-oldTime) < sample_RateSeconds:
        pass
    timeData = datetime.now().timestamp()-startTime
    oldTime = timeData
    with nidaqmx.Task() as task:
        task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai0")
        task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai1")
        task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai2")
        task.timing.cfg_samp_clk_timing(1000)
        pressureIn,pressureVessel,volumeFlow = task.read()
    position, force = pullData(c)
    accousticEmission1 = 999
    vibration = 999
    pressureIn = (1000000/16)*(pressureIn-0.004)
    pressureVessel = (200000/16)*(pressureVessel-0.004)
    volumeFlow = 3250*volumeFlow            
    ExChange[:] = [timeData,pressureIn,pressureVessel,volumeFlow,accousticEmission1,vibration,position,force]

我已经阅读了许多论坛帖子并试图挖掘 nidaqmx 的文档。我遇到了 Stream 方法。我对此发现很少,但我也尝试实现此方法。传感器值可以正确无延迟地传输。但是这里缓冲区溢出,根据采样率,迟早会弹出以下错误:

(基础)PS C:\Users\Jetting\Desktop\Robert\SCT_TryOut_DifferentAcqTypes> python SCT_18.02.2021_v1.0_stream.py SCT_18.02.2021_v1.0_stream.py:290:用户警告:尝试设置相同的底部 == 顶部 == 0.0导致奇异的变换;自动展开。ax.set_ylim(np.amin(dataPlot),np.amax(dataPlot)) SCT_18.02.2021_v1.0_stream.py:291:用户警告:尝试设置相同的左 == 右 == 0.0 会导致奇异变换;自动展开。ax.set_xlim(np.amin(timePlot),np.amax(timePlot)) SCT_18.02.2021_v1.0_stream.py:290:用户警告:尝试设置相同的底部 == 顶部 == 0.16962570625000006 导致奇异变换;自动展开。ax.set_ylim(np.amin(dataPlot),np.amax(dataPlot)) SCT_18.02.2021_v1.0_stream.py:291:用户警告:尝试设置相同的左侧 == 右侧 == 1。4031758308410645 导致奇异变换;自动展开。ax.set_xlim(np.amin(timePlot),np.amax(timePlot)) 进程 Process-1:回溯(最近一次调用最后一次):文件“C:\Users\Jetting\anaconda3\lib\multiprocessing\process.py” ,第 315 行,在 _bootstrap self.run() 文件“C:\Users\Jetting\anaconda3\lib\multiprocessing\process.py”中,第 108 行,在运行 self._target(*self._args, **self._kwargs ) 文件“C:\Users\Jetting\Desktop\Robert\SCT_TryOut_DifferentAcqTypes\SCT_18.02.2021_v1.0_stream.py”,第 105 行,在 DAQ_Monitoring reader.read_one_sample(values_read) 文件“C:\Users\Jetting\anaconda3\lib\站点包\nidaqmx\stream_readers.py”,第 370 行,在 read_one_sample _read_analog_f_64(self._handle,数据,1,超时)文件“C:或指定要读取的固定数量的样本而不是读取所有可用样本可能会解决问题。属性:DAQmx_Read_RelativeTo 对应值:DAQmx_Val_CurrReadPos 属性:DAQmx_Read_Offset 对应值:0 或指定要读取的固定数量的样本而不是读取所有可用样本可能会解决问题。属性:DAQmx_Read_RelativeTo 对应值:DAQmx_Val_CurrReadPos 属性:DAQmx_Read_Offset 对应值:0

任务名称:_unnamedTask<0>

状态码:-200279

在我看来,流不断地将数据存储到内存中,这导致了溢出(错误 -200279:无法跟上 DAQmx 中的采集 - National Instruments)。但我不知道如何覆盖数据而不是将其附加到内存中。老实说,我不得不承认,我并没有完全理解 task.read() 和流方法是如何完成它们的工作的。

以下是带有流媒体的代码:

def DAQ_Monitoring(c,condition,ExChange,sample_rate):        
with nidaqmx.Task() as task:
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai0")
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai1")
    task.ai_channels.add_ai_current_chan("cDAQ9184-1B901BFMod1/ai2")
    task.timing.cfg_samp_clk_timing(rate=1000,sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS,samps_per_chan=2)
    reader = AnalogMultiChannelReader(task.in_stream)
    task.start()
    values_read = np.zeros((3,), dtype=np.float)
    sample_RateSeconds = (sample_rate)*(10**(-3))    #convert sampleRate from [ms] to [s]
    startTime = datetime.now().timestamp()
    oldTime = 0
    while condition.value == 3:
        while ((datetime.now().timestamp()-startTime)-oldTime) < sample_RateSeconds:
            pass
        timeData = datetime.now().timestamp()-startTime
        oldTime = timeData
        reader.read_one_sample(values_read)
        pressureIn,pressureVessel,volumeFlow = values_read
        position, force = pullData(c)
        accousticEmission1 = 999
        vibration = 999
        pressureIn = (1000000/16)*(pressureIn-0.004)
        pressureVessel = (200000/16)*(pressureVessel-0.004)
        volumeFlow = 3250*volumeFlow            
        ExChange[:] = [timeData,pressureIn,pressureVessel,volumeFlow,accousticEmission1,vibration,position,force]
    

感谢您对我的代码的任何建议或帮助和改进。如果缺少任何信息,我很抱歉(这是我的第一篇文章),以防万一。

谢谢!

4

1 回答 1

1

我自己找到了解决方案。我只需要在 task.read() 方法中添加一个参数。参数“number_of_samples_per_channel = nidaqmx.constants.READ_ALL_AVAILABLE”确保保存到实习缓冲区的所有数据都被立即读取,因此数据始终是“新鲜的”!

于 2021-03-01T12:41:43.070 回答