Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

AnalogWaveform time infromation

Solved!
Go to solution

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!

0 Kudos
Message 1 of 14
(4,319 Views)

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.

Product Manager for Product Data
National Instruments
0 Kudos
Message 2 of 14
(4,293 Views)

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

0 Kudos
Message 3 of 14
(4,289 Views)

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.

Product Manager for Product Data
National Instruments
0 Kudos
Message 4 of 14
(4,271 Views)

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, 

0 Kudos
Message 5 of 14
(4,266 Views)

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

Product Manager for Product Data
National Instruments
0 Kudos
Message 6 of 14
(4,252 Views)

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

0 Kudos
Message 7 of 14
(4,248 Views)

How does it stop after 100 records? 

Product Manager for Product Data
National Instruments
0 Kudos
Message 8 of 14
(4,233 Views)

by   runTask.Stop();

 

 

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

0 Kudos
Message 9 of 14
(4,231 Views)

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
National Instruments
0 Kudos
Message 10 of 14
(4,209 Views)