Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Asynchronous reading occurs more often than expected.

I have an 8 channel analog input board (NI PXI-4472) that allows all 8 channels to be sampled simultaneously. I've written code in C# that reads the data. I implemented a callback. My goal is to read 8 channels where each channel is sampled at 16000 samples/second. I setup a buffer to hold 16000 bytes. When the callback gets called, I immediately read the data using EndReadMultiSample and start the callback again using BeginReadMultiSample. What I expect to happen is that if I am doing a continuous read using 16000 samples per second and have a buffer of 16000 bytes, the callback should only get called every second. That is what I want. What actually is happening is that the callback is getting called thousands of times within a second. I can't figure that out. How can I get my call back to execute continuously every second and give me exactly 16000 samples for each channel? Below is the code I wrote...

Thanks,
Johann

private AnalogMultiChannelReader aiReader = null;

// Configure a task

public class NIPXI4472 : Task
{
public NIPXI4472() : base("NIPXI4472")
{
this.Configure();
}

public virtual void Configure()
{
CreateVoltageChannel("PXI1Slot4/ai0", "Voltage0", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai1", "Voltage1", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai2", "Voltage2", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai3", "Voltage3", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai4", "Voltage4", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai5", "Voltage5", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai6", "Voltage6", Pseudodifferential, -5, 5, Volts);
CreateVoltageChannel("PXI1Slot4/ai7", "Voltage7", Pseudodifferential, -5, 5, Volts);
this.Timing.ConfigureSampleClock("", 16000, Rising, ContinuousSamples, 16000);
}
}

// Create a task
NIPXI4472 task = new NIPXI4472();
this.aiReader = new AnalogMultiChannelReader(task.Stream);

//Acquire samples
IAsyncResult handle = this.aiReader.BeginReadMultiSample(-1, new AsyncCallback(OnSamplesAcquiredCallback), null);

...

// The callback that gets called continuously. Should get called once a second.
public void OnSamplesAcquiredCallback(IAsyncResult i)
{
//Retrieve the data that was read.
double[,] data = this.aiReader.EndReadMultiSample(i);

IAsyncResult handle = this.aiReader.BeginReadMultiSample(-1, new AsyncCallback(OnSamplesAcquiredCallback), null);
}
0 Kudos
Message 1 of 2
(3,076 Views)
Johann,

The BeginReadMultiSample method takes a parameter that indicates how many samples to read. Passing -1 indicates "read whatever is already available in the buffer and return immediately", which is the value you are using. Using -1, if it so happens that 16000 samples have already been acquired by the board and are ready for you to read by the time you call BeginReadMultiSample, then you'll get 16000 samples. However, if only 3 samples are ready, or 2, or 0, then you'll get only that many. If you want to get exactly 16000 samples every time, then you can pass 16000 to BeginReadMultiSample. In that case, if 16000 samples are not acquired by the board yet, the function will wait for them. You can configure how long the function waits by setting the Timeout property on the DaqStream class. For example:

myTask.Stream.Timeout = 1000; // Wait for 1sec
// ('Timeout' is in milliseconds)

I hope this helps, Johann.

-- Chris W
.NET DAQmx Team, NI
Message 2 of 2
(3,068 Views)