我很难让我的代码以我想要的方式运行。该代码应该从传感器获取数据,并将其存储在带有时间戳的文件中。使用其中一个传感器值来控制直线电机。我使用NIPython9184和cDAQ包。出现的第一个问题是数据传输延迟。因此,发动机的控制过程非常缓慢。我创建了一个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: UserWarning:尝试设置相同的bottom == top == 0.0会导致奇异转换;自动扩展。ax.set_ylim(np.amin(dataPlot),np.amax(dataPlot)) SCT_18.02.2021_v1.0_stream.py:291: UserWarning:尝试设置相同的left == right == 0.0会导致单一转换;自动扩展。ax.set_xlim(np.amin(timePlot),np.amax(timePlot)) SCT_18.02.2021_v1.0_stream.py:290: UserWarning:尝试设置相同的底层== top == 0.16962570625000006会导致奇异转换;自动扩展。ax.set_ylim(np.amin(dataPlot),np.amax(dataPlot)) SCT_18.02.2021_v1.0_stream.py:291: UserWarning:尝试设置相同的left == right == 1.4031758308410645会导致奇异转换;自动扩展。ax.set_xlim(np.amin(timePlot),np.amax(timePlot))进程-1:回溯(最近一次调用):文件"C:\Users\Jetting\anaconda3\lib\multiprocessing\process.py",行315,在np.amin self.run()文件self._target行108中,在运行self._target(*self._args,**self._kwargs)文件数据行105,在DAQ_Monitoring reader.read_one_sample(values_read)文件数据行370中,在read_one_sample _read_analog_f_64中(self._handle,data,1,超时)文件"C:\Users\Jetting\anaconda3\lib\site-packages\nidaqmx_task_modules\read_functions.py",第35行,在_read_analog_f_64 check_for_error(error_code)文件提升行127,in check_for_error raise DaqError(error_buffer.value.decode("utf-8"),error_code) nidaqmx.errors.DaqError:应用程序无法跟上硬件获取。增加缓冲区大小、更频繁地读取数据或指定要读取的固定样本数而不是读取所有可用样本可能会解决此问题。属性: DAQmx_Read_RelativeTo对应值: DAQmx_Val_CurrReadPos属性: DAQmx_Read_Offset对应值:0
任务名称:_unnamedTask<0>
状态码:-200279
在我看来,流不断地将数据存储到内存中,这导致了溢出(错误-200279:无法跟上DAQmx - National Instruments中的获取)。但我不知道如何覆盖数据,而不是将其附加到内存中。老实说,我不得不承认,我并不完全理解task.read()和流方法是如何工作的。
以下是streamer的代码:
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]任何建议或帮助和改进我的代码是感激的。如果遗漏了任何信息,我很抱歉(这是我的第一篇文章),以防万一。
谢谢!
发布于 2021-03-01 20:41:43
我自己找到了解决方案。我只需向task.read()方法添加一个参数。参数"number_of_samples_per_channel = nidaqmx.constants.READ_ALL_AVAILABLE“确保保存到内部缓冲区的所有数据都被一次读取,因此数据总是”新的“!
https://stackoverflow.com/questions/66277281
复制相似问题