03-24-2022 02:39 PM
Hello All,
I am working on a project in which I will be running tests inside of a furnace at various temperatures. I need to create a setpoint profile for controlling the temperature of the furnace. I was planning on doing this using the PID setpoint profile VI to do this. My goal is to run a code that will send temperature set point data to my furnace controller to define dwell times in which I will perform different tests. For example, I want to ramp up to 300 C, dwell for 20 minutes while performing tests, then continue on to 400 C, dwell for 20 minutes, perform tests, ramp to 500 C, etc..
I am fairly new to labview, What is the best way to layout the structure of this code so that the PID setpoint runs consistantly while allowing testing once a certain temperature is hit? I need this to be done in a way that I can record the current temperature versus time and the results of my tests.
My initial idea was to run the setpoint profile vi in a loop, then when the setpoint equals a certain value, a flat sequence begins to run a series of tests. This does not work though, as the setpoint profile stops working when the sequence is called.
Thanks for the help in advance!
-Nick
03-24-2022 03:47 PM
This sounds like a great application for a state machine architecture. Learn about state machines, look at the examples, and come back with questions (preferably attaching your code as it is very difficult to help debug words).
03-24-2022 04:45 PM
@johntrich1971 wrote:
This sounds like a great application for a state machine architecture. Learn about state machines, look at the examples, and come back with questions (preferably attaching your code as it is very difficult to help debug words).
To add to this, the PID control loops should be a parallel task/loop to your state machine to ensure it runs continually. Whatever you do, do not use sequence frame structures.
03-24-2022 07:04 PM
Maybe you can take a look at the dqmh framework (installable through VIPM).
There is a nice example that comes with it which is very similar to your application !
03-25-2022 11:58 AM
Hi Mark, Would you advise against ever using sequence structures? I have a series of tests to perform at each temperature, I was thinking to call a sub-VI from my state machine to run the tests using a sequence structure. Would it be better to have a sub VI for each individual test and call them individually from the state machine?
Thanks,
Nick
03-25-2022 01:27 PM
@NickIke1 wrote:
Hi Mark, Would you advise against ever using sequence structures? I have a series of tests to perform at each temperature, I was thinking to call a sub-VI from my state machine to run the tests using a sequence structure. Would it be better to have a sub VI for each individual test and call them individually from the state machine?
Thanks,
Nick
Why not make each test a state in your state machine? No need for a sequence structure.
03-25-2022 01:42 PM - edited 03-25-2022 01:45 PM
@NickIke1 wrote:
Hi Mark, Would you advise against ever using sequence structures? I have a series of tests to perform at each temperature, I was thinking to call a sub-VI from my state machine to run the tests using a sequence structure. Would it be better to have a sub VI for each individual test and call them individually from the state machine?
Thanks,
Nick
There are basically three cases where I will use a sequence structure.
1. To impose data flow where there is none. This will ALWAYS be a single frame sequence wrapping some piece of code which does not have any data dependencies therefore normal data flow is not available. One example would be to read the stop button in a while loop. I will warp the button in a single frame and then wire the last output of the internal code of the while loop to the frame. This will force the button read to occur at the end of the loop after everything has executed. Without the frame the Stop button will almost certainly be read at the beginning of the loop iteration and this will usually result in executing an extra iteration after the stop button has been pressed.
2. To wrap code that I am benchmarking for performance. This will be a three frame structure. The first will contain a call to the high resolution timer. The middle frame will contain the code I am benchmarking and the last frame will contain another call to the high resolution timer. This allows me to time the execution of the code in the middle frame.
3. In unit tests. The frames basically outline the flow of the unit test. This is generally 4 frames. First frame is test setup, second is execution, third is verification and forth is cleanup/teardown. I will only use this in unit tests/ Never in production code. Production code will be a state machine, queued message handler or some other more advanced framework.
Frame structures are much to rigid in their implementation and make maintaining and enhancing the code much more difficult.
To answer your specific question about using subVIs and a state machine, yes that would be an option I would recommend. Control the execution of your code using data flow as well as a code architecture such as a state machine. It would be an extremely rare case or me to use a sequence frame structure in any other manner than what I described above.
03-29-2022 11:45 AM
I'm still figuring out state machines - and Labview in general, but I've uploaded my VI here if anyone wants to check it out. I don't have any actual tests programmed in yet, but I am close to getting the test sequence dialed in.
Basically, the way this VI works right now is you select the tests you want to run then hit "Run Tests" and it cycles through the tests that you selected.
It works ok, but I am having trouble with the data flow inside each case structure. Currently, the VI shuts off the test button (ex: Test A), waits 2 seconds, then displays the status string. How can I control the data flow so that the status is shown first, then the wait, then the light turns off and finally the case structure goes to the next state?
Thanks,
Nick
03-29-2022 12:18 PM
@NickIke1 wrote:
I'm still figuring out state machines - and Labview in general, but I've uploaded my VI here if anyone wants to check it out. I don't have any actual tests programmed in yet, but I am close to getting the test sequence dialed in.
Basically, the way this VI works right now is you select the tests you want to run then hit "Run Tests" and it cycles through the tests that you selected.
It works ok, but I am having trouble with the data flow inside each case structure. Currently, the VI shuts off the test button (ex: Test A), waits 2 seconds, then displays the status string. How can I control the data flow so that the status is shown first, then the wait, then the light turns off and finally the case structure goes to the next state?
Thanks,
Nick
I can't open your vi because I've not yet moved to LabVIEW 2021. It's usually a good idea to save code for a previous version (usually 2 or 3 versions back) when the code is not dependent upon features of the current version.
To answer your question though, you could have a state that is "Update status," another state that is "waiting", another state to turn off the light, etc.
Also, you should really consider getting rid of those local variables. Use the terminals instead.
03-29-2022 01:17 PM
I would recommend that you look at examples such as the JKI state machine for better ways to implement your state machine. Also, don't think of a state as being a single test. Individual actions in the state machine should be relatively small so they can be re-used by other "states". Using something like the JKI state machine you will see that state transitions actually queue up a series of actions to perform. Generally it is not a good idea to have large complex actions as a single case in the state machine. If you wanted to make each test a subVI (not sure if I would recommend this approach unless you have a decent set of re-usable libraries the test can use), then you could consider using parallel loops. ne handles the overall logic and UI well the other performs the tests. You main UI loop would queue up the test to be executed and the tests themselves would return data back to the UI loop using a queue as well.