NI Home > Community > NI Discussion Forums

Multifunction DAQ

Reply
Member
gremlm
Posts: 34
0 Kudos
Accepted Solution

AnalogWaveform time infromation

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!

Member
Kyle_K
Posts: 64
0 Kudos

Re: AnalogWaveform time infromation

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.

Applications Engineer
National Instruments
Member
gremlm
Posts: 34
0 Kudos

Re: AnalogWaveform time infromation

[ Edited ]

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( ...)?

Member
Kyle_K
Posts: 64
0 Kudos

Re: AnalogWaveform time infromation

[ Edited ]

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.

Applications Engineer
National Instruments
Member
gremlm
Posts: 34
0 Kudos

Re: AnalogWaveform time infromation

[ Edited ]

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, 

Member
Kyle_K
Posts: 64
0 Kudos

Re: AnalogWaveform time infromation

Are you stopping the task and restarting it to "rearm" your trigger?

Applications Engineer
National Instruments
Member
gremlm
Posts: 34
0 Kudos

Re: AnalogWaveform time infromation

[ Edited ]

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

Member
Kyle_K
Posts: 64
0 Kudos

Re: AnalogWaveform time infromation

How does it stop after 100 records? 

Applications Engineer
National Instruments
Member
gremlm
Posts: 34
0 Kudos

Re: AnalogWaveform time infromation

by   runTask.Stop();

 

 

  if(counter < buffer.Length )
       reader.BeginMemoryOptimizedReadWaveform((int)config.Acquisition.RecordSize, analogCallback, runTask, data_oneRecord);
  else
       runTask.Stop();

Member
KatieC
Posts: 102
0 Kudos

Re: AnalogWaveform time infromation

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

Katie Collette
Product Marketing
National Instruments