02-24-2012 06:08 PM
I am performing data acquision in continues mode through the NI 6132 board under DAQmx, using .NET (C#).
Everythihng works perfect, except each time the AnalogWaveform that is acquired has exactly the same start time information!
Each records aqcuision is triggered by trigger. We need to now exact time when trigger has happened 5 times in the row and aquire some data (for example , 100 samples after trigger). The aquired samples are correct. The issue is start time information for each record
For example, my call back function AnalogInCallback() is defined as following, for reading 5 records from the same channel:
AnalogWaveform<double>[] buffer = new AnalogWaveform<double>[5];
int counter = 0;
private void AnalogInCallback(IAsyncResult ar)
{
...
AnalogWaveform<double>[] data_oneRecord = reader.EndReadWaveform(ar);
buffer[counter] = data_oneRecord[0];
counter++;
}
When 5 records should be acuired, the function above is callsed 5 times.
The problem is that each time Waveform timing information is exactly the same, as first time so as for 5th one,
i.e
buffer[0].Timing.StartTime == buffer[4].Timing.StartTime
I need to have exact start time information oof the each record!
Solved! Go to Solution.
02-27-2012 05:46 PM
Tell me more about your trigger. Is your task ended by software after a given time and waits for the software to start it up again?
Kyle K.
02-27-2012 10:51 PM - edited 02-27-2012 10:53 PM
It is AnalogEdgeTrigger or DigitalEdgeTrigger.
The task is in the continues mode:
...
Task runTask = new Task();
runTask.Timing.ConfigureSampleClock("",10000, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1000 );
runTask.Triggers.ReferenceTrigger.ConfigureAnalogEdgeTrigger(aiName, AnalogEdgeReferenceTriggerSlope.Rising, 2.5, 20);
runTask.Control(TaskAction.Verify);
// Read the data set up
reader = new AnalogMultiChannelReader(runTask.Stream);
analogCallback = new AsyncCallback(AnalogInCallback);
reader.SynchronizeCallbacks = true;
reader.BeginReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask);
}
private void AnalogInCallback(IAsyncResult ar)
{
if (runTask == ar.AsyncState)
{
// Get the available record data from the channels
AnalogWaveform<double>[] data_oneRecord = reader.EndReadWaveform(ar);
buffer[counter] = data_oneRecord[0];
counter++;
AnalogWaveform<double> awf = data_oneRecord[0];
double xIncrement ;
double InitialXTimeSeconds;
double InitialXTimeFraction;
double InitialXOffset;
if(awf.IsPrecisionTimingInitialized)
{
xIncrement = awf.PrecisionTiming.SampleInterval.TotalSeconds;
InitialXTimeSeconds = awf.PrecisionTiming.StartTime.WholeSeconds;
InitialXTimeFraction = awf.PrecisionTiming.StartTime.FractionalSeconds;
InitialXOffset = awf.PrecisionTiming.TimeOffset.TotalSeconds;
}
else
{
xIncrement = awf.Timing.SampleInterval.TotalSeconds;
TimeSpan interval = new TimeSpan(awf.Timing.StartTime.Ticks);
InitialXTimeSeconds = Math.Truncate(interval.TotalSeconds);
InitialXTimeFraction = interval.TotalSeconds - InitialXTimeSeconds;
InitialXOffset = awf.PrecisionTiming.TimeOffset.TotalSeconds;
}
reader.BeginMemoryOptimizedReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask, data_oneRecord);
}
}
Could it be related to usage of the reader.BeginMemoryOptimizedReadWaveform( ...), after reader.BeginReadWaveform( ...)?
02-28-2012 06:34 PM - edited 02-28-2012 06:34 PM
You should use a finite acquisition when using reference triggers. The reason you are seeing the same timestamp information is because once your first trigger hits, the program continues to acquire forever and does not stop. In addition, your card does not possess the hardware to be retrigerable. This means that you will have to stop the task and restart it to allow the next trigger to hit. I would suggest leaving the hardware committed and stopping the task after you have the data you want and immediately restarting.
Kyle K.
02-28-2012 07:49 PM - edited 02-28-2012 07:53 PM
You are right about reference trigger - for continuous mode, the start trigger should be used.
But the following code still have the same issue - we acquiring 100 waveforms, and their StartTime are the same, i.e
buffer[0].Timing.StartTime.Ticks == buffer[1].Timing.StartTime.Ticks == buffer[99].Timing.StartTime.Ticks
....
AnalogWaveform<double>[] buffer = new AnalogWaveform<double>[100];
Task runTask = new Task();
runTask.Timing.ConfigureSampleClock("",10000, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1000 );
runTask.Triggers.StartTrigger.ConfigureAnalogEdgeTrigger(aiName, AnalogEdgeStartTriggerSlope.Rising, 2.5, 20);
runTask.Control(TaskAction.Verify);
// Read the data set up
reader = new AnalogMultiChannelReader(runTask.Stream);
analogCallback = new AsyncCallback(AnalogInCallback);
reader.SynchronizeCallbacks = true;
reader.BeginReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask);
}
private void AnalogInCallback(IAsyncResult ar)
{
if (runTask == ar.AsyncState)
{
// Get the available record data from the channels
AnalogWaveform<double>[] data_oneRecord = reader.EndReadWaveform(ar);
if(counter < buffer.Length )
buffer[counter] = data_oneRecord[0];
counter++;
if(counter < buffer.Length )
reader.BeginMemoryOptimizedReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask, data_oneRecord);
else
runTask.Stop();
}
}
By the way, buffer[0].IsPrecisionTimingInitialized == false,but for all other i != 0, buffer[i].IsPrecisionTimingInitialized == true,
02-29-2012 05:26 PM
Are you stopping the task and restarting it to "rearm" your trigger?
03-01-2012 12:20 AM - edited 03-01-2012 12:21 AM
No. task is not stoped for trigger rearming.
It is continues data aquision mode.
It will stop by itself as soon 100 records are acuired
03-02-2012 11:20 AM
How does it stop after 100 records?
03-02-2012 12:17 PM
by runTask.Stop();
if(counter < buffer.Length )
reader.BeginMemoryOptimizedReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask, data_oneRecord);
else
runTask.Stop();
03-05-2012 04:11 PM
Gremlm,
It looks like it has to do with the way you are doing the precision time stamp. In order to implement it, you will need to initialize the precision time stamp:
buffer.IsPrecisionTimingInitialized.Equals(true);
Then, each time you run the task, use: buffer.GetPrecisionTimeStamps();
This should eliminate some (if not all) of the following code:
double xIncrement ;
double InitialXTimeSeconds;
double InitialXTimeFraction;
double InitialXOffset;
if(awf.IsPrecisionTimingInitialized)
{
xIncrement = awf.PrecisionTiming.SampleInterval.TotalSeconds;
InitialXTimeSeconds = awf.PrecisionTiming.StartTime.WholeSeconds;
InitialXTimeFraction = awf.PrecisionTiming.StartTime.FractionalSeconds;
InitialXOffset = awf.PrecisionTiming.TimeOffset.TotalSeconds;
}
else
{
xIncrement = awf.Timing.SampleInterval.TotalSeconds;
TimeSpan interval = new TimeSpan(awf.Timing.StartTime.Ticks);
InitialXTimeSeconds = Math.Truncate(interval.TotalSeconds);
InitialXTimeFraction = interval.TotalSeconds - InitialXTimeSeconds;
InitialXOffset = awf.PrecisionTiming.TimeOffset.TotalSeconds;
Try that, and let me know how it goes!
Katie