These notes are an attempt to figure out how to aquire data from more than one channel on the NIDAQ board at one time.
Here are the necessary functions described below:
Note: in the declarations below ulong stands for unsigned long, ushort stands for unsigned short, etc.
NIDAQ Board interested in is: AT-MIO-16-E. Also interested in continuous samples at a steady sampling rate controlled by the hardware.
Here is a disclaimer at the start of the chapter:
   Note: It is recommended that you do not mix calls to the Data
      Acquisition Library with similar types of calls to the Easy I/O for DAQ
      Library in the same application.  For example, do not mix analog input
      calls to the Data Acquisition Library with analog input calls to the
      Easy I/O for DAQ Library in the same program.
The sample programs for the Easy I/O are located in the cvi/samples/easyio directory. These sample programs are discussed in the EASYIO section of cvi/samples.doc
Note that Easy I/O for DAQ Library cannot currently work with multirate scanning. (page 10-2).
 You can specify the voltage range for particular channels via this example string: First suppose that the AIStartAcqusition function set the initial voltage range from 0 to 5 volts., then
      "0,1; cmd hi 10.0 low -10.0; 2,3"
        channel voltage ranges are:
         0:  0 to 5
         1:  0 to 5
         2:  -10 to 10
         3:  -10 to 10
    
| short AIStartAcquisition(short device, char* channelString, int bufferSize, double scansPerSecond, double highLimitVolts, double lowLimitVolts, double *actualScanRate, ulong *taskID); | 
| device | the device number assigned by the configuration utility (which is a separate program run beforehand). | ||||||||||||
| channelString |  a string listing the input channels that are to be sampled.
         For examle, if you want to sample channels 0, 1 and 2, then
         the string would be: "0,1,2" or "0:2"
|  bufferSize
     |  The maximum number of scans which can be stored in
         the internal circular buffer.  A scan is a set of samples,
         one from each channel being sampled.
 |  scansPerSecond
     |  The desired sampling rate for the channels. All channels
         will be sampled at this rate.  The actual sampling rate
         will be returned by actualScanRate and
         depends on what sampling rates are possible on the
         NIDAQ card.
 |  highLimitVolts
     |  maximum voltage to be measured, Is this software value, or
         the hardware value?
 |  highLimitVolts
     |  minimum voltage to be measured, Is this software value, or
         the hardware value?
 |  actualScanRate
     |  This value will return the true sampling rate which the
         board is aquiring the samples at.
 |  taskID
     |  This is the descriptor number returned by the function
         AIStartAcquisition
 |  | 
| short AICheckAcquisition(ulong taskID, ulong *scanBacklog); | 
| taskID | This is the descriptor number returned by the function AIStartAcquisition | 
| scanBacklog | will return the number of scans (sets of samples) waiting in the input circular buffer. With the AIReadAcquisition function, you can now read up to this many scans. | 
| short AIReadAcquisition(ulong taskID long scanstoRead. ushort readMode, ulong *scanBacklog, short fillMode, double *waveforms); | 
| taskID | This is the descriptor number returned by the function AIStartAcquisition | 
| scanstoRead | The number of scans (sets of samples) which are read from the internal circular buffer. | 
| readMode | Can be either CONSECUTIVE_MODE which will read from the oldest side of the buffer, or by LATEST_MODE which will read from the most recent side of the buffer (and which may drop out some sample data). | 
| fillMode | Method to fill the waveforms array. Either by GROUP_BY_CHANNEL which will arrange samples into units by channel, or by GROUP_BY_SCAN which will arrange samles by scan. (see definition of fill modes for more information). | 
| scanBacklog | returns the current number of scans (sets of samples) which are still in the input circular buffer which will be ready to be read by a later call to AIReadAcquisition. | 
| waveforms | returns the data for the scans of each channel. data is organized according to fillMode parameter | 
| short AIClearAcquisition(ulong taskID); | 
| taskID | This is the descriptor number returned by the function AIStartAcquisition | 
Declarations for above functions:
 
   char* errorString = GetDAQErrorString(short errorNumber);
   short error = GetNumChannels(short device, char channelString[], 
                                short channelType, 
                                unsigned long *numberOfChannels);
   short error = GetChannelIndices(short device, char channelString[],
                                   char channelSubString[], short channelType,
                                   long channelIndices[]);
 
   short error = GetChannelNameFromIndex(short device, char channelString[],
                                         long index, short channelType,
                                         char channelName[]);
   
   short error = GetAILimitsOfChannel(short device, char channelString[],
                                      char singleChannel[]
                                      double initialHighLimitVolts,
                                      double initialLowLimitVolts,
                                      double *highLimitVolts,
                                      double *lowLimitVolts);
  
   short error = GroupByChannel(float array[], long numberOfScans,
                                unsigned long numberOfChannels);
   void SetEasyIOMultitaskingMode(int multitaskingMode);