From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Reinitialize defaults when anything causes the program to stop running.

Hi everyone,

 

I'm pretty new to LabVIEW but have become the person in charge of reworking the code that runs the MFCs on our vacuum system. We run toxic gases, and as such, I wanted to know if there was a way to properly reinitialize the default values of the MFC inputs (all to 0) anytime something makes LabVIEW close or somebody aborts the execution of the VI.

 

I've tried using an Invoke node for my MFC cluster inside an Event Structure using both the notify and filter events for both Application Instance Close and Panel Close, but both of these have failed to shut off nitrogen flow. I've gotten the Panel Close? filter event to work with the invoke node, but only if LabVIEW prompts me to save changes before shutting down.

 

Any insight would be greatly appreciated. Thanks!

0 Kudos
Message 1 of 8
(2,814 Views)

Hi everyone,

 

I'm pretty new to LabVIEW but have become the person in charge of reworking the code that runs the MFCs on our vacuum system. We run toxic gases, and as such, I wanted to know if there was a way to properly reinitialize the default values of the MFC inputs (all to 0) anytime something makes LabVIEW close or somebody aborts the execution of the VI.

 

I've tried using an Invoke node for my MFC cluster inside an Event Structure using both the notify and filter events for both Application Instance Close and Panel Close, but both of these have failed to shut off nitrogen flow. I've gotten the Panel Close? filter event to work with the invoke node, but only if LabVIEW prompts me to save changes before shutting down.

 

Any insight would be greatly appreciated. Thanks!

0 Kudos
Message 2 of 8
(2,799 Views)

Hi Eric,

 

reinitialize the default values … anytime something makes LabVIEW close or somebody aborts the execution of the VI

Yes, sure!

Program your VI so the user can never abort it!

Program it so it will never close "on its own"!

 

- Hide the tool menu for running VIs.

- Create executables so your users will never work with VIs in the IDE.

- Check for errors.

- Before you stop your program you need to output your "default" values…

- Think about state machines…

 

I've tried using an Invoke node…

Ok, you write to an invoke node when your program exits? What should happen when the program just exits?

You need to avoid "exiting" your program when you want to execute certain parts of your code…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 3 of 8
(2,809 Views)

Let me "second" what GerdW said, and add a few things.

  • I've been using State Machines (sometimes disguised as a Queued Message Handler -- the "Message" is the "State + Data", so to speak), and (almost) always have an Initialize (the first State executed), an Error (which does not cause the program to Exit, but "does what is necessary" to clean up), and an "Exit" (which is the only routine allowed to stop the State Machine and to tell the other loops to exit).
  • If I want a "manual stop", I sometimes put in a "Stop" button, but this usually takes me to the "Stop" State which is in charge of "orderly shutdown" until it is ready to call "Exit".
  • A trick that many experienced LabVIEW developers know (and that I learned from Fabiola de la Cueva) is to have an Event for the Panel Close? Event (when the user pushes the Windows "Close" symbol in the upper-right corner of an Application).  The Event calls the Stop State, but also "discards" the Event to prevent Windows from stopping the Application early, allowing you to do an orderly shutdown/exit.
  • I'd put the "Return the Controls to a Safe State" as part of the Stop State, though you could have a separate "Return Controls to Safe" State that Stop calls, and let the new State call Exit.
  • A well-designed (and documented) State Machine can lay out the (sometimes complex) logic of your Application, allowing Developers and Users to see the broad structure of the code and suggest modifications when new functionality needs to be added (or old functionality removed).

Bob Schor

0 Kudos
Message 4 of 8
(2,768 Views)

@EricJHU wrote:

 

Any insight would be greatly appreciated. Thanks!


OK, you need to discard the "panel close?" filtering even by wiring a TRUE to the discard? terminal, then trigger all your shutdown code instead. Resetting all values to default is ineffective if the program closes nanoseconds later, before the new values have even been read elsewhere in the code and propagated to the external hardware.

 

Of course there also needs to be external, non-software features to properly shutdown the hardware if somebody would accidentally unplug the computer or the computer crashes due to some other event.

 

It is difficult to tell but it seems that the communication with the hardware is via TCP/IP. Is on the other end a cRIO or similar, also running LabVIEW code? In this case you could implement some watchdog code there that automatically shuts down the hardware if no communication has been received from the master over a certain interval.

 

In any case, looking at the code I see big NoNo's! It is a mess with many very questionable constructs and many places where race conditions and even deadlocks could hide. Some casual observations:

 

  • Lose the stacked sequence structure and the sequence locals. This is a hallmark of bad coding, it fragments the diagram. all you do is open and close the tcp connection in the flanking frames and since the connection is wired across the main structure, dataflow already determines proper execution order, even without the sequence structure. (see also)
  • Never (never!! ever!!!) hide event structures inside case structures. They accumulate events in their queue whenever an event occurs, and if the case never activates, they can never execute them. Once the case activates, you might first get an event that got triggered days ago! (Imagine that the vent is ON but the pressure is too high: You'll accumulate thousands of events on no time due to the value signaling. Could happen if the vent valve gets stuck, for example 😄 Murphys' law is alive and well!)
  • Never have more than one event structure in a loop. (You make them "transparent" with an empty timeout to prevent deadlock, but that is a horrible kludge).
  • Keep the diagram size to one screen.
  • Partition repetitive code into subVIs.
  • Most of your scaling and math could be done on arrays instead, using 10% of the code.
  • How many instances of the same numeric diagram constant do you possible need? One each is sufficient, you can branch the wire. Currently, if one of the calibration constants needs to be changed, you need to make identical changes in dozens location and the probability that you forget to change one grows exponentially.
  • Minimize the use of local variables. Sometime you read the same local variable several times in parallel. Again reading once and branching the wire is better, but maybe you don't even need the locals.
  • "Index array" is resizeable. no need for dozens instances next to each other and branching of the array wire..
  • You need to implement some error handling. For example if the network connection cannot be established, the main code should probably not run, right?
  • ...

This is just the tip of the iceberg. My laptop screen is only 1080p so I cannot efficiently inspect your code. Good luck!

 

 

0 Kudos
Message 5 of 8
(2,761 Views)

And certainly you need to stop using the Abort button.

 

What was that LabVIEW Proverb?  Oh yes. 

Capture1.PNG


"Should be" isn't "Is" -Jay
0 Kudos
Message 6 of 8
(2,757 Views)

@altenbach wrote:
  • Most of your scaling and math could be done on arrays instead, using 10% of the code.

Here's a quick example how you could use array operations. Also check the math for your convoluted unsigned>signed 16 bit integer conversion (insert on right).

 

 

0 Kudos
Message 7 of 8
(2,753 Views)

Shame on me for posting a response without first looking at the code!  The First Priority should always be to have code as "clean and transparent" (meaning easy to see and understand by someone who knows LabVIEW) as possible.  If you can't understand the code by looking at it (which means not having to scroll around just to see the entire Block Diagram), you won't be able to grasp the logic and feel confident in handling "unusual cases" such as shutdowns and error conditions.

 

Bob Schor

0 Kudos
Message 8 of 8
(2,736 Views)