使用DAQmx进行数据采集编程通常包括以下步骤:
由于函数调用与NI-DAQmx VI相同,因此基于文本的编程环境中的数据采集与LabVIEW NI-DAQmx编程非常相似。
DAQmx附带数据采集编程所需的API。DAQmx API只是一组库,其中包含关于如何执行所有数据采集操作的函数。这些API支持LabWindows/CVI、C、C++、Visual Basic 6.0、VB.NET和C#。
DAQmx API随DAQmx驱动程序一起安装,包含以下参考手册:
这些API分别包含有关使用函数库和类库与NI数据采集(DAQ)设备进行通信并对其进行控制的详细信息。
虚拟通道是一组属性设置(包括名称、物理通道、输入端连接、测量或生成类型),并包括换算信息。
任务是NI-DAQmx中的一个重要概念,指一个或多个具有定时、触发和其他属性的虚拟通道。从概念上来说,任务表示要执行的测量或生成操作。可以为模拟输入和输出、数字输入和输出以及计数器操作创建任务。
如要使用C语言创建任务和模拟输入通道,则使用以下函数调用:
DAQmxCreateTask("", &taskHandle));
DAQmxCreateAIVoltageChan (taskHandle, "Dev1/ai0", "Voltage", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL);
如要使用.NET创建任务和模拟输入通道,请实例化任务对象并创建通道,如下所示:
analogInTask = new Task();
AIChannel myChannel;
myChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0", //The physical name of the channel
"myChannel", //The name to associate with this channel
AITerminalConfiguration.Differential, //Differential wiring
-10, //10v minimum
10, //10v maximum
AIVoltageUnits.Volts //Use volts
大多数NI数据采集设备使用采样时钟来控制采集和生成样本的速率。采样时钟可设置两个采样之间的时间间隔。时钟的每个计时周期都在每个通道上启动一次样本采集或生成。
在软件中,可通过指定采样率来指定间隔(时钟采集或生成信号的速度)。此外,采样率受限于信号应用的信号调理或应用的通道数。
如要使用C语言配置定时参数,则调用DAQmxCfgSamp函数,如下所示:
DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising,
DAQmx_Val_FiniteSamps, 1000);
要使用.NET语言配置定时参数,请使用Task.Timing属性,如下所示:
analogInTask.Timing.ConfigureSampleClock(
"/Dev1/PFI0", // external clock source line or use "" for internal clock
10000, // expected rate of external clock or actual rate of internal clock
SampleClockActiveEdge.Rising, // acquire on rising or falling edge of ticks
SampleQuantityMode.ContinuousSamples, // continuous or finite samples
1000 // number of finite samples to acquire or used for buffer size if continuous
);
当由NI-DAQmx控制的设备执行某个行为时,便称为一个操作。生成采样和开始波形采集是两个很常见的操作。每个NI-DAQmx操作都需要一个激励或原因。激励发生时就会执行操作。操作的原因就是触发器。触发器以其引发的操作命名,例如启动采集的启动触发器。
NI-DAQmx Trigger函数用于对触发器进行配置,以执行指定操作。最常用的操作是启动触发器和参考触发器。启动触发器用于启动采集或生成操作。参考触发器则用于在一组采集到的样本中创建触发前数据结束和触发后数据开始的位置。这两种触发器都可以配置为在数字边沿和模拟边沿或者在模拟信号进入或离开窗口时发生。
如要将启动触发器配置为当设备的PFI线0传入上升数字信号时启动,则使用C语言编写的DAQmxCfgDigEdgeStartTrig函数:
DAQmxCfgDigEdgeStartTrig (taskHandle, "PFI0", DAQmx_Val_Rising);
如要使用.NET语言配置启动触发器,则使用Task.Triggers.StartTrigger集合中的ConfigureDigitalEdgeTrigger,如下所示:
DigitalEdgeStartTriggerEdge triggerEdge = DigitalEdgeStartTriggerEdge.Rising;
analogInTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("PFI0, triggerEdge);
NI-DAQmx Start Task函数可以将一个任务显式转换为运行状态。在运行状态下,任务执行指定的采集和生成。当NI-DAQmx读取函数运行,而NI-DAQmx开始任务函数未运行时,任务将隐式转换成运行状态或自动启动。当NI-DAQmx写入函数自动开始写入指定的输入,但NI-DAQmx开始任务函数未运行时,也会发生这种隐式转换。
如要使用C语言启动任务,则使用DAQmxStartTask函数:
DAQmxStartTask(taskHandle);
如要使用.NET语言启动任务,则使用Task.Start函数:
analogInTask.start();
NI-DAQmx提供多个用于数据读取和写入的函数。在很多情况下,有多种方案可供选择。读取和写入函数有两个主要选择标准:数据格式和数据结构。数据格式指定返回的数据类型。例如,计数器读数可返回整数或浮点数。第二类是数据结构,规定了所返回数据采用的结构。例如,模拟读数具有多种数组和标量结构。
我们可以执行数据采集或数据生成。采集模式下,需要进行读取操作才能从缓冲区中读取指定数量的样本。在数据生成模式下,样本写入数据采集板的缓冲区。
如要读取C语言数据,则使用DAQmxReadAnalog函数调用:
DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data, 1000, &read, NULL)'
如要读取.NET数据,则创建一个ChannelReader对象,将其绑定到Task.Stream,然后调用读取函数,如下所示:
//Create the reader and attach it to the stream
AnalogSingleChannelReader reader = new AnalogSingleChannelReader(analogInTask.Stream);
//Perform the read
double[] data = reader.ReadMultiSample(100);
有关使用.NET读取和写入数据的更多信息,请参阅NI-DAQmx .NET 2.0 Framework帮助中的“使用NI-DAQmx .NET库读取和写入”部分。
完成任务后,停止任务并取消分配所有预留的资源。NI-DAQmx清除任务函数可清除指定的任务。如果任务正在运行,则函数将先停止任务,然后再释放任务的所有资源。任务清除后,除非重新创建,否则无法使用该任务。因此,如果需要再次使用任务,则应使用NI-DAQmx Stop Task函数来停止任务,而不是将其清除。
要使用C语言停止和清除任务,请使用以下函数:
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
要使用.NET语言停止和清除任务,请使用Task.Stop和Task.Dispose方法,如下所示:
analogInTask.Stop();
analogInTask.Dispose();
有关其工作原理的清晰范例,请参考本文档下方的代码范例部分。
下面的示例是一个模拟输入电压操作,使用NI数据采集板从传感器采集一定数量的电压样本。
********************************************************************************
#include <stdio.h>
#include <NIDAQmx.h>
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
int main(void)
{
int32 error=0;
TaskHandle taskHandle=0;
int32 read;
float64 data[1000];
char errBuff[2048]={'\0'};
// DAQmx analog voltage channel and timing parameters
DAQmxErrChk (DAQmxCreateTask("", &taskHandle));
DAQmxErrChk(DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL));
DAQmxErrChk(DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000));
// DAQmx Start Code
DAQmxErrChk(DAQmxStartTask(taskHandle));
// DAQmx Read Code
DAQmxErrChk(DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data, 1000, &read, NULL));
// Stop and clear task
Error:
if( DAQmxFailed(error) )
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( taskHandle!=0 ) {
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}
if( DAQmxFailed(error) )
printf("DAQmx Error: %s\n",errBuff);
return 0;
}
********************************************************************************
注: 为了访问DAQmx库,main.c程序中必须包含NIDAQmx.h头文件。
在此范例代码中,此函数创建了一个任务:
int32 DAQmxCreateTask (const char taskName[], TaskHandle *taskHandle);
这为任务分配一个名称,其输出引用了创建的任务。然后,该函数配置了一个虚拟电压通道:
int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]);
此函数调用指定了对已创建任务的引用、物理通道名称、分配给虚拟通道的名称、通道的输入接线端配置、需测量单位的最小值和最大值,以及应用于通道的自定义换算名称。
配置虚拟电压通道后,可使用采样时钟设置函数来指定采样率、采样模式以及要读取的样本数量:
int32 DAQmxCfgSampClkTiming (TaskHandle taskHandle, const char source[], float64 rate, int32 activeEdge, int32 sampleMode, uInt64 sampsPerChanToAcquire);
也可以使用DAQmx_Val_ContSamps常量将采样模式设置为连续。如要真正开始采集电压样本,必须调用以下函数,同时引用配置的任务。
int32 DAQmxStartTask (TaskHandle taskHandle);
DAQmxReadAnalogF64从包含一个或多个模拟输入通道的任务中读取多个浮点样本,如函数调用所示。
int32 DAQmxReadAnalogF64 (TaskHandle taskHandle, int32 numSampsPerChan, float64 timeout, bool32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32 *sampsPerChanRead, bool32 *reserved);
该函数读取了1000个样本,并将其写入长度同样为1000的阵列中。
最后,DAQmxStopTask和DAQmxClearTask停止任务,使其返回到调用DAQmxStartTask之前的状态,并释放任务保留的所有资源。任务清除后,如果不重新创建或重新加载任务,则无法使用任务。
对于相同操作,可以使用适用于Visual Basic和C#的Microsoft .NET Framework DAQmx库的API编写类似伪码。API包含为NI-DAQmx提供.NET接口的类、委托和枚举。以下是一个非常简单的读取操作范例代码:
********************************************************************************
// Create a channel
myTask.AIChannels.CreateVoltageChannel(physicalChannelComboBox.Text, "", (AITerminalConfiguration)(-1), rangeMinimum, rangeMaximum, AIVoltageUnits.Volts);
// Configure timing specs
myTask.Timing.ConfigureSampleClock("", sampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, samplesPerChannel);
// Verify the task
myTask.Control(TaskAction.Verify);
// Prepare the table for data
InitializeDataTable(myTask.AIChannels, ref dataTable);
acquisitionDataGrid.DataSource = dataTable;
// Read the data
reader = new AnalogMultiChannelReader(myTask.Stream);
// clear task
myTask.Dispose();
********************************************************************************
注: 如要成功运行该程序,必须包含NationalInstruments.DAQmx类库。
NI-DAQmx还为每个编程环境提供一组范例。 您可以在以下目录位置找到C API的使用范例:
<Program Files>\National Instruments\NI-DAQ\Examples\DAQmx ANSI C
或
<Documents and Settings>\All Users\Documents\National Instruments\NI-DAQ\Examples\DAQmx ANSI C
.NET API范例可在以下目录找到:
C:\Program Files\National Instruments\MeasurementStudioVS2005\DotNET\Examples\DAQmx
或
<Documents and Settings>\All Users\Documents\National Instruments\NI-DAQ\Examples\DotNET2.0
名为VB的文件夹包含Visual Basic .NET范例,名为CS的文件夹包含C#范例。
Visual Basic 6.0范例可以在以下目录找到:
<Program Files>\National Instruments\NI-DAQ\Examples\Visual Basic 6.0
或
<Documents and Settings>\All Users\Documents\National Instruments\NI-DAQ\Examples\Visual Basic 6.0
安装NI-DAQmx驱动程序并选择支持C和/或.NET后,可在程序(Programs) » National Instruments » NI-DAQ »基于文本的代码支持(Text-Based Code Support)下的“开始”(Start)菜单中找到帮助快捷方式
如需NI-DAQmx概念的更多文档,详见程序(Programs) » National Instruments » NI-DAQ 下的NI-DAQmx帮助(NI-DAQmx Help)