09-23-2013 02:30 PM - edited 09-23-2013 02:31 PM
Hi,
I'm fairly new to LabView, so hopefully I'm just missing something basic here.
I'm trying to control a Maxon EPOS2 motor controller with LabView.
The system has a motor and a position sensor whose ouput is an analog 0-5V signal.
What I'd like to do is have a button on the front panel. When the button is clicked the first time (setting it to "true"), the program commands the motor at some positive constant velocity until the position sensor rises to a particular voltage. Once the voltage is hit, the motor stops. When the button is clicked again (setting it to "false"), the program commands the motor at some negative constant velocity until the position reading drops to a particular voltage. Once the position sensor drops below that voltage, the motor stops.
I've gotten all the individual parts of this to work on their own - I can command the motor, and I can read the position sensor. But doing both of these simultaneously and implementing the logic is giving me trouble. My VI so far is attached.
The general problem (I think) is that the Position Reading isn't getting through to the event structure, probably something related to data dependency between multiple structures. However, I've noticed that if I take out the while loop around the encoder reading portion of the code, the program doesn't read the analog input except for when I click the mouse (and then it's just an instantaneous update, not a live readout).
How can I organize these structures to get the motor behavior described while maintaining a live readout of the position sensor?
Thanks!
09-23-2013
04:17 PM
- last edited on
05-09-2025
09:25 PM
by
Content Cleaner
You need a two-loop solution, because the Event structure only operates once when you give it an event (which you found out). A two-loop solution, when you put it together right, allows one loop to start another (Okay, Move.), then the second loop can continue until it finishes, with all the features you had in that "individual part" VI (STOP HERE!). I'd use a Producer-Consumer architecture, which is designed specifically for when the Producer loop is over quickly and the Consumer loop can take as long as it wants to finish. There was just recently a long discussion of it in this forum (it's a fairly common topic), and there is an NI whitepaper introducing the concept here. (Searching NI for "producer-consumer" also leads to at least 669 hits, one of which was that link).
Cameron
09-23-2013 04:51 PM - edited 09-23-2013 04:52 PM
In addition to what has been said already, you need to backtrack much more, because your code is faulty in many more ways.
Dataflow:
09-23-2013 07:53 PM - edited 09-23-2013 08:19 PM
Thanks Cameron and altenbach! With your advice I was able to get something that functioned the way I'd like. I'm not convinced it's necessarily done the "proper" way though. I attached the latest code for reference and in case either of you have any further advice - I'm new, so I'd love to learn how to do it the right way.
One question I do have is about the queueing. As I understand it, the first while loop is piling position readings into a queue that is first-in-first-out. Then when the second loop executes the event structure, the dequeue function starts pulling data off the queue. But that seems like it would be pulling off old data - the data that was added to the queue during the time the first loop was executing but the second loop was not. Or does a dequeue function only pull data that was collected after it was called? Or is the queue only an element or two big by default, so that it will fill up right away and not grab a new value until the second loop starts dequeueing?
Thanks so much for the help, I was really happy to see the motor act the way I wanted it to!
09-23-2013 08:45 PM - edited 09-23-2013 08:51 PM
Found some issues with my last piece of code, possibly related to my question on queueing. Worked fine in some earlier code where I kept the dequeue inside the case structure, but when I moved it out it looks like it kept trying to read old values (that were outside the acceptable range) so it was exiting the loop immediately. I added in the queue flush to empty out old values so it can read in the most recent data.
09-23-2013 09:01 PM
In both VI's you are continually loading up the queue. Nothing gets dequeued until the TV Control boolean's value changes.
In this VI, when the event finally executes, you get the first element in the queue, the oldest.
Previously, you were flushing the queue which emptied it out. Then it waits at the dequeue waiting on the next element which is going to be very fresh.
Is there a reason you are using the queue? If you are discarding all of the old elements in the queue, what's the point of queueing things up? You might as well use a notifier which gives you the latest element.