Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Synching Counter Start to Analog Output Start

Solved!
Go to solution

Hello,

 

I am using NIDAQmx to send signals that control the line and frame acquisition of an imaging device, with the code being written in C++. I have attached the portion of the code that deals with my current issue and removed the irrelevant sections.

 

For context, I have an analog signal controlling a scanner which should be synced to a counter that handles frame acquisition. The analog signal is a triangle waveform, with one slope encompassing one low and high pulse of the counter (I have illustrated the expected oscilloscope output below)

Expected Oscilloscope outputExpected Oscilloscope outputThe issue that I have been running into is that the analog signal experiences latency, and ends up being very slightly delayed from the start. Instead of being perfectly aligned at the start of the low pulse as shown above, the "peaks" and "valleys" fall somewhere in the middle of the low pulse.

 

Unfortunately, this delay is different at every startup so adding a constant initial delay does not solve the problem. One solution I have tried implementing that did dramatically decrease the delay (but not entirely) was to pre-commit the tasks before starting them. I am skeptical that the solution would have something to do with the sample clock, as the signals are being sent at the same frequency.

 

I am hoping that this is not an uncommon problem or that there might have been a C++ function I overlooked. However, if this delay is inevitable, I can try to account for the delay in the post-processing step (of course, this is much less desirable). Any help or other suggestions would be greatly appreciated!

 

- Morgan

 

0 Kudos
Message 1 of 5
(2,040 Views)
Solution
Accepted by topic author morgmorgan

I'm a LabVIEW guy and am really no help with syntax details of the C++ API.  But I can assure you that you can get those signals sync'ed perfectly.  There are 2 keys:

 

1. Define your CO pulses in terms of "Ticks" while also configuring its "timebase source" to be the AO sample clock.  It looks like you're already trying to do the Ticks part.  Probably one of those optional-looking "" arguments should be something like "/Dev1/ao/SampleClock".

    Then your counter pulse timing will be driven *in hardware* by the AO sample clock.  Note: be sure to set idle state=Low, and set Initial Delay=Low Ticks.

 

2. Be sure to start the CO task before starting the AO task.  The CO task won't have anything to "count" to track time until the AO task starts producing its sample clock.  So sync will be guaranteed (provided your sum of Low Ticks + High Ticks = 1/2 the # samples in an AO cycle.  So you'll need to be sure to have an *even* # samples per AO cycle.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
Message 2 of 5
(2,021 Views)

Hi Kevin,

 

Thank you for taking a look at my problem! Your solution makes sense. The issue I am running into as I try to implement it, however, is that when I change the counter sample clock from implicit timing, the signal is longer being output.

 

This happens when I change the original line from this:

DAQmxCfgImplicitTiming(coHandle, DAQmx_Val_ContSamps, 10000);

 to this:

DAQmxCfgSampClkTiming(coHandle, "Dev1/ao/SampleClock", ANALOG_FREQ, DAQmx_Val_Rising, DAQmx_Val_ContSamps, 1000);

 

I have tried changing most of the parameters without any luck, which makes me think the issue is with the function itself - but I don't see any other way to change the timebase source. Any idea where I'm going wrong? I know this might be specific to the C++ API.

 

Here are the links to the documentation for the above functions:

DAQmxCfgSampClkTiming 

DAQmxCfgImplicitTiming 

 

Thanks again!

 - Morgan

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

Go ahead and switch back to Implicit Timing, that's still the right way to set up timing that's defined *implicitly* by the pulse parameters themselves.

 

Given you help link, I was able to poke around just a little and find this function prototype:

 

int32 DAQmxCreateCOPulseChanTicks (TaskHandle taskHandle, const char counter[], const char nameToAss...

 

So it looks to me like you'd just set the sourceTerminal argument to something like "/Dev1/ao/SampleClock".  Again, the timing config should still be set for implicit timing.

 

 

-Kevin P

 

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
Message 4 of 5
(2,002 Views)

This solved my issue - thank you!

0 Kudos
Message 5 of 5
(1,990 Views)