srh Posted December 9, 2005 Report Share Posted December 9, 2005 Hi all, I'm hoping you can help me. I have a main top-level VI (in the form of a template so it can be opened multiple times) which must execute one VI several times, so I made that VI reentrant. I need to both send and retrieve information back from that VI. I call this VI by invoking the "Run VI" method and I can easily send information to it by using "Send Control (varient)", but my problem comes when I try to retrieve information from it. I know I can't use "Get Control (varient)" because all it would send back is a blank control (since the front panel on a reentrant vi is always blank). I thought my best option would be setting up a queue, but I tried creating a queue on the top-level VI and sending the queue name through to the VI, but it still doesn't work. I know everytime it tries to "obtain" the queue, it is creating a new one reference, but I'm not sure if this is part of the problem or not. Am I creating two queue with the same name? Is that possible? I was hoping it would be as simple as creating the queue in the top-level vi before entering a while loop, filling the queue in a timed loop in the reentrant VIs and dequeuing the elements in the top-level vi loop, but that doesn't seem to be the case. Am I doing something wrong? I'm assuming it is possible to grab information from a reentrant VI, right? I know a global would work perfectly here, but then information from the different template instances would end up overwriting or mising together. Plus I know that globals in Labview, in general, are bad. I would like to code this application as clean as possible (and being new to Labview coming from my C++ background is actually a little difficult for me! ) Sorry if this seems like a junior problem, but I really don't know how to get around it. Oops - last minute information - I am using Labview 7.1, but I am currently upgrading to Labview 8.0 (literally actually, my computer is upgrading as I type!). I'm not sure if they have added anything new to help me, but I'm assuming not, but if so, let me know. I won't have much time to play and explore with unfortunately (deadlines!!). Thanks so much in advance for any help you can provide me! Quote Link to comment
Jim Kring Posted December 10, 2005 Report Share Posted December 10, 2005 I believe that LabVIEW 8.0 might fix your problems. There have been additional features added that allow debugging reentrant VI instances: Debugging Reentrant VIs To allow debugging on a reentrant VI, select File Quote Link to comment
srh Posted December 11, 2005 Author Report Share Posted December 11, 2005 I believe that LabVIEW 8.0 might fix your problems. There have been additional features added that allow debugging reentrant VI instances:For solving the problem in 7.x, take a look at the Process Spawning Design Pattern discussion thread. Thank for your help Jim.. I would LOVE to set up some debugging in the reentrant subvi to find out where the problem lies, but because I am invoking the "Run VI" method, I am left with using references which apparently still leaves me hanging. I looked through the slide package and, other than offering a small reassurance that I'm not doing anything illegal, it didn't offer any additional information I didn't already know (however, it did say queues were "useful when a process does not have a user interface AND contains a looping structure" -- that's me, right there!). As for the GOOP solution of spawning a process, that seems a little advance for the problem I am trying to solve. Especially considering I am new, I would like to try and avoid diving into that realm right now if I can help it. Actually, I'm not sure if debugging would help much. Everything works fine when I remove the reentrancy from the subvi. The problem only shows up when make it reentrant. I know the dynamic reentrant VIs are created correctly because I store the references in an array used throughout the program which I watch through probes. The references are created and, some time later, destroy automagically - which makes sense because the timed loop inside the reentrant subvi would have completed and the auto ref disposal would have kicked in. I'm sure it has something to do with the queue implementation. Is there something I'm missing about reentrant VIs? Can a dynamically created reentrant VI use a queue created by a top-level VI? And if not, how do these VIs pass information back to the main VI? Quote Link to comment
PJM_labview Posted December 11, 2005 Report Share Posted December 11, 2005 Hi all,I'm hoping you can help me. I have a main top-level VI (in the form of a template so it can be opened multiple times) which must execute one VI several times, so I made that VI reentrant. I need to both send and retrieve information back from that VI. I call this VI by invoking the "Run VI" method and I can easily send information to it by using "Send Control (varient)", but my problem comes when I try to retrieve information from it. I know I can't use "Get Control (varient)" because all it would send back is a blank control (since the front panel on a reentrant vi is always blank). I thought my best option would be setting up a queue, but I tried creating a queue on the top-level VI and sending the queue name through to the VI, but it still doesn't work. I know everytime it tries to "obtain" the queue, it is creating a new one reference, but I'm not sure if this is part of the problem or not. Am I creating two queue with the same name? Is that possible? I was hoping it would be as simple as creating the queue in the top-level vi before entering a while loop, filling the queue in a timed loop in the reentrant VIs and dequeuing the elements in the top-level vi loop, but that doesn't seem to be the case. Am I doing something wrong? I'm assuming it is possible to grab information from a reentrant VI, right? I know a global would work perfectly here, but then information from the different template instances would end up overwriting or mising together. Plus I know that globals in Labview, in general, are bad. I would like to code this application as clean as possible (and being new to Labview coming from my C++ background is actually a little difficult for me! ) Sorry if this seems like a junior problem, but I really don't know how to get around it. Oops - last minute information - I am using Labview 7.1, but I am currently upgrading to Labview 8.0 (literally actually, my computer is upgrading as I type!). I'm not sure if they have added anything new to help me, but I'm assuming not, but if so, let me know. I won't have much time to play and explore with unfortunately (deadlines!!). Thanks so much in advance for any help you can provide me! Hi A few things: You say "I have a main top-level VI (in the form of a template so it can be opened multiple times) which must execute one VI several times" 1) Does this subVI of your template has to be executed at the same time (meaming, will this be OK for one instance of the template instance to wait until another instance is done using this subVI?) If the answer is yes, you dont need reentrant VI 2) Assuming the answer is no, then why dont you pass the data in and out of your rentrant subVI using the connector pane? There are some instance where this is not suitable (for example if you have a rentrant labview 2 style global and you need to access the same instance data from different location [such as the OpenG Goop for example]) but most of the time this is fine. 3) Assuming again that you are in that situation that you need to access a given instance of your rentrant VI in several location in your template instance then you should go and read the thread Jim mentioned. It will show you one way of doing what you are trying to do. Good luck PJM Quote Link to comment
srh Posted December 12, 2005 Author Report Share Posted December 12, 2005 Hi PJM, Thanks for your suggestions! Unfortuantely I do need to access the subVIs in parallel. Call by Reference was my first choice of spawning the subVIs based on how the complexity of the information I needed to pass through to each subvi (thank you OpenG for solving most of my problems there!). A little background on my project : basically I have multiple stations that have to control multiple instruments. The template gives access to each individual station while the reentrant subvis control all the individual instruments. Each instrument (hence subvi) has a value change which needs to go to two seperate places - [1] printed to a file and [2] to a control on the template front panel. Since all the values from every instrument needed to be printed to a file, that was easy to solve with an LV2 global which stores the queue refnum. Now I need a global that is specific to each template. Unfortuantely a global is exactly that - global! I found a solution from a previous post from mgunning which I thought would work. Basically he suggests making an LV2 global reentrant and opening it from a VI server. I did a quick example of it using numbers instead of a queue refnum to see if it would work the way I was hoping and it seems to do the job. Each instance of the global held values specific to each template and was fed it's data by a reentrant subvi, but when I implemented it with queue refnums and my monster of a program, it seems to fail (again, it is fine when I ran it in non-reentrant mode). It's probably a little error I made, but given everything is setup as dynamic and reentrant, my debugging abilities are severly limited. I'm almost ready to give up and delve into the world of GOOP like Jim originally suggested. It sounds like Jim's GOOP suggestion runs similar to the example posted above, except he allows himself one more way to kill the instance if other methods fail to do so. Perhaps I read it wrong though. I'll know once I try to implement it. My worry now is that not even GOOP can help me. Quote Link to comment
PJM_labview Posted December 14, 2005 Report Share Posted December 14, 2005 Hi PJM,Thanks for your suggestions! Unfortuantely I do need to access the subVIs in parallel. Call by Reference was my first choice of spawning the subVIs based on how the complexity of the information I needed to pass through to each subvi (thank you OpenG for solving most of my problems there!). A little background on my project : basically I have multiple stations that have to control multiple instruments. The template gives access to each individual station while the reentrant subvis control all the individual instruments. Each instrument (hence subvi) has a value change which needs to go to two seperate places - [1] printed to a file and [2] to a control on the template front panel. Since all the values from every instrument needed to be printed to a file, that was easy to solve with an LV2 global which stores the queue refnum. Now I need a global that is specific to each template. Unfortuantely a global is exactly that - global! I found a solution from a previous post from mgunning which I thought would work. Basically he suggests making an LV2 global reentrant and opening it from a VI server. I did a quick example of it using numbers instead of a queue refnum to see if it would work the way I was hoping and it seems to do the job. Each instance of the global held values specific to each template and was fed it's data by a reentrant subvi, but when I implemented it with queue refnums and my monster of a program, it seems to fail (again, it is fine when I ran it in non-reentrant mode). It's probably a little error I made, but given everything is setup as dynamic and reentrant, my debugging abilities are severly limited. I'm almost ready to give up and delve into the world of GOOP like Jim originally suggested. It sounds like Jim's GOOP suggestion runs similar to the example posted above, except he allows himself one more way to kill the instance if other methods fail to do so. Perhaps I read it wrong though. I'll know once I try to implement it. My worry now is that not even GOOP can help me. Before you go investigating GOOP, did you download Michael presentation on process spawning that Jim linked to. It explain how to use Queues to span process? From reading your description I am still not quite sure what's going on. So let me re iterate my questions Is your reentrant SubVI a LV2 Global? Is it use in only one location in the template? If you anwser yes to both, you do not need to instantiate your LV2 reentrant subVI, just drop it as such and pass parameter through the connector pane. Now I jus re-read your initial post and I think you issue is that you need a different queue name for each template instance. Once again read michael post on process spawning you will learn a lot about queues. Good luck PJM Quote Link to comment
bsvingen Posted June 1, 2006 Report Share Posted June 1, 2006 I downloaded the "process spawning" article. Great article with lots of useful stuff. However, it needs updating since one thing in there is plain wrong. It says that You cannot show the front panel of a specific instance of a reentrant VI. This is wrong, at least for LV8. I am doing this all the time in my application with front panels for each instance of the reentrant vi. There is also an example in the example folder that shows this feature. Quote Link to comment
Michael Aivaliotis Posted June 1, 2006 Report Share Posted June 1, 2006 I downloaded the "process spawning" article. Great article with lots of useful stuff. However, it needs updating since one thing in there is plain wrong. It says that This is wrong, at least for LV8. I am doing this all the time in my application with front panels for each instance of the reentrant vi. There is also an example in the example folder that shows this feature. This was written about 2 years ago in the context of LV7 so it is not wrong. Also, more people than NI wants to admit are still using LV7 so this is still a very usefull article. It would be great if you could write an addendum describing your experiences with this new feature addition in LV8 and I will include it in the original article. Quote Link to comment
bsvingen Posted June 4, 2006 Report Share Posted June 4, 2006 This was written about 2 years ago in the context of LV7 so it is not wrong. Also, more people than NI wants to admit are still using LV7 so this is still a very usefull article. It would be great if you could write an addendum describing your experiences with this new feature addition in LV8 and I will include it in the original article. I have used it in a different content. My vis are already running, and i use the FP.Open method or double click them in the block diagram to show the front panel as a user interface for particular instances of the vi (show graphs, input and so on for the elements in a simulation package). It is not only possible to open the FP, it is also possible to debug the instance, just like any normal vi. Basicly it has enabled me to make "objects" with working front panels. Previously i made these "objects" as distinct vis on the harddisk to be able to see front panels. This worked OK, but it was not possible to make a menu system in the palette for these objects (there would be 70 different objects of the same type but with different name, XXX 01.vi and so on). It was therefore easier to drag them into the diagram directly from the folders. Now it is possible to make a real palette, a toolset with vis that have interactive front panels. With this toolset i run the simulation directly in the block diagram and have full interactive possibilities simply by double clicking on them while running. It is also much easier to build systems when you can use click copy and drag. The Labview graphical programming environment (the block diagram) and these reentrant sub vis will together make a full featured simulation package for design and engineering, just as good as anything else. I can also make stand alone executables (a real process simulator that also include measurements from the real system) using the exact same block diagram. Then i must use the FP.Open method and build a user interface (wich is needed for simulators in any case). Quote Link to comment
bsvingen Posted June 5, 2006 Report Share Posted June 5, 2006 I can add that at initialization the "This VI" ref for each element or reentrant vi (also new in LV8) is stored in a named notifier. This notifier is later used in a main user interface to open the appropriate reentrant instance (when i build executable stand alone simulators). In the main user interface the named notifier is associated with custom made boolean switches that represent and looks like the physical object (for instance a pump), so that when the user click on the pump picture, the front panel for that particular instance of the pump sub vi is opened. The "This VI" ref and reentrant vis with front panels that can be opened looks very object orientet to me. Does anyone know if this is a gradual tramsition to natively implemented OOP in newer version of LV? 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.