04-09-2009 01:29 PM
smercurio,
That is the perfect answer to the DAQ question and a great start towards a state machine implementation. Kudos
Robbo13,
The TDMS Open.vi has an input terminal labeled operation. One of the options is to create a new file. If you try to create a file that already exists, an error is generated and the existing file should be untouched. As far as auto incrementing the filename, you can always use a shift register or functional global to hold the last number used.
04-09-2009 01:59 PM
smercurio_fc wrote:The best way to do this is to append some sort of timestamp to the filename. You can use the Time functions to return you a string to indicate the date and/or time.
Aha thats a great idea, thanks!
I had been looking into state machines after the earlier posts but that link looks very helpful, i'll get reading that right away.
The only reason I had for wanting to use the DAQ assistant was that I know it's very easy to add more channels later on, however given how well you've explained the breakdown of the DAQmx functions involved in the example I reckon I'll try and do it that way instead.
Well i've got a lot to be getting on with for now, thanks to you both for your help, its much appreciated.
04-09-2009 03:07 PM
Robbo13 wrote:The only reason I had for wanting to use the DAQ assistant was that I know it's very easy to add more channels later on, however given how well you've explained the breakdown of the DAQmx functions involved in the example I reckon I'll try and do it that way instead.
It's also quite easy to do it using the DAQmx VIs directly. The example I pointed to has a "physical channel" input. This does not have to be a single channel. You can specify a range. Since it's a control you would not need to change code. Alternatively, instead of using the "physical channel" input you can use the "task" input. Then you can simply create a task outside of LabVIEW using Measurement and Automation Explorer (which gets installed when you install DAQmx).
04-10-2009 11:42 AM
I've had a go at putting this together, unfortunately I wont be able to test it with actual DAQ hardware for a few days since uni is shut for Easter. I've got a few queries about what I've done so far (apart from 'will it work?'....... will it?!).
I created the state machine using the labview template and i'm unsure what effect the 'milliseconds to wait' function will have. Does this add a wait in between each iteration in the loop, therefore meaning that in every loop there will be a 100 millisecond or so gap in my recorded data?
Also as the program is at the moment would it be better to move the creation of the TDMS file into the start state? To me it looks like if you've pressed start, recorded your data and pressed stop the program will return to the initialise state and wait for a user input. Wont this then create a new TDMS file which will be empty if the user doesnt then want to start the loop again? Come to think if it i don't think they have a choice right now as pressing exit will only do something if data is actually being recorded, i'd better change that!
I think i've at least tried to do everything smercurio_fc suggested, with the exception that the program doesn't check to see if data acquisition has already been started, as I wasn't sure how to do that.
If anyone could give it a quick once over and see how it's looking i'd be really grateful. Thanks once again to all who've helped so far
04-10-2009 01:28 PM
A very good start, actually. Well done. Give yourself £10.
You actually can run the code without hardware. DAQmx allows you to create simulated devices and you can use Measurement & Automation Explorer to do so. I don't recall you mentioning what kind of device you have, but if it's not in the list of devices that can be simulated you can always find one that's close, especially since all you're doing is performing a simple voltage read. Then in your code you need to select the channels for whatever device you created. That's how I ran your code.
Code comments:
04-10-2009 03:32 PM
Ha ha, touché! I'd better get on ebay!
Couple of things i'm having trouble with:
- can i have my buttons appearing in more than one case? So for example my exit button currently appears in the collect case, can i also have it in the UI case somehow so that I can allow the program to be stopped at that point? Or do i have to do this some other way?
- when trying to move the creation of the TDMS file to the start state, presumably i have to also move the 'set file properties (TDMS).vi' with it?
- Regarding initialising the shift registers, is this just a case of setting a zero value for them, as with the (what was a floating point but is not a boolean shift register)? You say that at the stop state if the user is only stopping then to go back to the UI state, do the shift registers not need reinitialising at this point before the next set of data can be recorded?
- I like the idea of having an error state and i've found a function to reset the error once a dialog box has been shown, but i'm not sure how to navigate the program to the error state when an error occurs. At present anytime i need to choose between possible states it's done by just using the select function to choose between 2 options. How can i add in the 3rd option of moving to the error state, and make this take precedence over the other 2 options?
When it comes to actually using the system for real the hour and minute time stamp should be fine, but for testing the program i might add in seconds too just to prevent anything going wrong.
I'm really pleased with how well it's gone so far, thanks for your patience!
04-10-2009 04:22 PM
Robbo13 wrote:
- can i have my buttons appearing in more than one case? So for example my exit button currently appears in the collect case, can i also have it in the UI case somehow so that I can allow the program to be stopped at that point? Or do i have to do this some other way?
Sort of. You would need to use local variables (see below for WARNING) or property nodes to read the value. However, the default action of push buttons is "Latch", which is not compatible with local variables (and using the "Value" property on a push button with "Latch" is an error). Thus, you would need to change the mechanical action to "Switch". This just means you need to set the value of the button when you first start the program so you start at a known value.
- when trying to move the creation of the TDMS file to the start state, presumably i have to also move the 'set file properties (TDMS).vi' with it?
Yes. Basically everything in the "Initialize" state goes into the "Start" state.
- Regarding initialising the shift registers, is this just a case of setting a zero value for them, as with the (what was a floating point but is not a boolean shift register)? You say that at the stop state if the user is only stopping then to go back to the UI state, do the shift registers not need reinitialising at this point before the next set of data can be recorded?
Basically, yes. You just want to make sure you've set everything up so the state machine can operate properly. In your case you want the "Stop" to act as a "reset", so it makes sense to go back to the "Initialize" state where you can start fresh.
- I like the idea of having an error state and i've found a function to reset the error once a dialog box has been shown, but i'm not sure how to navigate the program to the error state when an error occurs. At present anytime i need to choose between possible states it's done by just using the select function to choose between 2 options. How can i add in the 3rd option of moving to the error state, and make this take precedence over the other 2 options?
All that you really need to do is to look at the error cluster at the output of the state machine and override the state that's supposed to be next. You unbundle the error cluster. If "status" is true, then go to the "Error" state. Otherwise, go to the intended state. Note that this requires that the "Error" state not generate an error, otherwise you're caught in an infinite loop.
You've clearly put some effort into this and I think you should know what changes to make. I'm attaching a modified version of your code with the tweaks I mentioned above. My recommendation is to try to make the changes yourself first, and then compare them to my working copy. Remember, there is no single solution to this.
04-11-2009 07:43 AM
Thanks very much, i've had a good look through what you did and had a go at most of it on my program and i'm pretty sure i understand everything and can arrive to a similar solution myself.
I'm very much looking forward to getting this up and running now. I've tested the program by setting up simulated hardware and i got it working which is a good start.
The final 2 steps are to modify it so that it acquires data from 7 channels, and then somehow port it so that it runs on a PDA. Do you have any experience working with the PDA toolkit? Any idea how much work it'll be getting this ported?
Just for interests sake we're going to be running a USB-6008 with an accelerometer, 2 pressure transducers, 2 passive magnetic pickups as wheel speed sensors, a throttle position sensor and a crankshaft speed sensor.
When adding more channels do i have to duplicate the DAQmx create channel.vi with each instance configuring 1 channel, or is it possible to create 7 separate channels using the 1 .vi?
I honestly can't thank you enough for all your help, I'm also glad that i've done it myself rather than getting someone else to do it, so bonus points for that one!
04-12-2009 11:44 AM
Unfortanately, I have no experience with the PDA toolkit so I can't help you there.
As for reading multiple channels you would not need to duplicate the Create Channels VI. All that you would need to do is to change the range of channels for the "physical channels" input if you're using that, or just to change the task if you're using the "task" input and you created the task using MAX. Check the documentation on the Create Channels VI and it will tell you how to specify multiple channels. I can't look at the VI right now, but if I recall correctly, I believe the data acquisition read should already have been setup to read multiple channels.
04-18-2009 06:29 AM - edited 04-18-2009 06:37 AM
I've had the chance to test the program with an accelerometer connected and it works brilliantly. I'm now onto the other program which reads and formats the data. I'm trying to open a TDMS file, then extract the results from the various channels within the file and display them onto some charts. I've attached a bit of code which I'm hoping to put into this program (i started it ages ago and don't have access to it right now), would someone be able to check that it's along the correct lines? Also how do I change the data type of the 2nd chart so that it will display the data from both the pressure1 and pressure2 channels?