基于Python nidaqmx库的NI USB-6361模拟触发采集问题:通过AI0触发AI1通道采集N样本
解决NI DAQ触发采集AI1的问题
你的核心问题在于把触发配置和目标采集通道放到了两个完全独立的任务里——第一个任务只配置了AI0的触发但没实际运行采样,第二个AI1的任务根本没关联任何触发逻辑,所以它一启动就直接读取样本了。要实现用AI0触发AI1采集,必须把两个通道加到同一个任务中,让触发条件作用于整个任务的采集流程。
下面是修正后的完整代码,同时满足「触发后采集AI1的N个样本、重复执行1分钟」的需求:
import nidaqmx import time num_samples = 1000 s_freq = 1e3 run_duration = 60 # 运行1分钟 def readdaq_on_trigger(): # 使用上下文管理器自动管理任务生命周期,避免手动close的错误 with nidaqmx.Task() as task: # 同时添加AI0(触发源)和AI1(采集目标)到同一个任务 task.ai_channels.add_ai_voltage_chan("Dev1/ai0", max_val=10, min_val=0) task.ai_channels.add_ai_voltage_chan("Dev1/ai1", max_val=10, min_val=0) # 配置采样时钟:有限采集,每个通道采集num_samples个样本 task.timing.cfg_samp_clk_timing( s_freq, sample_mode=nidaqmx.constants.AcquisitionType.FINITE, samps_per_chan=num_samples ) # 配置参考触发:AI0下降沿低于5V时触发,预触发样本数设为0(如果不需要预采集AI0的样本可以调整) task.triggers.reference_trigger.cfg_anlg_edge_ref_trig( trigger_source="Dev1/ai0", trigger_slope=nidaqmx.constants.Slope.FALLING, trigger_level=5.0, pretrigger_samples=0 ) # 启动任务,等待触发后采集样本 task.start() # 读取两个通道的样本,这里我们只需要AI1的结果 _, ai1_data = task.read(number_of_samples_per_channel=num_samples) task.stop() return ai1_data if __name__ == "__main__": start_time = time.time() print("开始采集,将运行1分钟...") while time.time() - start_time < run_duration: try: ai1_samples = readdaq_on_trigger() # 这里可以添加对采集到的AI1样本的处理逻辑,比如打印、保存等 print(f"触发采集完成,获取到{len(ai1_samples)}个AI1样本") except nidaqmx.errors.DaqError as e: print(f"采集过程出错:{e}") # 根据需要添加错误处理,比如重试 print("采集结束")
关键修改点说明:
- 合并任务:把AI0和AI1放到同一个任务中,这样触发配置会对整个任务生效,AI1的采集会等待AI0的触发条件满足才开始。
- 上下文管理器:用
with语句管理Task对象,自动处理任务的打开和关闭,避免手动调用stop()和close()时可能出现的资源泄漏。 - 触发与定时顺序:先配置采样时钟,再配置触发——nidaqmx要求定时配置在触发之前,确保触发逻辑能正确绑定到采样流程。
- 1分钟循环逻辑:用
time模块记录开始时间,循环执行采集直到运行时间达到60秒,同时添加了基本的错误捕获。 - 预触发样本调整:如果不需要在触发前采集AI0的样本,把
pretrigger_samples设为0即可;如果需要保留触发前的AI0数据,可以根据需求调整数值。
另外,你提到单独测试AI0触发时能正常工作,这是因为当时触发和采集都在同一个任务里,现在把AI1加入同一个任务,就能实现你要的触发采集逻辑了。
内容的提问来源于stack exchange,提问作者Alec Thomas
相关产品推荐
相关产品推荐

