WORM Global

Continued from old thread.
Here is my latest version of the WORM Global.  For those who are not familiar with this project, a WORM Global is a way to store variables where you can write to them once.  WORM stands for Write Once Read Many.  This vi holds an array of variants. 
You can add any variable at any time.  When adding, you write the value to the variable.  After adding, you cannot write to it again, there is no mechanism to do so.  But you can read the variable as many times as you wish.  This prevents race conditions from happening. 
It is useful to store constants (variables that are defined and then don't change).  An example of its use would be to store GPIB addresses of instruments, datalog file names, config file names, constants flags, and others. 
Upon first call, the array of variants is emptied to get rid of leftovers from previous use.  It is best to call this vi inside a loop, with two arrays as inputs to the loop:  an array of global names and an array of corresponding values.  Wire in the Add enum to the Action input.  Now the globals are set and can be used anywhere in the program.  To use, call the vi again with Read as the action.  Wire in the name of the global you want to read.  The output is a variant, but can be converted to its proper type using Variant to Data function. 
Another action is to Delete.  You can delete globals that are no longer needed at any time. 
If trying to add a global with a blank name, you will get an error.  If trying to read a global with a blank name, you will get an error.  If trying to add a global whose name already exists, you will get an error.  If trying to read a global whose name does not exist, you will get an error.  If you try to delete a global that does not exist, or one in which the name is blank, you will get an error.
Please review the vi and give me some feedback.  If you see problems, bugs, or have a better idead, I would love to hear about them.
- tbob
Inventor of the WORM Global
Solved!
Go to Solution.
Attachments:
WORM_Globals.vi ‏40 KB

One question, any specific reason to use an array of clusters over a Variant with attributes?
The searching for a specific tag (or name) should be way faster (something with black and red books) in large datasets for a Variant attribute list vs. an Array of strings.
Why not skip the search when the Global name in is empty?
You picked an error number from the NI error-list that is not standard and is not available to users.
This is really nit-picking but you used a 'default'  state in an enum-based case structure
Why expose the worm globals to the outside world?
here's a Variant based on your code.
Ton
Free Code Capture Tool! Version 2.1.3 with comments, web-upload, back-save and snippets!
Nederlandse LabVIEW user groep www.lvug.nl
My LabVIEW Ideas
LabVIEW, programming like it should be!
Attachments:
WORM_Globals_Variant.vi ‏37 KB

Similar Messages

  • Pass the value of the current case in a case structure to a global variable for use in VIs.

    I have built a large queued state machine (>100 cases).  In each state, I run a VI that I have created.  These VIs are usually not very different from one another.  In many cases, I could simply use the same VI over and over again.  There is only one problem with that.  None of these VIs know which case to send the program to next.  I have to change the value of the "NEXT_CASE" constants in the VI and save it under a new name to be inserted into each new case.  Now my program consists of hundreds of VIs whose only difference is the value of their "NEXT_CASE" constants.  This causes all kind of headaches when I have to insert new cases into the state machine, and it is just too much for me to deal with.
    I need to be able to use a global variable to keep track of the current case within my VIs.  I could change it from a string to a number and add or subtract from it to determine which case the program should go to next.  Since I'm usually only skipping from one case to the next (or the previous) I could use the exact same VI in most cases.  Can anyone tell me how to create a global variable that contains the value of the case in my case structure that I could use within my VIs to keep track of the current case?  Let me know if you have any questions.

    Instead of defining the next state inside the subvi, why not do it in the main vi inside each state case?  An output from the subvi could be used with a case structure to determine the next state.  Sort of like, if the subvi returns 0 then next state is State3, else if the subvi returns 1 then next state is State4.
    Message Edited by tbob on 08-19-2005 03:15 PM
    - tbob
    Inventor of the WORM Global
    Attachments:
    NextState.PNG ‏5 KB

  • How do I open and close VIs from within a VI?

    Ladies and gentlemen,
    I would like to use a VI to open and close other VIs based on user input.  Example:  The first VI will have text that reads:  "Does the car have heated mirrors?"  There will be two buttons: one for "YES" and the other for "NO."
    If the user hits the "NO" button, the current VI will close and a similar VI will open that asks the user the next question, "Are the mirrors lighted?" "YES" or "NO..."
    If the user hits the "YES" button, the current VI will close and another will open that will tell the user to "Activate the heated mirrors" and press a button that will say "NEXT."  At that point, that VI will close, and in two minutes another VI will open and ask the user "Is the driver's side mirror hot?" with another set of "Yes" or "No" buttons.  If the user presses "YES" we will have verified that the heated driver's side mirror is working properly and store that information somewhere .  If the user presses "NO", the VI will close and another VI will open with some kind of repair instruction and a button that says "RETEST" that will rerun the heated mirror test when repairs are completed.
    During the two minutes we are waiting for the mirrors to heat up the program should move on to the next question: "Are the mirrors lighted?" "YES" or "NO..."
    Does anyone know how to manipulate VIs in this way?  Please help!
    Drew

    Instead of opening and closing vi's, just create one main vi with a state machine architecture.  Search for examples on state machines to get a basic understanding of them.  This is pretty complex so I have written an example of how this could be accomplished.  The trick part was the 2 minute timer (my vi is set for 5 seconds for quick testing).  Each state produces a question, and depending on the answer, the next state is inserted into a queue.  You can add more states for more questions and answers.  Notice that the boolean buttons can be hidden if you just want to show one button (like Next) instead of two buttons (Yes and No).  Study the vi and let me know if you have questions.
    - tbob
    Inventor of the WORM Global
    Attachments:
    Q&A.vi ‏166 KB

  • Front panel of SubVI locks on 2nd call

    HI!
    I'm calling a SubVI and pass a Boolean Reference to this SubVI. In the SubVI I'm executing a While loop. The stop condition is the value of the boolean control in the VI that calls the SubVI. (Boolean Refnum + Property Node: VALUE connected to while stop condition)
    Mechanical Action of the Boolean in the calling VI is: Switch when pressed.
    For the first time this will be executed it works fine. But the 2nd time the SubVI is called. The Front Panel of the calling VI where the stop button is located will be locked.
    Does anybody have an idea why this happens and how I can solve that problem?
    ANDY

    I tried what you described, using LV 7.1, and I have no problems running the vi over and over again. See the attached examples. Ref1.vi calls Ref2.vi and passes the Boolean reference to it.
    - tbob
    Inventor of the WORM Global
    Attachments:
    Ref.zip ‏21 KB

  • How do i sweep two voltage at the same time by using for loop ?

    Hello, Can anyone help me on this topic ?
    My problem is to sweep Vds and Vgs as same time vs Id in MOSFET by using for loop. I also use the Agilent power supply source. Let me tell a litle bit about what i'm doing. For different value of Vds, i will get Vgs vs Id curve. (The x axis is Vgs, the y-axis is Id).
    I started to create two for-loop, the inner to sweep Vgs, and the outer one to sweep Vds. My problem is don't know how to connect all the wire in  the for loop.
    In the for loop i saw N, i icon. Suppose I have the two variable for Vgs such as Vgs start and Vgs_stop. Should the Vgs_start( or Vgs_stop) be connected to N or leave it in the for_loop ?
     for example: I want to sweep Vgs from 0(for Vgs_start)  to  5(Vgs_strop) V, and the step increment is .5V how do i connect these variables in the for loop ?
    Thank you for your time
    Ti Nguyen

    It is easier to use a while loop.  Dennis beat me to the punch.  Here is my solution:
    You can remove the flat sequence structure if you use Error In and Error Out to ensure the execution flow will occur in the proper order.  Be sure to include the delay time in the loop so that your vi doesn't hog all the CPU time.
    Message Edited by tbob on 10-17-2005 01:00 PM
    - tbob
    Inventor of the WORM Global
    Attachments:
    RampVoltage.PNG ‏8 KB

  • Listbox one line at a time

    I want to add one line at a time in listbox/textbox just like InsertTextboxLine funtion in CVI. I can not find similar VI in labview. I think I can do it long way...by saving listbox to an array then append my line at the end of the array and send updated array to listbox..these are lot of steps to add one line to listbox/textbox...
    Any help would be appreciated.
    Thanks.
    CVI 2010
    LabVIEW 2011 SP1
    Vision Builder AI 2011 SP1

    Actually, the way to append an item to a list box is to create an Item Names property node for the list box.  Then you can use Insert Into Array, and write to another property node for Item Names.
    Message Edited by tbob on 10-03-2005 02:31 PM
    - tbob
    Inventor of the WORM Global
    Attachments:
    ListBox.PNG ‏3 KB

  • How do I select a control based on another control's selection and how do I remove enumerations from a control?

    Hi everyone,
    I have a question and I *think* the answer may be the new active controls, so here goes:  I have a control which contains a variety of enumerated items - essentially a typedef enum.  I may have up to several dozen items in this control, like this:
    Position - 1
    Current - 2
    Pressure - 3
    Temperature - 4
    Duty Cycle - 5, etc.
    I also have a 2nd control (actually a set of controls) that refer to the indices of the above control.  For example, if I "Position" chosen, I wish the 2nd control to appear that refers to position - an enumeration with "X axis, Y axis, etc."  If I select "Temperature", I wish the 2nd control to appear that refers to temperature - a different typedef'd enum - "Inlet, Outlet, Air, Water, etc."
    How do I do this?
    Lastly, the first enum with ALL of the items, pressure, current, etc. does not need to be used.  For certain configurations, I wish to eliminate, say the 1st and 3rd item - I don't wish to just gray them out, I wish to remove them from the enumeration, WITHOUT changing their enumerated value.  Perhaps I need to write the resultant enum into a temporary ring enum - any ideas?
    Thanks,
    Jason

    Unfortunately, you cannot edit the list of enums during runtime, only during edit mode.  You can use a ring control however.  Then you can use the Strings[] property to set the selections to whatever you want depending upon the 1st enum.  See attached vi.
    - tbob
    Inventor of the WORM Global
    Attachments:
    ChangeRing.vi ‏52 KB

  • Trigger two FPGA instances at same time

    I have some basic FPGA code that transmits data bits over a serial bus (RS485),  The code is written so that it waits in the first state of a state machine in a single cycle timed loop.  Upon a certain trigger, it starts reading a FIFO containing data and sends the data out on a Tx line.  It does this until all bits are send then it goes back to the first state to wait for the next trigger.  The trigger is needed because windows has to fill the FIFO first before the FPGA can start sending.
    I need two instances of this code running because I have two com busses (one is redundant).  So I am using the FPGA code as a subvi and I wrote a main FPGA vi to call two separate instances of the subvi in parallel.  A regular windows vi writes to the FIFOs for Tx and reads FIFOs for Rx.  No problem so far.
    The trick is that I have to start both transmissions within 200nS of each other (yes, nanoseconds).  Windows will write to both FIFOs in parallel, but the timing is 4uS apart, too long.  I tried setting up a boolean flag in the FPGA subvi, but windows can't write to the subvi control directly.  FPGA won't allow it (the Write function is greyed out).  I tried using a FIFO for a flag, but the problem is a race condition.  One of the instances will read the FIFO first and wipe it out.  The other does not get to read it.  I need one common trigger point to be used by both subvi instances.
    My final solution was to use a memory in the FPGA subvi and a numeric control in the main FPGA vi.  Windows write to the numeric control,  It can because the control is in the main FPGA vi.  Inside the main FPGA, I run a timed loop that looks for the numeric to be other than zero.  If so, it writes the value to the memory location used by the FPGA subvi.  After some time, the main writes a zero back to the memory to prevent the subvi from starting up again, and it writes a zero to the numeric to reset it.  The whole thing repeats, waiting for windows to write to the numeric again for the next transmission.
    I had to do it this way because sometimes I want to transmit on both busses, and sometimes just one or the other.  Numeric values are used to determine which to transmit on.  Now the transmissions start at almost exactly the same time, 1 or 2 nanoseconds apart.  But the trigger process seems very far fetched to me.  I was wondering if there is a better solution.  I'm pretty new to FPGA.
    - tbob
    Inventor of the WORM Global
    Solved!
    Go to Solution.

    tbob wrote:
    Basically I did the same thing using FPGA Memory.  From windows I write to a numeric control which resides inside the FPGA Main vi.  In the FGPA main, I write to the Memory.  Inside the FPGA subvi, I read the memory and decode the value to either use one or the other or both busses.  After fooling with this for some time, because the Read Memeory needs to use a shift register (probably due to it taking an entier clock cycle), I got it to work.  Both busses trigger at the same time.  I guess it really doesn't matter if I use a FIFO or if I use Memory.  The main issue is that I have to write from Windows to the FPGA Main, and then from the FPGA Main to the FPGA subvi.  Then the timing is exact as far as the subvi is concerned.
    There are a couple of advantages to using two FIFOs over your approach.  First, you don't need the shift register for the memory location.  Second, you don't have to worry about which VI is responsible for clearing the memory location, nor do you run the risk that one of your subVIs will execute twice, or not at all, if the memory isn't cleared at the right time.  Perhaps most importantly, you'll save yourself space on the FPGA because you won't need arbitration - the extra code that gets added when two parts of the FPGA try to access the same resource at the same time.  In your case, both instances of the subVI access the memory block concurrently, so the FPGA compiler adds extra logic to prevent conflicts.  If you only read the memory block in one place and only write it in one place (the read and write can be in different loops or subVIs) there's no need for arbitration.  By using two FIFOs you can keep them independent and avoid the conflict resolution code.  See the help for "arbitration" for more details.

  • Convert timestamp to string with milliseconds showing.

    I have two questions. The first is I need to know how to convert the timestamp that displays from "Get Date/Time in seconds" to a string format.  I found the vi that converts to string but it stops at seconds and cuts off the milliseconds. I wired true to the "Get seconds" terminal so I get the time in seconds, I just don't get the millisecond value. Also I need to know if the clock from "Get Date/Time in seconds", is synchronized (or shows the same time down to the millisecond) with the timestamp that shows in the CAN read vi. I need to have the clock/timestamp from the CAN read synchronized with the "Get Date/Time in seconds" clock/timestamp. I am trying to compare delays in the CAN so I need precision down to the millisecond.

    Use Format Date/Time String.  For the format code use %H%M%S%4u to get two digits for hours, two digits for minutes, two digits for seconds, then a decimal, and after the decimal you get 4 digits for fractions of a second.  Replace the 4 with a 3 to get milliseconds, or with a 1 to get tenths of a second.   You get the idea...  See attached vi.
    - tbob
    Inventor of the WORM Global
    Attachments:
    Milliseconds.vi ‏12 KB

  • Terminating Event Generate an Error

    Hi All.
    My custom workflow has asynchronous task where the terminating events trigger from ABAP program and passed some data.
    This task will completed upon custom event "ACCEPTED" raised in the system based on certain keyfield and continue next steps.
    Terminating events tab contains element WIOBJECT_ID and my custom event "ACCEPTED".
    Binding is use standard element Binding details as per standards, &_EVT_CREATOR& --> &INITIATOR and &_EVT_OBJECT& --> &_WI_OBJECT_ID&
    I though this is the only step that I need to do and of course wait step.
    However when I test this terminating event via SWUE with proper object key, event trace transaction reported event "ACCEPTED" for task TS95000052 not defined as start/end event.
    I check in instance linkage transaction, linkage is activated for my object type, "ACCEPTED" and receiver type "WORK ITEM".
    Event type linkages between event and my asynchronous task also active.
    Will someone give me a clue, what should I do to resolve this issue?
    Many Thanks

    You cannot exit from a for loop until it is done. Use a while loop instead. Also, using the event structure in this case causes all kinds of exit problems. Try it and you will see what I mean. Instead, use the abort button itself. Put a case statement at the end to give the error output if the abort button was pressed. See attached vi.
    - tbob
    Inventor of the WORM Global
    Attachments:
    abortTesting.vi ‏45 KB

  • Probleme for writting in to the file

    Hello, I have a problem in my applicaion and I need your help.
    My problem is the following:
    I have a vi Entrées Consignes1.vi, when I run this vi, It open the file for exemple : FAUX.txt (which contain the expression like name = value),after the opening, the differents values display in my Entrées Consignes1.vi. up until then , that's ok!!
    But my problem is when I modify some values in my panel control and when I click to the button" Modifier Données" I' d like save it in the same file without affect the different name.I'd like just modify the values because in my solution,I don't know what make?
    I send you the Entrées Consignes1.vi with the file FAUX.txt
    Thanks you very much for your help.
    My seconds question is what exactly is the difference of Labview and Labview Real time?
    Attachments:
    Dossier.zip ‏31 KB

    Pardon, j'ai oblier l'attachment.
    - tbob
    Inventor of the WORM Global
    Attachments:
    Entrées Consignes1.vi ‏101 KB

  • How do you save characters in an array and then output the characters as a string one by one.

    I want to know how to save a number of different characters to an array. then after open this array and read these values one by one as a string.

    Input to your loop has indexing enabled.  What happens is that on the first iteration, the indicator displays the first string in the array, then in the next iteration, the indicator displays the second string in the array, the first one is overwritten.  This happens so fast that all you see is the second one.  Look at attached vi in LV6.1 to see how to concatenate both into one indicator.  You really need to study Labview to learn the functions.  Go to NI's website and search for Labview tutorials.
    - tbob
    Inventor of the WORM Global
    Attachments:
    ConcatString.vi ‏28 KB

  • How could I choose some bytes from HEX string and then convert it to a decimal value?

    Hi I am working with an OMRON E5EN temperature controller using VISA serial to get data, I send the Read from Variable Area command and get this string  in hexa 0230 3130 3030 3030 3130 3130 3030 3030 3030 3030 3041 3203 71 or .01000001010000000000A2.q in ASCII this string means:
    02 STX
    3031 3030 Node and subadress
    3030 End Code Normal Completion
    3031 3031 Command Read from Variable Area
    3030 3030 respt code Normal completion
    3030 3030 3030 4132 Hexadecimal A2 = 162  (this is the temperature data that I want to show in decimal)
    03 ETX
    71 Block Check Character
    I want to choose the eight bytes for the temperature data and convert it to a decimal number. I have seen the examples to convert a Hexa string to decimal but I do not know how to choose the specifics bytes that I need.
    I have look for a driver but i didn´t find any. I am a beginner so please include especific topics for me to study in your answer.
    Thanks
    Carlos Fuentes Silva Queretaro Mexico 

    If the response always has the temperature starting with byte 15 and is always 8 bytes in length, you can use the String Subset function to get those bytes out of the string.  Then use Hex String to Number to convert to a decimal number.
    Well someone already beat me to the solution:
    Message Edited by tbob on 01-04-2008 04:42 PM
    - tbob
    Inventor of the WORM Global
    Attachments:
    HexStr2Decimal.png ‏7 KB

  • Releasing Queue in Producer Consumer model

    I am having a VI which reads data from ethernet,writes to disk,processes and displays. Since lot of processing and displays are there, I am converting it to a Producer- Consumer model so that no data is lost.
    I am using 2 loops. IN the Producer I am doing the UDP read and Write to disk functions.and use the enqueing also.In the Consumer loop I am dequeing it and do all the processing and displays.My idea is to avoid any data loss in UDP reception and file writing.
    My confusion- where to use the release queue?from the Producer or Consumer ? In a third loop ? Should it be in a sequence structure ?
    How to set the loops stop conditions ?
    My requirements for stopping - when I press the stop button the program should stop completely(the Consumer loop should stop only after dequeing and processing all the data in the queue).  If i don't press the stop button the whole program should run continuously (if data does not arrive for some time it should wait without time out-i am using -1 for the time out condition in UDP read.)

    Here is the ultimate Producer-Consumer loop.  It queues a stop command when the stop button is pressed.  This ensures that every element is dequeued and processed before the bottom loop stops.  The last queue data to get processed is the stop command because after you press the stop button, the top loop stops enqueueing more elements. 
    If your data type is other than a string, you can create something to represent stop, like NaN for a numeric. 
    Notice the shift registers.  This is good practice.  Every loop starts with an error out of the previous loop.  If an error occurs, it is passed on to the next loop iteration.  Also, if an error occurs in the consumer loop, the loop stops.  It is good practice to put shift registers on the queue reference also, but not necessary in this case.  If you use a For loop, and the loop iterates 0 times, the output of the queue reference would be a null reference, and the Release Queue would not release the queue.  With While loops, they always iterate at least once, so it isn't necessary.  Its just good practice to make a habit of using shift registers so you don't forget when using For loops. 
    Notice also that the error in to the Release Queue is not wired.  If there were an error, the Release would not take place.  All errors are merged at the end to report exactly where an error occured.  A timeout is included in case an error prevents the stop command from being enqueued or dequeued.
    - tbob
    Inventor of the WORM Global
    Attachments:
    ProducerConsumer.vi ‏53 KB

  • Date and time stamp in array

    Hello,
    I am using Labview 8.0 and I would like to include a date and time stamp each time data is collected and include this as a 5th column in the final array.  I inserted a random number generator instead of devices so it would be easier to understand and test.  I am new to Labview and have never created a date/time stamp before.  Any help or advice would be appreciated.
    Dave
    Solved!
    Go to Solution.
    Attachments:
    Timestamp.vi ‏16 KB

    Yes you need to convert all to strings since the timestamp in HH:MMS is a string.  In the string palette, there is a sub-palette full of numeric to string conversion tools.  Use the Number to Fractional String to convert all numerical data to strings.  Use the Format/Date Time String function (found in Timing palette) to convert the timestamp to HH:MMS.  See the format string in my example.
    - tbob
    Inventor of the WORM Global
    Attachments:
    TimestampAssistance[1].vi ‏14 KB

Maybe you are looking for

  • [Solved]I just want to transfer some files from one computer to ano...

    Setup: Windows LAN (setup by my dad) One Arch Linux Box, hardwired and connected through the network without problems. One Ubuntu Linux Laptop, connected wirelessly. I want to transfer my music, schoolwork, ect, onto my desktop from my laptop. Both m

  • Obiee server SQL throw exception :ORA-29275

    The obiee server throws oracle exception: ORA-29275 while execute in the sql in the bidw , the sql results have Chinese characters I have try to copy the sql to query from Jdeveloper adn SQL developer , the sql can run and no exception so does it the

  • Ipad mini stuck on itunes

    Issue: iPad Mini just got updated I come home and it is at the recovery screen (connect to itunes screen) I plug it in and nothing doesnt even come up I tried the all the ports and nothing and they work with my iPhone. I have pressed the home and pow

  • Java.lang.UnsatisfiedLinkError on Linux

    Hi, I've got some Java code compiled which works fine for others on a Windows machine. The same code, when run on Linux using the latest tarball (oracle8161SE_tar.gz) for the 8i server gives me the following error when run: I searched here but didn't

  • MGR-02150 error after installing 8.0.6

    After installing Oracle 8.0.6 on either a 'fresh' Windows 2000 or Windows NT4 server, I get the error message "MGR-02150: an unrecognized database version was encountered" all the time. All other versions (from 8.0.5 to 9.0.1) work just fine, it's ju