LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Newbie doubt: two loops, one file, one graph

Solved!
Go to solution

Hello everyone!

 

I’m a chemist with very little knowledge of programming (only one semestre on fortran in the first year of university, and my own curiosity), but I was recently given the task of rewriting some of the software we use on a specific equipment in the lab. It was already written on LabView, but it lacked some functions we needed and had lots of functions we never used. It was written by a master student, who left before we could test the code. I tried my best to learn it in a month and on my own. This forum was a great help sometimes, but I still need help on a final detail.

My program must read Temperature from a temperature controller (which has been given a cooling ramp), in a loop, until the difference between two consecutive readings is larger than a given value. When the criteria is met, it reads from a lock-in, plots a graph, and writes the data in a file. It has to do so, until temperature reaches a minimum, which is input by the user.

Now my problem is: I want to do a second cycle, for heating, but I want the data for the heating part to be displayed on the same XY graph, and recorded in the same file.

But since the graph and the write file are inside the first loop, I cannot link them from the new loop. Soooo, where should I place the XYgraph and the file write controls, and how do I connect both loops to them, so that I can record both the cooling and the heating?

I hope I’m not being too confusing, I’m sending my cooling code (please don’t mock my coding skills, as I really am a newbie to this 🙂 ).

 

Kudos everyone, and thanks in advance!

0 Kudos
Message 1 of 12
(1,198 Views)
Solution
Accepted by gracabrotas

@gracabrotas wrote:

It was written by a master student, who left before we could test the code. I tried my best to learn it in a month and on my own. This forum was a great help sometimes, but I still need help on a final detail.


Sorry to hear that you have to deal with this, having so little LabVIEW experience. (And a fortran background will not help!).

 

So is this now mostly your code or mostly from the "master student". Have you looked a the typical design patterns (e.g. state machine)? Your already describe the various state of the execution, so try to directly translate that.

 

Correctly rewritten, it will fit one one screen and probably won't need most of your sequence structures. Note that if you wire the error cluster up between all the GPIB operations, execution order will be defined even without that tapeworm of a multiframe outer sequence structure. 

 

Since you are writing simple tab delimited headers in the first frame, you probably want to append one tab delimited row in the innermost loop. All you need is open the file once before the loop and append a new row using simple file IO. Using express VIs is way overkill and much less efficient.

0 Kudos
Message 2 of 12
(1,177 Views)

Thank you very much for your answer.

Most of the small things are from the master student (honestly, when I picked it up, I could not even put a file together or even send a command to a GPIB 🙄), but the tapeworm multiframe outer sequence structure is really mine. I was trying to follow a linear thinking for the code (like, first you do this, next you do that). I was not familiar with state machines, but I already watched a couple of youtube videos, and I really think that is the way I need to go!

Again, thank you so much for taking the time to answer me.

 

Kudos!

Message 3 of 12
(1,145 Views)

@gracabrotas wrote:

Thank you very much for your answer.

Most of the small things are from the master student (honestly, when I picked it up, I could not even put a file together or even send a command to a GPIB 🙄), but the tapeworm multiframe outer sequence structure is really mine. I was trying to follow a linear thinking for the code (like, first you do this, next you do that).


When you need to control the order of execution using the Error in and Error out terminals are often useful. There is rarely a need to use a sequence structure. I agree that a state machine would really be beneficial for your application.

 

0 Kudos
Message 4 of 12
(1,126 Views)
Solution
Accepted by gracabrotas

Even without using the errror wire, execution order can be fully determined by placing repetitive code inside a FOR loop. Compare the picture. Same functionality (and yes, I still recommend wiring the errors, not shown):

 

altenbach_0-1605812576358.png

 

0 Kudos
Message 5 of 12
(1,116 Views)

Wow! That's really different from what I had, and looks really cleaner. Thanks for the suggestion!

I've already begun a new program with the state machine architecture! (wish me luck! 😅) I will try to use the error cluster, but now I have two options!

Thank you very very much again!

Message 6 of 12
(1,098 Views)

Hi again everyone!

 

Thanks for all your answers! 

I've managed to build a state machine, and I am really proud of it!! It took me a while to understand about shift registers and local variables, so that it would do everything I needed, but I think I managed it, and I am really happy about it! I only still have a problem left - writing the file!

Initially I had a tab delimited headed file, that was initialized in the beginning of the program, and then was updated using the express VI. (you can see the original code in my original post)

 

altenbach pointed out "Since you are writing simple tab delimited headers in the first frame, you probably want to append one tab delimited row in the innermost loop. All you need is open the file once before the loop and append a new row using simple file IO. Using express VIs is way overkill and much less efficient."

 

However, I cannot seem to find a way to do this. I've watched many videos on this matter, but I don't find some of the buttons they use. Maybe it's because I'm using Labview 7.1 (unfortunately, it's the only one we have a license for) and there are some functionalities which are not available.....

 

Is there any simple and elegant solution to this?

 

Again, I'm so thankful to you all, and honestly, really proud of my new program! 😅

 

Kudos!

0 Kudos
Message 7 of 12
(1,026 Views)

Looks pretty good (or at least better ;))

 

Some quick notes:

 

  • "actual state" string should also go into a shift register.
  • You don't need the inner while loop in the "check deltatT" case. Use the outer loop to repeat the state and only go to the next state if the condition is met. (you can make the outer wait state-dependent if this should occur faster)
  • You don't need the sequence structure in the "end" case. The case does not output anything until everything in it has completed.
  • If you would place your controls before the case structure, you can eliminate many locals.
  • Similarly, if you would place the Actual T" indicator on the orange wire before the case structure, it would never contain stale data (initialize the SR with NaN, same for the output in the first state). Similar arguments for MinK.
  • Focus on more consistent error handling.
  • Your enum should be a typedef. Right now you have diagram constants of it scattered everywhere and if you ever need to e.g. add a new state later, it would be like herding cats to update every instance.
  • etc.
0 Kudos
Message 8 of 12
(1,011 Views)

Hello! Thank you  for your quick notes! For some of them I still have questions, if you don't mind helping

 

  • "actual state" string should also go into a shift register.

well... In the beginning I had a lot more shift registers, but I thougth they made the code look messier with all the wires going around, so I replaced some of the with local variables. My mistake I guess, although I don't quite understand why local variables are that bad.... However, for the "Actual state", my problem was I needed it to be one of the triggers to end the program, and with the shift register It wasn't working as I needed.

 

  • You don't need the inner while loop in the "check deltatT" case. Use the outer loop to repeat the state and only go to the next state if the condition is met. (you can make the outer wait state-dependent if this should occur faster)

I see what you mean here, but wouldn't that mean that this state needs to access two states? and I only have one "blue" shift register.... How do I use the outer case as a loop without a looping condition and a stop?

 

  • You don't need the sequence structure in the "end" case. The case does not output anything until everything in it has completed.

This one I really get. I deleted it already!! 

 

  • If you would place your controls before the case structure, you can eliminate many locals.

Yep, I get this, I was just trying to minimize the amount of wires going around. I didn't know it was such a bad option.

 

  • Similarly, if you would place the Actual T" indicator on the orange wire before the case structure, it would never contain stale data (initialize the SR with NaN, same for the output in the first state). Similar arguments for MinK.

Ok, I'll try to do this.

 

  • Focus on more consistent error handling.

Honestly, this is a first version, and I was just trying to make it work, so we could use it in the lab.... afterwards I will continue to work on it to improve it, but I really need it to work for now! 😉

 

  • Your enum should be a typedef. Right now you have diagram constants of it scattered everywhere and if you ever need to e.g. add a new state later, it would be like herding cats to update every instance.

Yeah, I saw this in many videos, but I couldn't find it.... I'm working on LV7.1, so I think I don't have that feature.... 🤔

 

Anyway, the only thing I really need now to use the program, is to write the file, as I explained I the previous message, do you have any suggestion on how to do that?

 

Thank you very much for all your help!! 

0 Kudos
Message 9 of 12
(997 Views)

 

  • Your enum should be a typedef. Right now you have diagram constants of it scattered everywhere and if you ever need to e.g. add a new state later, it would be like herding cats to update every instance.

Yeah, I saw this in many videos, but I couldn't find it.... I'm working on LV7.1, so I think I don't have that feature.... 🤔

 


You definitely have typedefs in 7.1  When you save your enum constant or control as a control file, open it up and change the dropdown at the top to "Type Definition" rather than "Control".

0 Kudos
Message 10 of 12
(982 Views)