LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

loop iteration timing in milisecond resolution

I am using a USB DAQ to control the opening and closing of two micro-fluidic water nozzles.  Basically the program works by using a while loop that iterates every milisecond (with the wait until next multiple ms set to 1), and every milisecond it should check to see if it should "open the nozzle". 

For example:
frequency is set to 1 Hz and High Time is set to 500 ms (this means that the digital signal is 1 Hz with 50% duty cycle)
so everytime the while loop iterates, it checks to see if
                 the remainder of Current Time (ms since the execution of the program) / Period is less than High Time.  if this returns true then it writes the boolean value "true" to the                         DAQ and it opens the nozzle.  if the remainder of that equation is higher or equal to High Time, then it writes the boolean value "false" to the DAQ and the nozzle closes.

                in other words, during the first 500 ms, the remainder of Current Time (<500) divided by Period (1000) is always less than High Time (500) so it is true and the nozzle                         opens; on the 501 ms, the remainder of Current Time (501) divided by Period (1000) is 501 which is greater than High Time (500), so it is false and the nozzle closes.

My code seems to work fine until the High Time is set to less than 10 ms.  Sometimes the nozzle doesn't open when it is supposed to.  It just gets worse and worse as the High Time goes down. 

I made a few simple VIs to test various timing issues and i have noticed the following:
1. When I set Wait until next multiple ms to 1, it doens't actually force the while loop to run every millisecond.  the iteration count is actually about half of the milisecond count.
2. When I set Wait until next multiple ms to 0, the iteration count way way exeeds the milisecond count, so this proves that the while loop is capable of running at a much higher speed than the milisecond timer.

since 1 is the lowest number i can set Wait until next multiple MS, i can't seem to make the loop iterate at exactly once every ms...
i believe this is the main problem with the program.  Is there any way to fix this or alternative ways to force the while loop to go once per ms?  I have read some of the posts and i have seen many suggesting that Windows is incapable of sub-two-digit ms timing.  Is this true?


Thank you all for your help!!
Much appreciated



0 Kudos
Message 1 of 5
(3,232 Views)

@Fan Wu wrote:
I have read some of the posts and i have seen many suggesting that Windows is incapable of sub-two-digit ms timing.  Is this true?

Yes ...  and no. A while loop that has no delay in it is also known as a "greedy loop". It will spin as fast as possible. What that rate is depends on your CPU and whatever else you're doing. While it's possible to have a delay of a few milliseconds, it's not guaranteed in an OS like Windows. Thus, in one iteration you could get your 5 msec, but in the next iteration it could be 15 because Windows decided it's time to check on security updates, or some other silly thing. See here for a similar question.

This means you probably need to use your DAQ to control your timing by, for example, creating a waveform that corresponds to your required duty cycle, and have the DAQ generate that waveform. When the waveform is high, the nozzle is on. This way you can get extremely precise timing.
0 Kudos
Message 2 of 5
(3,214 Views)
Thank you very much! I will try it out using DAQ timing.
0 Kudos
Message 3 of 5
(3,195 Views)
I'm new with hardware timing, could you please elaborate on your previous suggestoin?

Right now I'm trying to use Counter Output frequency to generate a digital signal to CTR0 OUT.  However, I realize that I only have two counters and eventually I will have to control more nozzles (say 4), each nozzle will have different timing properties (frequency, duty cycle, inital delay etc). How can I create multiple timing channels with hardware?  Also, I would like to create a graphic or numeric indicator so that I can count the number of peaks and see the digital waveform.  But I have no idea how to display the data output by the Counter other than connecting CTR0 OUT to an oscilloscope which is not very accurate.

Thank you for your help!!


0 Kudos
Message 4 of 5
(3,161 Views)
Hi Fan Wu,
 
You're right that you only have two counters on your USB DAQ device. If we limit the problem to only one channel, then I would recommend using the counter because it sounds like you're creating a pulse train of known parameters. Since the counters use a fast timebase (if you're using Mseries you're using an 80MHz clock), you'll get very predictable performance at 1ms of interest.
 
The other way to do this (since you'll need more channels) is to use a counter to setup a timing engine. A simple pulse train with 50% duty cycle and whatever frequency you're interested in (sounds like 1kHz) can be used as your DI/O timing clock. You can then create a digital waveform with the characteristics you are interested in and write that to your buffer. With your Digital task correlated to your counter output, you can output this waveform at the rate of your counter output.
 
While this is NOT the end application you are looking to write, this example has some great parallels to what you are trying to do. It illustrates creating a clock with the counter and then writing a digital waveform to correlate to that clock.
PBear
NI RF
0 Kudos
Message 5 of 5
(3,122 Views)