簡體   English   中英

NI DAQmx - 如何觸發輸入通道以使用模擬觸發輸入(python)讀取 N 個樣本?

[英]NI DAQmx - how to trigger input channel to read N samples using analog trigger input (python)?

我在使用 Python 和 nidaqmx 庫來正確觸發模擬輸入通道以讀取 N 值時遇到問題。 我正在使用 NI USB-6366 數據采集器。 我想從 ai0 通道讀取值。 我想使用參考觸發來收集超過閾值時的值。 我的問題是我可以使用 ai0 通道作為輸入和觸發源嗎? 或者我需要使用任何其他端口作為觸發源。 如果是這樣,如何使用它? 我正在添加當前正在嘗試的 python 代碼。 但是,它給了我一些錯誤

DaqError:在采集完成之前讀取相對於參考觸發或相對於預觸發樣本 position 的開始。 等待采集完成后再讀取,或增加讀取超時。 此外,確保硬件設置和接線正確,參考觸發信號正確,並且參考觸發發生在設備采集數據時。 屬性:DAQmx_Read_RelativeTo 對應值:DAQmx_Val_FirstPretrigSamp 任務名稱:hardwareFiniteVoltage 狀態碼:-200281

def hardwareFiniteVoltage():
      import nidaqmx
      import numpy as np
      import matplotlib.pyplot as plt
      sampleRate = 2E5   # Sample Rate in Hz
      secsToAcquire = 1    # Number of seconds over which to acquire data
      numberOfSamples = int(secsToAcquire * sampleRate)
      print('Acquiring %d data points' % numberOfSamples)
      with nidaqmx.Task('hardwareFiniteVoltage') as task:
         task.ai_channels.add_ai_voltage_chan('Dev1/ai0')
         task.timing.cfg_samp_clk_timing(sampleRate,samps_per_chan=numberOfSamples, 
         sample_mode=nidaqmx.constants.AcquisitionType(10178))
         
         task.triggers.reference_trigger.cfg_anlg_edge_ref_trig(
         'Dev1/ai0',10000,trigger_level=0.1)

                                    
         task.start()
         data = task.read(number_of_samples_per_channel=numberOfSamples)
         plt.plot(data)
         plt.xlabel('time [samples]')
         plt.ylabel('voltage [V]')
         plt.grid()
         plt.show()



if __name__ == '__main__':
      hardwareFiniteVoltage()

我不能說你是否可以在硬件上做到這一點,因為我不知道具體的 USB 卡,但我相信你可以在數據表上查看可行性。 只要涉及 python 代碼,觸發采集必須以異步方式完成:您的采集 function 將在數據可用時立即由nidaqmx調用(即,觸發事件發生 N 個樣本)。

筆記:

  • 據我從文檔中了解到, cfg_anlg_edge_ref_trig使 nidaq在觸發事件發生之前為您提供至少 N 個樣本:真的是您需要的,還是您在觸發事件之后尋找 N 個樣本?

請查看文檔以獲取有關回調注冊和 nidaq stram 閱讀器的更多信息。

注意:代碼沒有經過測試,因為目前我沒有可用的 nidaq 卡。 帶來不便敬請諒解

import nidaqmx
# This is an object that manage the samples stream acquisition
from nidaqmx import stream_readers
import numpy as np
import matplotlib.pyplot as plt
import time

# This var is initialized during task creation and is needed by your callback
nidaq_reader: stream_readers.AnalogMultiChannelReader = None


def do_something_with_data(data):
    # Just for convenience
    plt.plot(data)
    plt.xlabel('time [samples]')
    plt.ylabel('voltage [V]')
    plt.grid()
    plt.show()
    

def callback(task_handle, every_n_samples_event_type, number_of_samples, callback_data):
    try:
        # Allocate your numpy array (I'm assuming just one channel!)
        data = np.empty((number_of_samples,))
        # Now read the acquired samples
        number_of_samples_read = nidaq_reader.read_many_sample(data, number_of_samples)
    except Exception as e:
        print(f'Something went wrong reading samples: {e}')
    else:
        do_something_with_data(data)
    finally:
        # Always needed by nidaqmx to return 0!
        return 0

def hardwareFiniteVoltage():
      sampleRate = 2E5   # Sample Rate in Hz
      secsToAcquire = 1    # Number of seconds over which to acquire data
      numberOfSamples = int(secsToAcquire * sampleRate)
      print('Acquiring %d data points' % numberOfSamples)
      with nidaqmx.Task('hardwareFiniteVoltage') as task:
         task.ai_channels.add_ai_voltage_chan('Dev1/ai0')
         task.timing.cfg_samp_clk_timing(sampleRate,samps_per_chan=numberOfSamples, 
         sample_mode=nidaqmx.constants.AcquisitionType(10178))
         
         task.triggers.reference_trigger.cfg_anlg_edge_ref_trig(
         'Dev1/ai0',10000,trigger_level=0.1)
         
         # Here you register your callback into nidaqmx event loop
         task.register_every_n_samples_acquired_into_buffer_event(N, callback)
         
         # Initialize the stream_readers nidaq_reader to be used by your callback to get your actual data
         global nidaq_reader
         nidaq_reader = stream_readers.AnalogSingleChannelReader(task.in_stream)
                                    
         task.start()




if __name__ == '__main__':
      hardwareFiniteVoltage()
      
      while True:
        # Event loop. Don't use `pass`! It will saturate the CPU
        time.sleep(0.001)

暫無
暫無

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

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