簡體   English   中英

python 和 nidaqmx 的數據采集延遲或溢出

[英]Delayed or overflowed data acquisition with python and nidaqmx

我無法讓我的代碼按照我想要的方式運行。 該代碼應該從傳感器獲取數據並將其存儲在帶有時間戳的文件中。 使用其中一個傳感器值控制直線電機。 我將 NI cDAQ 9184 和 Python 與 nidaqmx package 一起使用。 出現的第一個問題是數據傳輸延遲。 結果,發動機的控制過程非常緩慢。 我創建了一個 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 方法。 我對此發現很少,但我也嘗試實現此方法。 傳感器值可以正確無延遲地傳輸。 但是這里緩沖區溢出,根據采樣率,遲早會彈出以下錯誤:

(base) 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: Attempting to set identical bottom == top == 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:\Users\Jetting\anaconda3\lib\site-packages\nidaqmx_task_modules\read_functions.py ",第 35 行,在 _read_analog_f_64 check_for_error(error_code) 文件 "C:\Users\Jetting\anaconda3\lib\site-packages\nidaqmx\errors.py",第 127 行,在 check_for_error 中引發 DaqError(error_buffer.value.decode(" utf-8"), error_code) nidaqmx.errors.DaqError: 應用程序 ion 無法跟上硬件采集。 增加緩沖區大小、更頻繁地讀取數據或指定要讀取的固定樣本數而不是讀取所有可用樣本可能會解決問題。 屬性:DAQmx_Read_RelativeTo 對應值:DAQmx_Val_CurrReadPos 屬性:DAQmx_Read_Offset 對應值:0

任務名稱:_unnamedTask<0>

狀態碼:-200279

在我看來,stream 不斷地將數據存儲到 memory 中,這會導致溢出(錯誤 -200279:無法跟上 DAQmx - National Instruments 中的采集速度)。 但我不知道如何覆蓋數據而不是將其附加到 memory。 老實說,我不得不承認,我沒有完全理解 task.read() 和 stream 方法是如何工作的。

以下是帶有流媒體的代碼:

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]
    

感謝您對我的代碼的任何建議或幫助和改進。 如果缺少任何信息,我很抱歉(這是我的第一篇文章),以防萬一。

謝謝!

我自己找到了解決方案。 我只需要在 task.read() 方法中添加一個參數。 參數“number_of_samples_per_channel = nidaqmx.constants.READ_ALL_AVAILABLE”確保保存到實習緩沖區的所有數據都被立即讀取,因此數據始終是“新鮮的”!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM