Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Ramping a pulse signal using PCI-6602 card

Here, I saved the ni.com example back to v 7.0. While it looks like it ought to work to get you started, I don't think I'd do things quite the same way. In particular, I'd recommend using the event structure to catch "value change" events for frequency and duty cycle rather than polling and storing previous values in shift registers.

I also thought the suggestion from pp42 was an especially good one -- to use a timed loop with the counter output as the timing source. One of the pitfalls of changing freq / duty cycle in a regular while loop is that for low frequency pulse trains, you could try to change the freq / duty cycle values a 2nd time before a full pulse has completed using the 1st values. This will give you an error. Under a timed loop, you can be sure that the freq change will produce a pulse or more before the next time the loop executes and you change the freq again.

I suspect that to make it work out properly, you may need to execute every 2 ticks rather than every 1. But I'm not really sure as I haven't really tried out the timed loops much. They run at very high execution priority, which can be a Very Good Thing, just not something I've happened to need yet.

Good luck!

-Kevin P.
ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 11 of 21
(3,394 Views)
Thanks Kevin
Just a warning if your timed loop is late for updating the last time you may still find that you get an error trying to change the frequency to fast.
pp42
0 Kudos
Message 12 of 21
(3,391 Views)
pp42 - could that possible error be avoided by configuring the timed loop to ignore missed iterations?

-Kevin P.
ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 13 of 21
(3,389 Views)
Thanks Kevin,
Trying to modify the vi to do finite generation with speedup of fixed increments at regular intervals (want to send 100 pulses starting at 500Hz and trying to get total time < 0.1s). I'm getting an error saying I can't update the frequency without stopping the task first. Putting in a stop and start seems to produce speedup but I get too many pulses.

Also, should I be using an external timebase? Am I correct in thinking I can run a line off the counter output into a PFI terminal on my SCB-100, and then in Labview wire the channel into CO.CtrTimebaseSrc in the property node? How would I work with those ticks?

Best wishes,
Will.
0 Kudos
Message 14 of 21
(3,381 Views)
Hello Will.

When you say that you are getting too many pulses, how off from 100 are you? As far as using an external timebase, that's exactly how I would do it; I would use the CO.CtrTimebaseSrc property node. Have a great day!

Sincerely,
Marni S.
0 Kudos
Message 15 of 21
(3,363 Views)
Hi Marni,
Based on the final position of my step motor shaft, I would say it's putting out ~30 pulses too many. The attached pic shows the error I get. Is this error simply because I do interrupt the task with a stop to update freq, or is it something else I have not considered?

Also, if I do specify the timebase from the counter output with a property node just before the reserve task vi, how can I use those ticks to help me control timing of the freq update for loop?

Best wishes,
Will.
0 Kudos
Message 16 of 21
(3,360 Views)
Will,

You've got a fairly difficult problem. You want to:
a) ramp a frequency up or down
b) exactly control the total # of pulses

It's fairly straightforward to do either a or b, but both at once is trickier. The fact that you're using the pulsetrain to drive a stepper motor adds another complication.

1. You're ramping a stepper. So you definitely shouldn't plan to stop and re-start your pulsetrain. Any frequency changes need to be done on-the-fly. [see note 3 below]

2. The warning message occurs because you've defined a # of pulses for the "finite sampling" task. However, you are then stopping that task every 10 msec -- probably not long enough to allow all those pulses to be generated.

3. I also had an app for driving a stepper for a precise # of pulses. I also tried to ramp the frequency up by changing frequency on-the-fly. I got an error too. The reason is because of how DAQmx actually implements a finite pulse train. (Description based on inference and having looked under the hood at the traditional NI-DAQ implementation. Would welcome corrections from any NI person.)

When you ask for a finite pulse train, the counter is actually configured for a "gated" (traditional NI-DAQ term) or "pause-triggered" (DAQmx term) continuous pulse train. Then the board's other counter is used to generate a single pulse. In this setup, your counter only shows pulses at its output pin while the other counter is within its pulse's ON time. By precisely controlling this ON time, you can also control the precise # of pulses that reach the output pin of the main counter.

The problem is that if you change the frequency part way through, the original timing relationships would no longer be true, which could cause you to produce a different # of output pulses. So DAQmx gives you an error in order to make sure you get exactly the # of pulses you asked for.

4. I had an idea for how to implement a precise # of pulses with a varying frequency, but had to abandon it because the method required a minimum of 2 pulses. In my app, I frequently needed to generate 1 single pulse. (In the end, I had to live with constant-frequency stepping. The slower speeed was only an inconvenience for total test throughput -- it didn't affect the system under test.)

I never implemented and tested the idea, but here's an outline of what I remember:
A. Setup counter 0 for pause-triggered continuous pulse generation, using output of counter 1 as the pause trigger. I think the active pause trigger level should be Low.
B. Setup counter 1 for edge counting, using an initial count == total # of pulses. Configure it to count down (decrement) on active edges and configure its output to "toggle" on terminal count.
C. In your vi, be sure to start counter 1 before counter 0. You should also stop counter 0 before counter 1.
D. In your vi, you can query the count of counter 1 to determine how many steps are left -- this may help you decide when to start ramping down.
E. In your vi, you can vary the frequency of counter 0 on-the-fly without generating an error!

More Description:
Counter 1 is programmed to count down counter 0's step pulses. When counter 0 is started, pulses will appear at the output right away because counter 1's output starts low. Each pulse decrements counter 1 until counter 1 counts down to terminal count (0). On that edge, counter 1's output switches to high (because it's set to "toggle" on terminal count). At this point, pause-triggering stops counter 0's pulses from reaching the output pin. And counter 1 stops receiving edges to count down. By querying counter 1's output state, you can detect when this happens and stop the counter tasks.

-Kevin P.
ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 17 of 21
(3,348 Views)
Kevin, discarding the missed steps definitely would help and I have set my program to do so but I also catches and discards the -200301 error and I’m not sure why. Perhaps it’s because I’m over paranoid or perhaps there is something to it, I remember testing it a bit, but then again I am the paranoid type.
One other way to handle this is to set the frequency to 4 or 3 instead of 2 to move away from the edge.

I’m adding an old version of the program I have made, it should allow you to ramp up and down a frequency train and take a specific number of steps. This is a test version only! The final version sits in the program now and appears to work although it’s not finally tested yet and contains more references to other stuff and is therefore not easily shared but it is basically the same. I’m happy for any comments and test result good or bad.

I to had the same idea as Kevin and tried to modify an existing example that used the internal time base as source for both counters. I had to two problems with it:
It is difficult to get a good control of the acceleration and more importantly I could not get it to work but in my mind it should be possible to do so.

pp42
0 Kudos
Message 18 of 21
(3,344 Views)
pp42,

I tried your example out quickly. It seemed to work pretty consistently for sub-kHz frequencies. It gave results that were more erratic as I ventured toward the 10 kHz vicinity. I suspect it has to do with depending on the 'Wait (msec)' software call to provide the timing for stopping the pulsetrain.

I tried implementing the idea I outlined earlier in the thread and got it to work properly -- able to produce exact # of pulses specified while varying the frequency on-the-fly. The initial version just allowed me to change the frequency via a control on the front panel though -- not too useful yet.

I next added a timed loop to be able to update the frequency in a more mathematically correct way, using the pulsetrain as the timing source for the loop. That part needs some more work. This is the first time I've done much playing around with the timed loops and the app occasionally keeps pulsing continuously.

I'll try to polish it up a bit and get it posted, though it may be a few days. Meanwhile, the description I gave earlier in the thread is pretty much what I did. The main little gotcha is that the initial count value must be set to a value 1 LESS THAN the # of steps desired. And you must have a total # of steps >= 2 (initial count >= 1) for the method to work.

-Kevin P.
ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 19 of 21
(3,314 Views)
Kevin
In my experience maximal frequencies up to approximately 15-20 kHz is possible if you have a decent ramp length and a low enough start/stop speed.
I have played with the idea to include your idea as the limiter to guarantee a given number of steps, but since my application at most moves at 500 Hz I haven’t had the time or urgent need.
A different (and probably better) method for handling the final step is to change the frequency off the loop to one and then to exit at the final step. This way the program ends in the second half of the final step and the problem handled by the wait function is eliminated.
If you believe that my implementation might be something you might want to use or modify feel free to do so.
pp42
0 Kudos
Message 20 of 21
(3,299 Views)