LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Increase Speed of DAQmx Sequence

Hi Everyone.  I'm working on my first Labview program that will use a stepper motor to apply a load which is measured using a loadcell.  I'm using a stepper motor driver that takes digital output from my NI USB-6009.  I'm struggling with how to improve the rotation speed of the stepper.

 

An image of my basic program is attached.  I've tried to make the labels on the tasks explain what each digital signal is responsible for.  I'm hopeful that when I contain the sequence within a while loop the motor rotates quicker than what it does.  Does anyone have an suggestions on how I can improve the speed of the program?

 

One thing I was thinking about was instead of passing an individual F and then T to the driver to create the step I could put both the F and T into a waveform.  Unfortunately I haven't had any luck in making that happen with my limited knowledge.

 

Another thing that I don't fully understand are the options in the DAQmx write function so I suspect I may be able to do something different there.

 

Any suggestions and help that could be offered would be very much appreciated.

 

0 Kudos
Message 1 of 8
(2,908 Views)

Hi,

 

Can you explain how the motor stepper works in your program.  Do you have to run the MS1-3 in order?  A little description would be helpful. 

If the step pin is the on/off or motion command, and the MS pins are only magnitudes (?) or something, you would want to put the step T/F toggle in a loop, with the MS channels outside the loop ( I'm thinking they only need to be set once?)

 

You can feed the step pin a waveform, or array, or just use a loop that runs for a set time.  There are a lot of options. 

 

-------
Mark Ramsdale
-------
0 Kudos
Message 2 of 8
(2,898 Views)

Hi Mark,

Thank you for your reply. I'll try to further explain:

 

- the MS1-3 are digital signals that control the angle of a single step for the stepper motor. The stepper that I'm using has a single step angle of 1.8 degrees however the driver allows that to be reduced to half, quarter, eighth, or sixteenth. This is set by the specific combination of high and low values from the MS1, MS2, and MS3 pins. For example, if the desire is to have the motor rotate with a step resolution of 0.45 degrees I would assign MS1 = H, MS2 = L, MS3 = H.

 

- the DIR is a digital signal that controls direction of rotation.

 

- the STEP pin is a digital signal that first goes to low and then to high.  The driver detects the raising edge of the high signal and make the stepper motor rotate by one step using the parameters defined by DIR and MS1, MS2, and MS3.

 

- If anyone is curious I'm using "Big Easy Driver" to operate the stepper (http://www.schmalzhaus.com/BigEasyDriver/BigEasyDriver_UserManal.pdf)

 

- I've modified the block diagram (please see attachment) slightly just to give an idea what I'm trying to do.  My goal is to just get the stepper to spin as fast as possible so I believe optimizing whatever is in the while loop is what I want to accomplish.  Once I feel that I've got the best speed I will remove the while loop and turn the program into a SubVI.

 

- I'm very new to Labview but I'm guessing that using a waveform that goes from low to high could replace the last two DAQmx write functions with one.  I'm struggling with creating the waveform as well as what to select from the write funtion "polymorphic selector".

 

- Is there a preferred method of the sequence structure?  I believe that the DIR and MS1 - 3 pins must be established prior to the STEP signal and using the sequence is how I have tried to control this.

 

Again, thanks for any help that can be provided.

 

0 Kudos
Message 3 of 8
(2,869 Views)

Hi there,

 

You won't be able to use a waveform datatype with a 6009 -- it only supports software-timed digital output.  So that sticks you with software timing, the way you're doing now.

 

You will need a timing function in your loop...otherwise it will spin as fast as it can, take up your computer's entire CPU, and eventually screw things up to a point where you're looking at ctl-alt-delete to try to get out of it.  Search "greedy loop" on this forum for more information.  You might be able to run your loop at 20Hz (put a 50msec time delay in it), but with a Windows processor, you won't get much better than that.  If you need faster digital output, you'll need a board that supports clocked digital I/O.  So how fast is "fast"?

 

You do not need a sequence structure.  You should use the error wires to enforce dataflow.  Merge the error wires from your MS1-3 DAQmx Write functions using the "merge error" function (it's on the Programming palette under "Dialog and User Interface"), then use the output of the "merge error" function as the input error wire to your "Step" DAQmx Write function.  In fact, you should always wire the error wires through, and you should stop your loop in the event of an error.  Otherwise you can have errors occurring that you won't see, leading to funny behavior that you'll have a devil of a time tracking down.

 

You probably want a small time delay between when you write "Step" F and when you write "Step" T.

 

Finally, straighten out your wires.  It may seem trivial, but it makes a huge difference in the readability of your block diagram.  As your code becomes more complex, that will be more and more important.  It's also a nice courtesy to the folks whom you're asking to review your code.  Smiley Happy

Message 4 of 8
(2,843 Views)

Hi Diane,

 

Thanks for taking the time to respond.

 

I followed your advice about removing the sequence structure and using the error wires to control the order in which the functions are executed and it worked great.  Error wires are something that I have a lot of learning left to do on but you've shown me a technique that I did not know of before.

 

I've also cleaned up the block diagram as you suggested so it looks much neater now 🙂

 

The goal of this VI was simply to see how fast I could make the motor spin with the USB 6009 and the stepper driver that I'm using.  I ran the loop as fast as possible for 30 seconds (using the elapsed time function to stop) which resulted in ~15,000 iterations being completed.  With each iteration resulting in 1.8 degrees of rotation I was rotating the motor at 150RPM with the USB 6009 sending digital signals at 1000Hz (one high and one low for every iteration).  Thanks for pointing me towards "greedy loops" as well.  I searched the forums and now I think I have an understanding of what they are (loop without delay will use all CPU resources).

 

My long term plan is to apply a load with this stepper motor that will be measured by a load cell.  The VI that I've posted will be made into a SubVI along with another SubVI that takes the load from the load cell.  The basic idea is that I'll have a target load and if the load measured by the load cell is too low then the motor will turn in direction 1 but if the load is too high the motor will turn in direction 2.  Any obvious flaws in the concept?

0 Kudos
Message 5 of 8
(2,824 Views)

Hi John,

 

I am happy to hear that your block diagram is now tidy.  Smiley Happy 

 

As I see from an earlier post, your intent is to remove the while loop from the block diagram, encapsulate the remaining code into a subVI, and call the subVI from a while loop.  Am I correct?  If so, it might be a good idea to think things all the way through:

 

- Load cell measures a load.  If load out of range, subVI containing motor logic / commands executes one time.  Motor moves 1 step.

- Load cell measures a load.  If load out of range, subVI containing motor logic / commands executes one time.  Motor moves 1 step.

...

- Load cell measures a load.  If load out of range, subVI containing motor logic / commands executes one time.  Motor moves 1 step.

 

Is that the way you want it to work?  Because that's the way it's going to work.  (assuming that the load is out of range, as you specified...if the load is within range, I presume that the subVI won't execute)  Your motor will move 1 step at a time, in response to each measurement.

 

To me, that seems like a completely reasonable way to do things, but it also doesn't match the purpose behind the VI we've been talking about...which was to get the motor to move as quickly as possible.  What am I missing?

 

Also, a question:  did you create your tasks in MAX?  That's a perfectly fine way to do things, but it is going to make moving your VI onto another computer kind of a pain -- you'll need to export the MAX configuration settings.  It's just less portable.  Maybe that's never going to be a problem for you, but keep it in mind.

0 Kudos
Message 6 of 8
(2,798 Views)

Hi Diane,

 

You're correct for the most part.  The motor will be used to apply/maintain a load on an object.  Let's say that a CW motor rotation applies load while a CCW rotation releases load.

 

- load cell subVI measures load and provides output to main VI.  If load is too low then subVI containing motor logic executes one time with single step rotation in CW direction.

- load cell subVI measures load and provides output to main VI.  If load is too high then subVI containing motor logic executes one time with single step rotation in CCW direction.

 

This will all be contained within a while loop (with a slight delay to avoid it becoming greedy as you mentioned).  Load would be held for a fixed period of time or until the user wishes to abort.

 

The purpose behind the VI we've discussed is to get an understanding of the max speed that the motor can rotate with the hardware that I have.  When I first started with my VI I was nervous that the rotation speed I could achieve wouldn't be fast enough so I figured a good task would be try to optimize it to be as quick as possible.  I understand that the process will slow down once I incorporate the load cell subVI and some limit switches but at least I feel good that the motor subVI is optimized.

 

Thanks for the advice on tasks in MAX.  That's how I did create them.  I'll have to research on what the best practice is for tasks in the future.

0 Kudos
Message 7 of 8
(2,793 Views)

It all sounds good and should work just fine.

 

I like to create my tasks explicitly in LabVIEW.  You can use "DAQmx Create Virtual Channel" to do that.  You will create your tasks once, outside your while loop, and then clear them after your while loop has finished executing.  It makes the application more portable, is all.  Just for future reference.

0 Kudos
Message 8 of 8
(2,790 Views)