Doug Harper Posted February 8, 2016 Report Share Posted February 8, 2016 Hello: I am working on an application where a main User Interface will need to open a subVI for a motion control system asynchronously using a menu selection. The motion control subVI should run independently in its own window separately from the main application that initiated it. I have the code working using the following ... This works fine up to a point... the subVI opens in its own window and runs independently in its own window. I use VI server within the subVI to open its front panel on startup. The problem occurs if the subVI hasn't been closed/stopped yet and the user selects the menu item again from the main UI. An additional instance of the subVI is queued up serially. If the user then stops the subVI then the other instance starts right up again. What I thought would work to avoid this problem is to check to see if the subVI is already running when my menu event triggers and if so just bring its window to the front using some code like... and then if it is Idle I would call the subVI asynchronously using However, the VI server call for the execution state never returns idle. It always returns Running even though the subVI hasn't been started yet. I was surprised by this, expecting it to return Idle when the subVI hadn't been called yet. Does anyone have suggestions for starting this subVI and if then if it has already been started to just bring its front panel to the front? Thanks, Doug Harper PS. Please ignore the incorrectly labeled global variable that is passed to my subVI. I had this in there temporarily and forgot to change it before taking screenshots. It doesn't have any bearing on my question. Quote Link to comment
ensegre Posted February 8, 2016 Report Share Posted February 8, 2016 This is what I use. Would it do? RiseAndRunPanelVI.vi 1 Quote Link to comment
Doug Harper Posted February 8, 2016 Author Report Share Posted February 8, 2016 Well, I could probably make it work but I was hoping to be able to pass a control value to the subVI which is why I was attempting to use the asynchronous call node. I'll give it a try. I'm still confused as to why I'm never getting an "Idle" execution state result. Thanks... Quote Link to comment
Tim_S Posted February 8, 2016 Report Share Posted February 8, 2016 Another option would be to pass a message from your subVI to the top user interface when the subVI is done. You already are using an event structure, so passing a event would be a natural choice. Quote Link to comment
drjdpowell Posted February 8, 2016 Report Share Posted February 8, 2016 ‘Running†means “reserved for runningâ€. I don’t think the LabVIEW execution system, designed to handle very fast-finishing subVIs without overhead, can actually tell you if a VI is actually running at a specific point in time. What you can do is create a reference (a queue, say) in the async-called VI and pass that back into the caller (via another temporary queue). References like queues are automatically cleaned up when a VI hierarchy goes idle (each async-called VI runs in its own separate hierarchy), so this queue can be used to tell if a VI is still running. Quote Link to comment
ensegre Posted February 9, 2016 Report Share Posted February 9, 2016 Well, I could probably make it work but I was hoping to be able to pass a control value to the subVI which is why I was attempting to use the asynchronous call node. One could argue that if the value comes from a global like in your example, that global could well be buried inside the VI. Anyway, if the workflow is such that the opened sub-UI has to be made aware at later time of a value change, I agree with Tim that a better message-passing channel can be set up. Another UI possibility, don't know if relevant for your case, would be to make your subVI behavior modal (on entry; revert to standard on exit to avoid development trouble). That way your user would be prevented to do anything like choosing a second time from a menu in the main UI. Quote Link to comment
Mads Posted February 9, 2016 Report Share Posted February 9, 2016 I normally use the window state to determine if the function is running already or not here. So i make sure the pop-up window will always close itself when completed, and the calling code will just check if the window is already open to determine if it should initialize and run the VI. I have attached an example here. Now, this does not work if you really want the Furnace control to continue running even if the window is closed, but in such cases I would separate the GUI (only runs when window is opened) from the Furnace control (runs continously in the background), and just send adjustments to the latter from the former when they occur. Init, run and open if not already running. Open only otherwise.zip Quote Link to comment
djolivet Posted February 9, 2016 Report Share Posted February 9, 2016 (edited) I can't explain the behavior you're seeing, but I do as shown below. This was the only option before 'Start Asynchronous Call' existed. The Ctrl Val.Set is obviously an example and you should modify it for your needs Edited February 11, 2016 by djolivet Quote Link to comment
Popular Post Yair Posted February 22, 2016 Popular Post Report Share Posted February 22, 2016 I'm still confused as to why I'm never getting an "Idle" execution state result. Thanks... A bit late, but this table can probably help: You're apparently in the Waiting to run state, which happens with statically linked VIs which are inside VIs which are in Run mode. I didn't remember whether this applies to static VI references, but apparently it does. Another option which hasn't been mentioned here is to store the VI reference in the caller (e.g. using a feedback node) and always start by opening its FP. If that works (no error), you carry on. If it doesn't, you launch a new VI and store its reference. 3 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.