LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Function globals in re-entrant vi's

I currently have a re-entrant Vi that aquires some data then writes the data to a Graph.  It is re-entrant as I use the same VI to write to several graphs.
 
One of the options I want to add to this re-entrant VI is the ability to 'Zero' the reading.  i.e you set a boolean to true, the VI remembers the current value and subtracts it from all subsequent readings.  If the VI had not been re-entrant I would have used a function global to 'save' the zeroed value.  I think what I'm going to do is put a dummy while loop and shift register round my re-entrant VI to implement a function global without creating a sub-vi.  Think this will work(I'll soon find out).  Is there any hidden dangers in doing this, or even a better way to implement this?
 
Thanks in advance for any replies.
 
Derek
0 Kudos
Message 1 of 6
(2,995 Views)
Derek,

the way you are looking into the issue has two pitfalls.
1st) You can use this shiftregister only once in your VI and only in the part which contains the loop. Maybe this is suitable for your application, maybe not. So this point is rather application dependend.
2nd) Why is your VI reentrant? You are saying that this VI has to acquire data from an external resource. Most external resources are "exclusive" meaning only one function can access them at a time. If you don't take care a lot about access security, you propably will run into race conditions, altering the functionality of your code to a way you wont like...... Leaving the VI non-reentrant would be the simplest way to accomplish a minimum of security here (nevertheless, it doesnt garantee anything!).

hope this helps,
Norbert
Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 2 of 6
(2,992 Views)

Hi Derek,

In this thread I posted the design of an application in powerpoint.

Slides 41-45 detail the "I/O status" Action Engine (functional global) which was designed to share the state of the systems I/O to multiple clients in manner that is similar to the file and DAQ I/O that comes with LV.

Note: If you down load the ppt there are notes included for each slide.

I hope this helps,

Ben

Message Edited by Ben on 07-16-2007 07:36 AM

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 3 of 6
(2,980 Views)

1)My application can cope this, I've put a while loop round the whole sub-vi and wired it's control terminal to a constant, when the 'Zero' boolean input is true I write the current value to my shift register. the rest of the time I subtract the shift register from my current reading.  Seems to be working ok, for now at least.

2)  Interesting question, I've come from a C, C# background and I guess what I was trying to mimic was this....

The Re-entrant VI is my 'class' every time I wish to construct a new instance of that Class I put down another re-entrant VI allowing me to re-use the wiring diagram but each instance has it's own data stored between calls in shift registers.

Am I abusing the re-entrant VI property by doing this?  Think I'm caught a bit in the, learning something new(Labview) but still having  to get things working Smiley Mad

0 Kudos
Message 4 of 6
(2,971 Views)

Do you have a known number of instances in your application, I assume you are tyring to emulate classes on OOP.  You might consider using a template vi, where your application will create (open a copy of the vi) and then you can reference the vi in your application.  This is not too easy and requires managing names of the instances but so does OOP. 

 

Paul

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 5 of 6
(2,957 Views)
As you guessed, there are several ways to do what you want to do.  You are using statically created re-entrant VIs.  This approach works fairly well, but is somewhat limiting if you want to do something else with the same data (e.g. plot the zero vector).  Some other options:
  1. Instead of statically using the VI, instantiate them with VI server.  If they are re-entrant, you get a new copy of the VI every time you "open" it.  I believe you need to set a flag on the open VI reference for this to work properly.  The file GLV_WaveformBuffer.vi in the code of Managing Large Data Sets in LabVIEW is an example of this.  There is an example of its use.  This method is used by the NI-SCOPE Soft Front Panel for buffered waveform storage.
  2. Create a strict typedef data type, probably just an array, but could include some control flags, and store it in a single-element queue.  You can create as many of the single-element queues as you want.  Think of this as the data of an object.  Methods take the queue reference as input, dequeue the data for use, and enqueue when finished.  This automatically gives you data locking, since when the queue is empty, no one else can dequeue it.  I attached a cheesy example of this below (LV7.1).  Forgive the icons, they are a mishmash of various projects.
  3. Use method 2, but use a LabVIEW Object instead of a strict typedef.  This gives you inheritance, as well.
  4. If you don't need a reference object, just use a LabVIEW Object.  It is multi-instance (it is just a wire) and includes reusable methods.
There are other methods, as well (e.g. globals, network variables, etc.), but they generally don't work as well and are subject to race conditions.

Good luck.
0 Kudos
Message 6 of 6
(2,927 Views)