Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx .NET acquisition problem

Hi,

 

I'm trying to perform a simple acquisition.  My setup is as follows:

 

Windows XP SP3

USB-6259 DAQ system

DAQmx 9.2.3

Microsoft Visual C++ Express 2008

National Instruments DLL resources in the project all indicate VS2008 versions.

.NET version 3.5

 

 

Here is my sample .NET application:

 

 

Stopwatch sw;


Task ^ task = gcnew Task;
AnalogMultiChannelReader ^ reader = gcnew AnalogMultiChannelReader( task->Stream );

task->AIChannels->CreateVoltageChannel( L"/Dev1/ai0", 
                                        L"analog_channel", 
                                        AITerminalConfiguration::Rse, 
                                        -10.0, +10.0, 
                                        AIVoltageUnits::Volts );

task->Timing->ConfigureSampleClock( nullptr, 
                                    10.0, 
                                    SampleClockActiveEdge::Rising, 
                                    SampleQuantityMode::FiniteSamples, 
			            100L );

task->Stream->ReadAllAvailableSamples = true;

task->Control( TaskAction::Verify );

task->Start();


sw.Start();
while ( sw < 3.0 );


array<double, 2> ^ data = reader->ReadMultiSample( -1 );

 

The task should acquire a total of 100 samples at 10 Hz, which takes 10 seconds to complete.

 

'sw' is a simple timer object.  I'm using it to wait 3 seconds before requesting samples.  I'm showing it for the sake of this example.

 

 

The problem I'm having is that, even though I've set the task stream's ReadAllAvailableSamples property to true, the first call to reader->ReadMultiSample(-1) never returns any samples no matter when it occurs during the 10-second period.  At the end, when acquisition has ended, a first call to ReadMultiSample(-1) returns all 100 samples. During acquisition, the stream's TotalSamplesAcquiredPerChannel property also always returns zero before the first read.

 

During acquisition, multiple reads beyond the first one will return some samples, but the number of samples returned does not correspond to the amount of time that has passed, even if the intervals are several seconds.

 

The example above uses FiniteSamples; I get similar results if I specify ContinuousSamples. 

 

I am aware of the possibility of acquisition using asynchronous reads with Begin/EndReadMultiSample(), but I'd rather not use those for my application.

 

What am I doing wrong?

 

Thanks -

 

0 Kudos
Message 1 of 5
(3,227 Views)

Hi, 


I think you're misunderstanding the function of ReadAllAvailableSamples. You can only read data after it's been sent from the DMA and it's not sent until it fills the buffer. Since your sample size is 100, you're not going to see any of those samples until they've been transfered in that 100-sample batch. If you want to constantly read every sample as it has been acquired, reduce your sampling rate to 1 and ReadAllAvailableSamples will show you a more immediate response.

 

Let me know if I misunderstood your issue. Hope that helps!

0 Kudos
Message 2 of 5
(3,215 Views)

> Since your sample size is 100, you're not going to see any of those samples
> until they've been transfered in that 100-sample batch

 

That doesn't appear to be the case with examples I have run. In all cases, only the first read returns no samples. Subsequent reads do return samples, but not enough to correspond to the time elapsed since the start.

 

I can't see the difference between waiting until the 100-sample buffer is filled and calling ReadMultiSample(-1) versus calling ReadMultiSample(100) to start with, i.e. there's no advantage to using the -1 argument.  If I set the buffer to a smaller number of samples so that I can have access to samples sooner, don't I risk overflowing the buffer?

0 Kudos
Message 3 of 5
(3,208 Views)

I believe you should be fine with a sample size of 1 since your samping rate is so low.  Since you are using USB, there is no DMA so USB sends data in chunks.  I'm pretty sure this is defined by your sample size.  With your sample size of 100, you should be waiting 10 seconds for every sample.  With this wait time in between samples, it will appear as if there is a time discrepancy until it acquires new data.  

 

I would look at the examples in the Text-Based Code Support folder that is installed with DAQmx.

 

0 Kudos
Message 4 of 5
(3,188 Views)

Hi mb2003,

 

There are two "buffers" to speak of that are relevant to your acquisition.

 

The first is the on-board FIFO, which is 4095 samples on the USB 6259 and cannot be changed.

 

The second is a portion of your computer's kernel memory that is reserved by DAQmx.  By default, for finite tasks it will be equal to the entire length of your acquisition (100 samples in your example).

 

 

During the acquisition, data is transferred from the on-board FIFO to the kernel buffer.  When you call DAQmx Read, you are copying data from the kernel buffer to your application.  Reading (-1) samples indicates that you are asking to read whatever is currently available in the kernel buffer (if ReadAllAvailableSamples is set to true, or if the task is continuous).

 

However, at low rates like what you have configured (10 Hz), data is not accumulated quickly enough to require a transfer from the on-board FIFO to the kernel buffer (the on-board FIFO is nowhere near full).  The driver is not going to initiate the USB transfer unless it is necessary--USB transfers have quite a bit of overhead so it makes more sense (from an efficiency standpoint) to send data in large packets.  PCI or PCIe devices on the other hand use 32-bit transfers so the data is available in the kernel buffer almost immediately after it is acquired.

 

So, when you read -1 samples, since no data is available in the kernel buffer (it's still in the FIFO on your USB device) you receive an empty array. 

 

 

Now... what it sounds like you're asking how to do is force a transfer of the data in the on-board FIFO to the kernel buffer.  Reading a specific number of samples will do just that, but it sounds like you don't necessary want to have to specify the number.  What I recommend doing is making two calls to DAQmx Read.  The first call, just read 1 sample, which should initiate the transfer of data from the on-board FIFO to the DAQmx buffer.  Then, on your 2nd DAQmx Read call you can read (-1) and it should return the expected amount of data.  I tried running your example with the extra DAQmx Read call, and got 29 samples (as expected) on my 2nd call to DAQmx Read.  I'll speak with the developers tomorrow and see if we can come up with a better way, but I think this workaround should be sufficient for what you're asking to do.

 

 

Best Regards,

John Passiak
0 Kudos
Message 5 of 5
(3,178 Views)