I am using a NI 9401 to send a pulse train to a servo drive using Counter Output to command a position move.
Position to Pulses.vi creates the array of high and low times which is written to the CO. This kind of works for frequencies less than 500 Hz, but anything higher and the actual number of pulses sent quickly becomes more than what is in the array.
Also, when the frequency increases, the amount of time the move takes increases past what it is supposed to.
I have the CO wired to the CI to verify how many pulses are sent.
I am not very familiar with Counter so any insight here would be helpful. Any ideas of why the CO is not matching the array i am sending it?
Solved! Go to Solution.
I made a few very minimal changes with brief comments to get your code to run on a desktop X-series device here. I didn't take a hard look at your "position to pulses" code but some stuff looked suspicious -- you may have some work to do there. You'll want your graph to show Freq vs Time, not sample # vs. I-don't-know-what.
Thanks Kevin, that seems to work.
However, I am unsure how to implement this into my larger program. My concern is: In the full program, this cycle needs to be immediately ran again, but in the opposition direction. Those 2 (half cycles) make up a whole cycle. Then that whole cycle is repeated thousands of times.
This is why I thought reserving the tasks may be necessary, because the same card is inputting and outputting continuously and that's how I've gotten similar things to work in the past. Admittedly, I don't really know how or when to use Reserve Task correctly.
I haven't used buffered tasks before. How do I accomplish what is described above? Does Samples per Channel have to be 2X? Should there be Start Task after every Write Task? Do I need to Stop Task before the next Write Task?
Here's what I was trying to do for this iteration:
Trying to understand the basic logic of how this all works.
Reserve is where a DAQmx task stakes its claim to internal resources but doesn't yet use them. Sometimes you need to reserve a task before you query for certain properties that only get defined at the Reserve stage. Commit starts to use those resources (buffers, internal signal routing connections) and gets the task as near to starting as possible. When a counter output task reaches the Commit stage, its output will be forced into its defined Idle State.
One subtle aspect of the DAQmx Task State Model is that a task can be stopped and restarted more efficiently if you explicitly Commit before starting. Dunno if you need that extra efficiency here (it's only a small # of msec savings typically), but I suppose it doesn't hurt.
You do NOT need the 2x factor for # samples when configuring DAQmx Timing. 1 "sample" for counter output will include both of the pulse timing parameters (either Freq & Duty Cycle, or Low Time & High Time). To generate 1000 pulses, you'll have a size 1000 array of pulse timing parameters to write.
I did another little simple mod to wrap up the pulse control code into a subvi that I called "pulse and wait". It uses dataflow to make sure the direction DO line is set first, then it starts pulse generation and waits for them to complete. I then added a msec Wait function you can use to give the stepper some settling time before reversing direction. The default wait is 0 though.
If you plan to generate the same set of pulses every time, you don't need to rewrite the data. You can just Stop and re-Start and the task will have retained all the pulse data and reuse it. So here's a snippet to show how to use the subvi in your overall main loop. I added another optional time delay between each out & back movement cycle.
The pulse and wait function itself is pretty simple too, here's a snippet and I'll also attach the vi.