05-17-2011 10:54 AM
Hello,
I have searched all over the Forum and have not found a good example for me to reference.
I would like to "automatically" name files (.tdms files) with a push of a button. Each button refers to a file name. When I click this button, the File Dialog VI will create a new file to which the data will be written to. Currently, my plan is to have the file name strings in a cluster and have the boolean buttons in clusters and try to link the two. However, I've had the most frustrating time trying to accomplish this. I have tried cluster to array, index arrays, any kind of array in combination with property nodes but I've had no success. Please advise me on what steps to take. If I need to get rid of the cluster method, let me know. I chose that option because it was cleaner/simpler/more organized on the front panel (which is a necessity for the overall goal).
I have attached it below. There are more parts to this code but this is my main focus.
05-17-2011 12:15 PM - edited 05-17-2011 12:15 PM
Unfortunately, that's not much to go on since it's not clear what those buttons are going to be doing. Are they supposed to be starting some sort of process? Do you have an event structure in the main code? Also, what is the naming scheme? If the file exists do you overwrite it, or do you append some sort of timestamp?
As for your specific code, one thing that's missing is knowing which button was pressed. For a cluster of Booleans a Cluster to Array followed by a Search 1D Array (looking for a True) will tell you which ones are pressed. This points to a problem, however. Since you are using a cluster, more than one button can be pressed at a time, unless you "reset" the cluster programmatically. You may want to consider using a radio button group, which has built-in mutual exclusivity. If you wish to have rectangular buttons you can easily customize the control to replace the radio buttons with rectangular buttons. Then the value of the control can be used to directly index our the filename from the other cluster:

Of course you still have to create the full path to feed to the File Dialog VI.
05-17-2011 03:28 PM
Thank you so much for your help!
To answer your questions:
"Are they supposed to be starting some sort of process? Do you have an event structure in the main code?"
In the actual code, there are sequence structures (flat and stacked) that control a series of events to "prep" the test. For instance, it takes preliminary data to set up a range for a Tank Numerical Indicator (not shown) using property nodes. After that, the file creation begins and then the test runs. Currently, I am hoping the prelim data won't have to change for every new file I have to write. If that is the case, after the prelim sets up the range, I will push a button (File 1) to write File 1.tdms. Then, after some time, I push another button (File 2) which will commence the file writing for File 2.tdms. And so on.
"Also, what is the naming scheme? If the file exists do you overwrite it, or do you append some sort of timestamp?"
The pic I attached shows a simple code of what I am doing (taken from the Cont Acq&Graph Voltage - Graph Unscaled Data from File (TDMS).vi LabVIEW example). Each condition of the test has a different name so there should be no overwriting of files.
Right now with the changes, it automatically asks to save a file after 5s (the default Sampling Time). However, if I am currently running and writing test condition File 1 and File1.tdms, I have to remember to click on "File 2" button so that it writes File 2.tdms or else it is still thinking about File 1. Of course I can always just type in File 2.tdms but, the final product of the code will be handed to a group of users who may not know too much about LabVIEW and won't have the time to tamper with it too much while testing. With the exceptions of clicking "Run" and each test button (File 1, 2, 3,...), it has to be virtually hands free.
So my new questions are: How do I get it to write a file upon command of the button? Then, when done, wait for my next command (next push of test button) before running the test and writing it? I don't think I want it to keep asking me to chose a path/file. When I set a file path (which I forgot to do in the attachments), it should save there with the new file name without asking me.-->When I click a new button/command, how do I make it stop asking me for a new file/path and just write? I feel this may involve event structures which I don't know how to use but willing to learn.
05-17-2011 04:25 PM
I would recommend that you consider using a state machine architecture rather than your current mix of flat and stacked frame structures. Using a state machine architecture will allow you to reuse common code (states) easily. Filenames are effectively strings so you can use the various string VIs to format the file name in any way that you want. Usr a build path with the directory where you want to store the files and teh file name you generated and pass this value into the TDMS VI for creating a file.
05-17-2011 05:09 PM
Mark thank you for your advice, however, I have no problem with the flat or stacked sequence structures and they have always worked for me. As a matter of fact, I need those structures to generate a specific sequence of events. It is the linking of boolean buttons to the file name strings to automate the file naming process and testing process that is the problem. I am really hesitant to rebuild the entire code that took ~4 months to make when sequence structures are not the problem.
05-18-2011 09:36 AM - edited 05-18-2011 09:42 AM
LabVIEW is a dataflow language and sequence structures significantly change this paradigm. There are countless discussions on the many pitfalls of using sequence structures. In all but some very specific cases a program design using dataflow to control order of execution will be more flexible and much more maintainable. It may have worked for you in the past but trust me sequence structures should not be a regular part of LabVIEW programming. If you don't believe me ask the folks who are Certified LabVIEW Architects how often they use and rely on sequence structures. There are reasons these people, myself included, don't regularly use them. If you plan on using LabVIEW in your professional career it is worth your time and effort to learn how dataflow works and to write code using it, not sequence structures. I can assure you that your comments stating you need them is not accurate and that there are better ways of writing your code. I can understand that at the end stage of your project you may not want to rewrite your code but I am trying to give you advice on how to write better code in general. You are free to use or not.
With regards to code you posted you do not need to prompt the user for the file name. You can simply construct the file name based on the test they chose to execute (again simplified using a state machine architecture). If you want to guarntee unique file names you can append a date and timestamp to the file name. This will pretty much guarantee you have unique file names.
05-25-2011 01:53 PM
So, I've tried this state machine option (for the first time in my life) and it's not working. I can't get my code to switch from the Idle case to the File 1 case. I used a cluster of booleans wired to the Search 1D Array and then to a Type Cast as seen in some examples. I've attached the code below. Can someone please check what's wrong with it?
05-25-2011 02:06 PM
The representation of your enum on your typecast is incorrect.
The search 1D Array returns an I32. Looks like typecasting it into a U16 Enum is no good.
Either convert the I32 to U16 or change the TypeCast to use a U32 Enum instead of a U16.
05-25-2011 02:16 PM
You have several issues with your code. First and foremost you don't have any means to actually stop your state machine. You have no user action or programmatic event that will stop the state machine once it starts running. You have a state called stop but you don't have any way to invoke that state.
Also, I highly recommend that you create a typedef for your ENUM that defines the states. This makes it much easier to add new states. With individual ENUM constants you have to update each one whenever you change the definition of your states.
There is very little difference between the code for each of your "file" states. This looks like a good candidate for a subVI.
Generally you want to pass your data through the state machine from one state to another. Therefore you should use shift registers to pass the data through. In addition, any time you run the idle state you will initialize your data. However since you are not actually using shift registers to pass the data through this is a mute point in this code. It would be a problem if you had shift registers.
Your typecast is not working for the ENUM. The index returned is a I32 and the ENUM is a U16. The type cast actually uses the upper 16 bits of the I32 which will always be 0. Insert a "To Unsigned Word Integer" between the search 1D array VI and the increment. This should return the value you want.
This isn't a fix for your code but here is a basic example of a state machine. This might help you understand state machines better.
06-01-2011 11:06 AM
Mark,
Is there a way you can post a pic of the code. I can't open the vi; I have LabVIEW 2009.