Hi all. I am working on a VI that talks to a laser shutter controller, Thorlabs SC10. The device only has an RS232 interface. I have adapted the RS232 port with a serial device server so my VI sends commands and receives responses with TCPIP vi's. The VI only does three things, it send an Enable command, and it polls the device for the state of the shutter (open or closed) and the interlock port every 500ms.
But here is my question. We have ten such shutter controllers. I would like to have all ten shutters controlled from the same Master VI. The problem is that the VI gets jammed up if one of the controllers is not connected. I am thinking that I want to be able to turn instances on and off but have not been able to figure out a good way to do it.
A brute force method would be to just run multiple versions of the VI and give them different names like shutter1, shutter2, etc. So there would be ten windows open if I had ten controllers running. Seems like there should be a better way.
I tried researching and trying my own ideas but so far nothing works exactly right. The VI has two parallel While structures: one has an Event structure and sends the Enable command when I press a button. The second has a frame structure that reads the shutter state, then reads the interlock state, then waits 500ms, and then repeats.
I tried using case structures so the VI isn't really off, just jumping around the part that sends commands out.. I can turn the read functions on and off that way but the Event structure gets jammed up if I try it when case structure bypasses the Event structure.
I tried various other things like putting the two While structures in an outer While structure. That didn't work either. Always seem to get stuck in the Event if I press the send command.
I did searches for thing like "turn parts of a VI on and off", "turn while loops on and off" etc.
Open to any ideas
Solved! Go to Solution.
When you have multiple more-or-less identical things you want to do at the same time, you absolutely want to develop a VI that will "do what you want", and then run multiple instances of this VI. I'd recommend making your "multiple VI" have the "pre-allocated re-entrant clone" property, and "launching" as many as you need using Start Asynchronous Call. You communicate with them via their Front Panel Controls, passing in a Queue so they can send data back to you through the Queue.
You've provided little information about your Shutter devices. I presume you have a way to detect if Shutter X is connected -- you'd want to initialize your system by simply testing all 10 Shutters and (for example) creating a Boolean Array called "Connected". Depending on how you are communicating with your multiple Shutters (are they all supposed to "click" at the same time? At the same rate? Can they run at their own pace, and maybe start and finish at different times, or is everything synchronous?), you could using the "Connected" array to "gate" which "Array of detached Clones" is sent commands and returns data. Arrays are really useful for managing multiple devices, and Clusters are really useful for organizing the disparate data elements that are peculiar to each device (such as its identifier, 1,2,3, its particular set of input parameters, if some differ, its output Data Array).
Been there, done that.
Thanks for the reply. The only way to tell if a shutter is connected is to send it a command and see if you get a response back.
The operation would be asynchronous. The shutters are part of a safety system so we need to open them remotely after we leave the room with the laser. So basically, we will just press the open shutter button when we get to the control room but I have the VI checking the state of the shutter every second because it someone opens a door, the interlock connection will close the shutter.
I can post my VI. It just take a bit of work because it is on a different network. Also there are a few sub vi's so i have figure I have to post all of it....maybe as a zipfile.
I am really far from a Labview expert as Labview programming is not my primary work. I know enough to stumble through making relatively basic programs. The stuff you mentioned like "pre-allocated re-entrant clone property" is pretty far out of my experience. No idea what that is. i will work on posting my VI's maybe there is a simple approach.
I just don't want, for example, Shutter4 to be operable if we know it isn't connected.
I will post my VI's in a few minutes
but I have the VI checking the state of the shutter every second because it someone opens a door, the interlock connection will close the shutter.
I hope your program is ONLY checking the state of shutter, all interlocks should be hardware based for safety.
As far as your program goes, can you use the fact that a shutter doesn't respond to let you know it's not active, and then just close the connection?
I have attached a zip file with the main and sub vi's
Be gentle. I know there are some things that aren't "best practices". I wanted to get something working quickly.
Anyway, what I would want is basically just ten versions of Shutter #1 controller in one window but be able to "turn off" the ones that aren't connected. But, it needs to be "idiot proof" so that if someone clicks on the Enable button for a turned off shutter, it doesn't lock up the program.
The interlock is totally hardware based. The SC10 has a mini-phone jack in the back that must be shorted for the shutter to open. Via the RS232 port, I can send a shutter open command but it won't open unless the interlock connection is shorted (closed). My VI does check the state of the shutter and the state of the interlock once a second. This is for troubleshooting so we can see in the control room of the interlock is made up.
Like i said in my first post, i tried several schemes to turn a shutter "channel" on and off but none of them exactly worked right. The Event structure with the Enable button get locked up if I press the toggle button when the channel is off.
This may be too hard to figure out over a forum.
This is why I tried to make the problem more generic as in "turning VI's on/off" or "turning while loops on/off", etc.
My VI's are posted now.
The Event structure with the Enable button get locked up if I press the toggle button when the channel is off.
Your event structure is set to "Lock Panel" until event completes; thus if your subVI "freezes" so will your front panel. To get around this you could
The other problem is you are constantly querying the status of the shutter in the bottom loop; if your resource is not there your bottom loop is going to freeze up also.
Below is a quick example to get you started.
hey McDuff. Thanks for the reply 🙂
"The other problem is you are constantly querying the status of the shutter in the bottom loop; if your resource is not there your bottom loop is going to freeze up also."
We have to keep polling the controller because we have no way of knowing if the interlock got crashed. But that is the reason why I wanted a master on/off control for both loops.
I found a simple solution that works perfect with the bottom loop but only partially works with the top loop. I put the polling sequences in a T/F case structure. This works great with the lower loop. True runs the reads and false run a short WAIT.
I tried this with the upper loop too and it works ok unless you click the Toggle button when the case is false. Then it gets stuck because the latched boolean doesn't reset.
I have another version with only one while loop. basically I put the lower loop reads into the Timeout frame of the upper Event structure and set the timeout to 200ms. If I then put the Event structure into a T/F case structure, it get the same problem. The Toggle switch latched Boolean doesn't reset if the Case is in the False (off) position and someone were to click the Toggle button. Both versions work with the case structure to do the On/Off function. They just aren't idiot proof if you click Toggle when the Case is False. I will post the vi.
here is a version with only one while loop and event structure. My attempt at the On/Off function is with the added Case structure. This works unless you press the Toggle button when the Master on/off is is the OFF position. The latched boolean doesn't reset.
This works unless you press the Toggle button when the Master on/off is is the OFF position. The latched boolean doesn't reset.
That is because the boolean is in the event case. One way out, would be to move the toggle boolean into the while loop.
Another way out, which I recommend, is to make a State Machine. I recommend the JKI State machine, or you can use one of NI's State Machine templates.