LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem synchronizing position encoders measurements using cDAQ 9174

Hi,

The main purpose of my work is to read simultaniously and compare signals of two diffrent encoders.

I am using cDAQ-9174 on which is mounted an NI9401 DIO Module.

To make sure of the sychronisation of my position encoders (ctr1 and ctr2) measurements. We duplicated a signal so that both encoders would have the exact same input in order to see if they are measuring the same. the set up is described in the ''Setup'' image.

The VI I am using is ''Synch.vi'' joined to this post. I created the VI based on two examples :

https://forums.ni.com/t5/Example-Program-Drafts/Synchronizing-Two-Counter-Tasks-in-NI-DAQmx/ta-p/349...

and

 http://www.ni.com/example/31081/en/

I am using an arm start trigger to ensure that both encoders begin measuring at the exact same moment and i use a third counter (ctr0) to generate a pulse train that i use as a clock signal for both encoders to ensure their synchronization.

According to NI engineers with whom i had an e-mail exchange, This VI should work perfectly and there should be no problem.

The configuration we used is also correct according to them.

The signal I am using as an input could reach a frequency of 3MHz.

The resluts are joined to the post.

i visualised those results I got as described in the ''visualised results''. a zoomed area of those results is in ''zoomed area of results'' to describe better the results.  

 

It seems that there is a delay of the reading between the encoders. the same signal is read by both of them but with a delay.

What could be the origin of this problem ?

 

Hassen.

0 Kudos
Message 1 of 26
(3,383 Views)

I probably disagree with the NI engineers who said "Synch.vi" should work perfectly.   It's really close, but not perfect.

 

1. The sample clock counter should start *after* the encoder measurement counters are started.

2. The source of the "Arm Start" trigger signal isn't clear.  What controls it, especially what controls the timing of when it occurs relative to execution of "Synch.vi"?   The triggering event should also not arrive until *after* the encoder measurement counters are both started.

 

The data shows a lag of about 30 msec.  From experience, this is in the right neighborhood of the lag one might get from a sequence of DAQmx Start calls to a USB device like your cDAQ.  Your code has such a sequence of DAQmx Start calls, the error wire enforces the execution order.

 

My guess is that your triggering signal is always present and you start this app before encoder motion begins.  When you start this app, it first starts the sample clock counter.  Then it starts one encoder task.  It pretty much immediately gets triggered (this is an educated guess based on the *behavior*.  The code doesn't define the triggering signal).  So it starts sampling 0 values because the sample clock is already running.  Thus it gets a head start of having some extra 0 values in its buffer before the 2nd encoder task starts about 30 msec later.  Sometime after both have started, motion begins and the changing position values get buffered.   However, that headstart of 0 values for the 1st task makes it appear to lag behind the 2nd task.

 

The first simple fix is to start the sample clock *after* the encoder tasks.  Even if the Arm Start trigger is always present, that just allows both counters to start tracking position internally after a 30 msec lag.  But since there's no motion yet, they're just tracking 0 anyway.  Then once the sample clock starts, their *buffers* will be synced instead of the 1st one getting a 30 msec headstart.  Further, since your DAQmx Read calls request the same # data points from each, your reads keep the data in sync.

 

In a situation where motion might already be present when you start the app, you would *need* to control the timing of the Arm Start trigger by generating it in code *after* both encoder tasks start.  I would probably also wait until after I started the sample clock.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 26
(3,352 Views)

Hi,

Thanks a lot for your quick answer.

I tried to do what you suggested. So I put the sample clock after the encoders tasks. But i get an error -200557 window saying :

"Specified property cannot be set while the task is running.

Set the property prior to starting the ttask, or stop the task prior to setting the property." 

as shown in the pcture named "error".

I created many VIs. In each one I tried modifying the position of the samle clock and the position of the control task hoping that would resolve the problem. but I always get the same error.

all VIs created are below.

for all may test i used the same "configuration" as shown before.

Could you, please, show me how to solve that ?

 

Hassen. 

0 Kudos
Message 3 of 26
(3,306 Views)

I was talking about the sequence of when you *start* the various tasks, not the sequence of when you configure timing.   I've attached a mod of your original code and did a little tidying up mainly b/c I couldn't help myself.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 4 of 26
(3,294 Views)

Hi,

Thank you for the answer.

I tried your VI and i got a new error -200279 saying :

"The application is not able to keep up with the hardware acquisition.

Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to read instead of reading all available samples might correct the problem."

screenshots of the error window and theconfiguration used for the test are attached.

could you tell me what could cause this and how to solve it please.

 

Hassen.

Download All
0 Kudos
Message 5 of 26
(3,271 Views)

Kevin, you are close but not exactly....

 

Hassen, Forward the following to the NI AE

 

A couple of things that are not quite right:

  • You Reserve the Tasks then go and mess with triggering- uhmmmm. that changes the resources you need so you get an implied transition all the way back to unverified and up to reserved again.  Better, fully configure the task then explicitly Commit just prior to start.  But, this is not you source of offset
  • Error chain in cyclic loop. You simply cannot write the data to file before you read it from PC memory- Better Read then write the data to file

Now, let's talk about what IS causing the "Apparent" ch-ch offset   For reference see NI-DAQmx Programming in LabVIEW. Module 1 "Programming with the DAQmx API"  Available from The Badging Pilot Home Page

 

Time of the Task Data is the "time" (per the OS timer) that it was read from the PC buffer.  It would be just dandy if there was a deterministic clock onboard the 9401 but, there ain't  so the software time is the only one available to us and... we read the two tasks serially because there can be no multi-ch counter tasks on a 9401.  Better, Deserialize the reads.  (Split the error chain and use a compound Math node set to OR for the stop condition) and let the OS multi-thread the darned PC Buffer reads.  Best, Use a multi- counter Task (This is NOT going to happen with encoders- sorry)  Also better, Reduce samples to read and queue out the data to a file logging consumer loop.

 

Now, I've heard rumors about a new reconfigurable cRIO module- There may be something there.

 


"Should be" isn't "Is" -Jay
0 Kudos
Message 6 of 26
(3,254 Views)

Hi Jeff,

Thank you for your help.

I will apply your seggestions and do the tests again and let you know how it turns out.

I just want to understand, when you say "there can be no multi-ch counter tasks on a 9401", "This is NOT going to happen with encoders- sorry" and "Now, I've heard rumors about a new reconfigurable cRIO module- There may be something there". do you mean that the NI9401 could not be able to realise what I'm trying to do and at best I'll be close but won't reach my goal ? Do you advice me to get another device ? If yes, which one would be most suitable ?

 

Hassen. 

0 Kudos
Message 7 of 26
(3,248 Views)

@Hassen13 wrote:

Hi Jeff,

Thank you for your help.

I will apply your seggestions and do the tests again and let you know how it turns out.

I just want to understand, when you say "there can be no multi-ch counter tasks on a 9401", "This is NOT going to happen with encoders- sorry" and "Now, I've heard rumors about a new reconfigurable cRIO module- There may be something there". do you mean that the NI9401 could not be able to realise what I'm trying to do and at best I'll be close but won't reach my goal ? Do you advice me to get another device ? If yes, which one would be most suitable ?

 

Hassen. 


Let me clarify

A Linear Displacement Encoder (X4 Encoding) measurement involves measuring the phase relationship between two signals and reporting a change in position at each transition.  There is really no way to synchronize the transitions of multiple encoders.  Basically 100 samples require 100 transitions on that channel so, they cannot be combined into the same DAQmx Task.  I know of no hardware that would get you there but, I do not know Everything.

 

At best you can get "Close." 

 

The best case scenario I can imagine is to read all available samples from each Task in as tight a loop as possible without anything else hogging any CPU resources.  This should pace at the Fastest transition rate but, may result in an underflow of the slower rate (assume 1 sample available from 1 channel but no samples yet available from the slower channel)  Now you need code to get around that.

 

Potentially, you might use two Acquisition loops set to 1 sample 1 Ch  and Notifiers to pass data to a consumer and that uses "Wait on Notification from Multiple with Notifier History" to re-queue the data to a logging loop that periodically "Flushes" the queue to file.  In theory, this could be lossless as long as the Notifier-Queue MUX loop isn't interrupted by the OS. 2Ch at 3MHz is going to be fast.  I would definitely "Stress Test" a Proof Of Concept simulation before committing to that approach.  I you find the buffers start getting a backlog (reduce the buffer sizes and see if you get any overwrite errors durring stress test) You may need to read all available samples and only place the latest one on the associated notifier.  You will have to accept the data must be lossy in that case.


"Should be" isn't "Is" -Jay
0 Kudos
Message 8 of 26
(3,235 Views)

I'm just getting back to this reply and see that Jeff B and you are already having some discussion.  I partly agree but not fully.  I also have my own mistake to correct.  Here goes:

 

1.  The buffer overflow from my posted example might likely be due to an oversight on my part when tidying wires.  I didn't enforce sequencing to make sure tasks can't start before the file dialog has returned.  The following dataflow sequencing will do that, just branch the output error wire from the file dialog to the left side of the sequence frame:

 

synch - modKP v2.png

 

2. A lurking possible problem is that your file writing is in the same loop as the data acq and is at risk of slowing the loop down and causing the same overflow error.  Jeff B already suggested moving the file writes to another loop and sending data via queue in a "producer-consumer" pattern.  Even after that, 1 MHz sampling may be a bit of a challenge.  Doing it over USB at a 100 Hz loop rate (due to reading 10k samples at a time) may also be a challenge.

   Once you move the file writing over to another loop, try slower sampling or more samples at a time to get closer to a 10 Hz loop rate.

 

3. From what I see here, there's no need to "reserve" the tasks at all.  I considered deleting them in my example, but decided to keep mods to a minimum.

 

4. One place I disagree with Jeff B is about the ability to achieve sync.  You're already [mostly] set up to get it exactly right because you've configured your encoder tasks to be "Arm-Start Triggered."   The likely problem (as I mentioned back at the end of msg 2) is that you aren't programmatically controlling when that trigger signal gets asserted.  I suspect it's a repeating signal that's already present when you run your task, causing one task to be triggered slightly before the other.

   However, now that I've corrected your sequence so the encoder tasks start before the sample clock, you should still be fine if your program starts in the absence of any encoder motion.  The Arm Start Trigger enables the counter to let the count register be updated by encoder motion.  In the absence of motion, the count register stays at 0.  The shared sample clock that starts after the encoder tasks helps keep your acquisitions in sync.

   Again, as mentioned in msg 2, if motion can be present when you start your program, *YOU* must control the generation of the Arm Start signal and it must *not* happen until after both encoder tasks have started.  I'd also wait until after starting the pulse train that's used as a sample clock.

 

5.  Jeff has a lot of insights packed into msg 8, but I'm pretty sure you aren't in the kind of situation that needs them.  From some of the comments, I suspect he might not know about Arm Start Triggers for counters.  Jeff?

 

6. Note that for the data you *did* get, the lag has dropped to just under 1 millisec.  I strongly suspect this improvement came from me de-serializing the encoder task starts (similar to Jeff's advice about de-serializing the reads), making them very much more nearly simultaneous.  Now, you just have to take control over the Arm Start Trigger signal so that they *have* to start *exactly* simultaneously.

   I would guess from your latest data set that motion must have been present at the time you started the program, otherwise I would have expected the data to be perfectly in sync already for all the reasons already stated.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 9 of 26
(3,218 Views)

Kevin.  I'm installing DAQnx for 2017 now.  I wasn't sure if that was an arm start trigger..

 

That said. Deserializing the reads is going to help a lot.  Especially if the encoders are operating at nearly the same speed.  ( Exactly in this case)  


"Should be" isn't "Is" -Jay
0 Kudos
Message 10 of 26
(3,212 Views)