Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

clocked acquisition (aiex2.cpp)

I'm having trouble with multi-channel clocked acquisition on an NI 622x card. I can't seem to get the right parameters set up for (near) continuous acquisition, using the defaults listed in the example or otherwise. I'm having trouble discovering what the issues are. I have no trouble with the code in aiex1.cpp, but I can't seem to get this to work. I don't even get the correct number of samples; the fifo queue only seems to collect two values once every second or so, even with the parameters entered in the example. This code works flawlessly for E-Series cards, but fails spectacularly for M-Series cards. By changing a few of the parameters, I can get the acquisition speed to increase somewhat, but only slightly. For some reason, the code examples show smileys in html. Those should just be colons. 😉

Here are the relevant code snippets:

NI.m:

-( BOOL )aiSetup {
UInt32 i;
UInt32 scanInterval = 2000;

// Convert ticks
UInt16 convert = 280;
BOOL continuous = FALSE;

[ self initMITE ];
[ self initialize ];
[ self configureTimebase ];
[ self resetPLL ];
[ self resetAnalogTrigger ];

[ self aiReset ];
[ self aiPersonalize:_aiNIConvertOutputSelect ]; // 3 for 622x cards
[ self aiClearFifo ];
[ self resetADC ]; // does nothing unless card is 625x series
[ self aiDisarm ];
[ self aiClearConfigurationMemory ];

for( i = 0; i < _aiChannelsToRecord; i++ ) // 2 channels
[ self aiConfigureChannel:( _aiFirstChannel + i ) :_aiGainIndex :kBiPolar :_aiChannelType 😞 i == ( _aiChannelsToRecord - 1 ) ) ? TRUE : FALSE ]; // first channel = 0, _gainIndex = 1, channel type = differential

[ self aiSetFIFORequestMode ];
[ self aiEnvironmentalize ];
[ self aiHardwareGating ];
[ self aiTrigger:kAISTART1SelectPulse :kAISTART1PolarityRisingEdge :kAISTART2SelectPulse :kAISTART2PolarityRisingEdge ];
[ self aiSampleStop:( _aiChannelsToRecord > 1 ) ? TRUE : FALSE ];
[ self aiNumberOfSamples:_aiFramesPerBuffer :0 :continuous ]; // 32 samples
[ self aiSampleStart:scanInterval :3 :kAISTARTSelectSITC :kAISTARTPolarityRisingEdge ];
[ self aiConvert:280 :3 :continuous ];
[ self aiClearFifo ];

return TRUE;
}

-( void )aiStartScan {
[ self aiArm:TRUE ];
[ self aiStart ];
}

-( void )aiEndScan {
if( [ self aiDataAvaliable ] ) [ self aiClearFifo ]; // Just in case the buffer contains extra values... never evaluates
[ self aiDisarm ];
}

AcquisitionController.m: // This is where the work gets done

-( void )aiSample {
[ _device aiSetup ]; // device = NI 622x

// Start sampling
_aiSampling = TRUE;
while( _aiSampling ) {
i = 0;
[ _device aiStartScan ];
while( i < numSamples ) { // channels * framesperbuffer = 64
if( [ _device aiDataAvaliable ] ) {
*( _aiInputBuffer + i ) = [ _device aiGetNextValue ] / normalizescale;
i++;
}
}
[ _device aiEndScan ];

... // buffer the scans
}
}
----
Rob Dotson
Asst. Research Scientist
Center for Neural Science
New York University
0 Kudos
Message 1 of 4
(7,104 Views)

Hi Rob-

My guess is that the problem is related to your calls to aiStartScan() in the loop.  The aiStart() sequence (i.e. AI arm and AI start) should only be performed once per acquisition (where an acquisition consists of multiple scans, in your case 32 samples per channel).  If you call aiArm and aiStart while an acqusition is running you are sort of stepping on the acquisition that is already in progress.

Do you need true continuous operation?  If so, you should configure the acquisition as continuous (via aiNumberOfSamples() ) and then perform FIFO reads in the loop on regular intervals.  If you'd like to stick to the burst operation you're using now I would nest your FIFO loop inside a larger loop and only read from the FIFO when the requested number of samples (in your case, 64 total) are available.

Hopefully this makes sense- let me know if this doesn't work or if you have other questions.

Thanks-

Tom W
National Instruments
0 Kudos
Message 2 of 4
(7,074 Views)
I still can't understand what's happening here. If I change the 'meat' of the code thusly:

[ _device aiStartScan ];
while( i < numSamples ) {
if( [ _device aiDataAvaliable ] ) {
*( _aiInputBuffer + i ) = [ _device aiGetNextValue ] / normalizescale;
NSLog( @"%e\n", *( _aiInputBuffer + i ) );
i++;
}
}
[ _device aiEndScan ];

I only get TWO samples in the fifo queue every second or so, regardless of the parameters I set in aiSetup.

The rest of the code has been modified to work with the exact parameters in aiex2.cpp, with continuous acquisition set to false. I'm not sure why when I set aiNumberOfSamples = 32, I only seem to get one sample per channel, or why the delay between scans is so incredibly long. Can you please explain again the relationship between the number of samples, convertPeriodDivisor, samplePeriodDivisor and their delay counterparts? I'm sure there is something quite simple that I am missing, but I can't find any real answers in the old STC manual or in the message board.
----
Rob Dotson
Asst. Research Scientist
Center for Neural Science
New York University
0 Kudos
Message 3 of 4
(7,047 Views)

Hi Rob-

Let me define a couple of the terms to help aid your understanding:

  • samplePeriodDivisor : The integer divisor used to create the ai/SampleClock, usually from the 20MHz onboard timebase.  There is one ai/SampleClock per AI scan.
  • numberOfSamples : The number of ai/SampleClock pulses that will occur after ai_start1 and before ai_stop for a finite acquisition.  This number is irrelevant for a continuous acquisition.
  • convertPeriodDivisor : The integer divisor used to create the ai/ConvertClock, usually from the 20MHz onboard timebase.  There are 'n' ai/ConvertClock pulses per AI scan, where 'n' is the number of channels in the task.  You must make sure that the resulting convert clock rate is at least equal to (sample clock rate * number of channels).
  • sampleDelay and convertDelay : refer to programmable delays between ai_start1 and ai_start (aka ai/StartTrigger and ai/SampleClock) or ai_start and ai_start2 (aka ai/SampleClock and the first ai/ConvertClock pulse), respectively.  For most operations the default values shown in the examples should suffice.

A couple of possibilities come to mind:

  1. Your ai/ConvertRate is too slow and subsequent ai/SampleClock pulses are being gated off in favor of finishing the scan in progress (this is automatically performed by the STC2).
  2. Your channel list is not being programmed correctly for some reason.  Check your call to aiConfigureChannel() and make sure that the lastChannel condition is being programmed correctly and is only being programmed for the last channel in the scanlist.

Can you please check your code given this new info and let me know if anything else jumps out at you? 

Thanks-

Message Edited by Tom W [DE] on 08-22-2007 01:21 PM

Tom W
National Instruments
0 Kudos
Message 4 of 4
(7,028 Views)