LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Barrels of LabVIEW

Hello all you princes of code, you kings of LabVIEW!
 
I'm working on my first LabVIEW program and running into a few snags. The program is for operating a lift that takes a barrel from a loading station and then drops it off in a particular tank for a certain range of time before retrieving it and dropping it off in the next assigned tank. There are several tanks and as far as getting the lift to move between them, that is solved through the use of a photo eye to detect reflectors on the side of the tanks. This part, I get and understand. Here is where the issue comes up...
 
There are 4 different "routines" that the lift has to be able to run. Not all the tanks are used for each routine and not each routine is used every time. For example, Routine 1 would have the lift only use tanks 2,4,6 while Routine 2 would use only tanks 3,4,7. I can get the lift to perform one of the routines one at a time, but how would I go about getting the lift to perform multiple routines at the same time?
 
So to summarize, I need someway to get the lift to move multiple barrels through different tanks while also remembering where the barrels have been placed so the lift can go back after a certain time range and retrieve the barrel for transport to the next tank in that routine.
 
If somebody could just type out the thought approach on how they would go about coding that I would be MOST appreciative. I am thinking the use of queues is going to be very important but the fact that it has to (A) keep track of what barrel needs to go where, (B) where each barrel was left, and (C) when it is time to head back to retrieve a barrel because time has expired. I just seems like a huge rubix cube to me.
 
Thank you folks and maybe in 6 months I'll know enough to answer some questions here instead of just ask them.
 
 -- Matt
 
 
 
0 Kudos
Message 1 of 23
(4,253 Views)

Hi Matt,

      I think a single queue solution might work very well. Smiley Happy  You might implement each "Barrel" as an independent program (a reentrant VI.)  When a barrel-program decides it's time to be moved, it sends a barrel-identifier, "From Vat#" and "To Vat#" to a Lift-driver via a Lift-command-queue.  The Lift-driver need only go where it's told, pick-up the specified barrel, and deposit it where told.

The [reentrant] barrel VIs need not be permanent diagram objects (as shown in this example) they could be launched dynamically and will run completely independently of where other barrels are in their processes.  This example makes no attempt to deal with resource scheduling! (given a limited number of "slots" per vat...)

Cheers.

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
Message 2 of 23
(4,141 Views)
Hot dog! You made my day! Many thanks plus one more for the example! I'll see what I can do with this newfound knowledge.  Again, thanks for the quick reply! If I can get this thing working I'll carve your name into my desk as a tribute or something.
 
-- Matt
Message 3 of 23
(4,119 Views)


...  I'll carve your name into my desk as a tribute or something

Smiley Very Happy
Thanks - I needed that!
 
 
"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
Message 4 of 23
(4,085 Views)
Okay two questions for any kind soul out there with a few minutes to devote to a struggling labVIEWer.
 
The above barrel.llb example is great and very similar to what I am trying to do. How would I get the program to wait until a button had been pressed before starting each barrel process lift sequence? For example, say I only want to run one of the barrel re-entrant VIs or start a second barrel re-entrant a few minutes after the first one has started.
 
I tried using dataflow and event structures to keep the data from passing to the re-entrant VIs, but the program just locks up. I'm missing something.
 
And lastly, as far as resource scheduling, to ensure that each "vat" only can have 1 barrel placed in it at a time, I am thinking I would use global variables to keep track of which two vats are currently occupied and place a delay in the re-entrant VI to keep any new barrels using that vat to be added to the queue until that vat is clear. Would this work or am I off track yet again?
 
Thank you folks! This forum has become a daily read for me and some of you impress me with not only your knowledge, but your friendliness and willingness to share your wisdom.
 
-- Matt
0 Kudos
Message 5 of 23
(4,032 Views)
Okay I figured out how to get each re-entrant barrel VI to run independently. I attached a .gif file of how I achieved this. In my program, I have 4 different barrel VIs so this solution just seems messy, still curious if there is a better way (which I'm sure there is). I suppose I could just create a subvi to hide some of the clutter. I used a while loop for each "Start" button and had that dataflowing into a sequence structure containing each barrel subvi.
 
Still not sure exactly how to keep the lift from dropping a barrel into a vat that already contains a barrel. I'm still thinking global variables is the way to go, but the two books I read on LabVIEW made globals sound like evil, evil monkeys.
 
Thanks again!
 
 
0 Kudos
Message 6 of 23
(4,012 Views)

Hi LVNube,

      A "cleaner" solution might be to launch the Barrel VIs dynamically "on-demand" so to speak.  Search examples and subjects re: "VI Server".  Running VIs "dynamically" is a very common practice - though less so with re-entrant VIs.  You'll want to create a VI that takes the Index, Occurrance, and Queue as parameters and launches an "instance" of Barrel.vi - which will then exist in memory - but nowhere on a diagram.  In this case it will probably be good for each "Barrel" to have a unique "Quit" occurrance.  Note:  LV8.0 or 8.2 introduced user-definable class objects which offers another (similer) solution to your application, but my experience with these tools is Nil.

I'd like to help more but can't until much later. Smiley Wink

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 7 of 23
(3,996 Views)

Thanks again tbd! I'll read up on that and do some homework on it tonight. I didn't fully understand the advantage of dynamically loading VIs until your last post. I was assuming the sole purpose of them was to save room in memory.

 

I'll also try my global variable idea out. Everything ON PAPER or IN MY HEAD always seems so easy until I get to coding it. I guess as they say, "the devil is in the LabVIEW details".

 

-- Matt

0 Kudos
Message 8 of 23
(3,989 Views)
Matt,

A semaphore can be used to limit access to a finite resource - your vats. Each time a barrel is moved to a vat it must first obtain a semaphore for that vat. When it leaves it releases the semaphore. Look under the Synchronization palette.

Lynn
Message 9 of 23
(3,984 Views)
Thanks for the reply Lynn!
 
I actually thought of using semaphores, but the vats are numbers stored in 4 different clusters (the example uses 2). The information in these clusters are then fed to 4 different subVIs to provide them with information on what vat the barrel goes to and how long it is to spend there. I understand how to use semaphores to lock out subVIs or functions, but can you use a semaphore to lock out an element of a function?
 
To clarify, can a semaphore be used to say, "Lock out these particular numbers (vats), but all other numbers (vats) are fine"?
 
Thanks for all the help! I answered a question on here yesterday and it felt good to give back to the community.
 
-- Matt
0 Kudos
Message 10 of 23
(3,942 Views)