LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help Needed with Limit Condition, Stop Functionality, and Cluster Implementation in LabVIEW using Queued message handler

Hi everyone,

 

I need to create a continuous counter in LabVIEW. The counter should increment whenever the input value exceeds a specified threshold. Additionally, the program should periodically check the status of this condition after a set interval.

 

I have a few questions:

 

  1. Limit Condition: I don’t want to set the limit to zero when starting the program. How can I ensure this doesn’t happen? Any suggestions on how to handle this?

  2. Error Threshold: Since I have both a counter and a limit in the program, I'm wondering if I still need an error threshold. Does it make sense to remove it, or should I keep it?

  3. Stop Functionality: When implementing the stop button, how can I make sure that there are no messages left in the queue when it's pressed? What’s the best way to handle this in a QMH?

  4. Cluster and Shift Register: I was advised to use a shift register, and unbundle and bundle by name instead of using local variables for storing data in a cluster. Can anyone provide a lead or guide me on how to implement this?

I've also uploaded the VI for reference if anyone wants to take a look and provide more specific feedback.

Thanks in advance for any guidance!

0 Kudos
Message 1 of 3
(163 Views)

Many years ago, when I was first learning LabVIEW (having programmed previously with text-based languages, my all-time favorite being Pascal), I "inherited" a LabVIEW Real-Time routine used to study sound localization in complete darkness using large primates (mostly BME Graduate Students).  The original code was a mess, many hundred VIs and TypeDefs, with the main DAQ routine (printed at 50% reduction) requiring a "scroll" of about 18 sheets of printer paper.

 

I decided to "start over" and chose the QMH as my model.  Yikes!  I didn't "get it", and basically abandoned it for a Queued State Machine.  From looking at your code, you also "don't get it".

 

I find that many of the LabVIEW routines I've developed are "task-driven", and seem to be a "natural" fit for a State Machine architecture.  What does your program want to do, and how does it go from doing one thing to doing something else?

 

You might check out the JKI State Machine (which you can get from VIPM, which you probably installed when you installed LabVIEW).  When Channel Wires were introduced (as a Hidden Feature in LabVIEW 2015, and fully supported in LabVIEW 2016), I replaced Queues with Messenger Channels and called it a "Channel Message Handler".  It seemed to impress some people at NI, as there is now a Channel Message Handler example that ships with LabVIEW, though I find that it, too, is overly-complex.

 

I find that many of the LabVIEW tasks that I develop follow a model I'll call the Channel Messenger State Machine.  The main Loop is the Message Handling Loop -- a Messenger Writer sends an initial Message (through a Messenger Channel Wire) into a While Loop where it goes to a Messenger Reader that outputs the Message (in my case, a TypeDef called "State" + a Variant called Data, usually empty) and sends them into a Case Statement, with "State" wired to the Case Selector.  So if the State was "Initialize", you do whatever initialization you need in that Case.  I run State Variables, either bundled into a Cluster that I can read or write as appropriate, or if only a few variables, individual wires held on Shift Registers on the outer While Loop and passed through each of the Case elements -- using the Linked Input Tunnel makes maintaining 5-10 wires at the top of each Case a breeze, since you do it once, and LabVIEW wires up the remaining Cases for you.

 

You travel from one State to another based on two main decisions -- at the end of a Case, you might know "what do I do next?".  If so, you have a "Send State" VI that has an input for "State" and for "Data" which bundles them into a Message Cluster and creates a Messenger Channel Wire that you bring out the right (output) side of the While Loop, up, over the top, back to the left, down, and join with the Channel Wire from the initial Message Writer that sent "Initialize".

 

Another way you can send a message is with an Event Structure.  Let's say you have a "Begin" and a "Stop" button.  Put Begin in a "Value Change" Event, have it send a "Begin" Message out of the Event Handler loop, down to the Messenger Channel Wire you just created for your State Machine loop -- when you push "Begin", the Event Loop will send "Begin" to your State Machine which will execute the "Begin" State.  Same thing for "Stop".  No Queues to create or release.

 

To prevent having Limit set to 0 at the start of the Program, make Limit one of the variables in the Shift Registers at the top of the Message-handling Loop, and set it to whatever you want (say, 1.5).

 

For Error Handling, I always have an Error Line running (absolutely straight, no kinks) through the Message Handling Loop.  Between the right-hand Case and While "walls", I put an Error Handler routine that the Messenger Channel Wire goes in, and comes out.

Here's a picture of one --

CMH Error Handler.png

 What I chose to do is if there's an Error on the Error Line, I throw away the current Message, clear the Error, and make the next Message "Error Travel" (Travel is the name of this routine), passing the Error itself as the data.  In this case, I know that Error Travel will display the Error, and force the program to Exit.  In the case of no Error, I've already read the Message, so all I have to do is send it to another Message Writer and out it goes as if nothing happened.

 

I have two loops running here -- the Event Loop and the Message-handling Loop.  I need to make sure both loops stop.  If I press the Stop button on the Front Panel, that goes to the Event Loop, which can stop itself, and send a "Stop" message to the Message Loop.  If the Message Loop decides to Stop (as in the Error routine I mentioned), I can use an Event Messenger in the Exit state to a Dynamic Event terminal to create a User Event that can stop the Event loop.

 

Oops -- I just realized your second point was not about Error Handling.  Oh, well.

 

Stop Functionality -- instead of having the Stop button tell the State Loop to go to the Exit State, it can set a "flag" in the State Loop that the State Loop checks and says "Shall I stop now?".  Frankly, I've not run into this situation in my own work -- Stop means "Stop now".

 

Cluster vs (multiple) Shift Registers.  My "rule of thumb" is 6-8 Shift Registers closely spaced together take about an inch of screen space, quite tolerable (my Block Diagrams all fit on a single Laptop screen).  More than a dozen (very rare, for me) I would cluster and Unbundle/Bundle (possibly with an In-Place Element structure).

 

Longer than I meant to ramble on ...

 

Bob Schor

 

 

 

0 Kudos
Message 2 of 3
(125 Views)

These are all very basic issues and a forum post is not the right way to learn the tools of the trade. You need to learn how to swim before diving into the deep end! Have you done any tutorials yet?

 

  1. You can enter any value into the control, then select the control and make current value the default (select control.. edit..make selected value default). Same for any other control.
  2. A counter exclusively deals with integers and should be blue (typically unsigned integer if you want to wrap at the data limits), never orange. How much do you know about the various data types? Just put the count into an initialized shift register (see below).
  3. Why would it matter if there are messages left if you want to stop things
  4. You already have a shift register from the template that bundles and unbundles, so study that. Nothing new!

 


@dhruv1725 wrote:

I need to create a continuous counter in LabVIEW. The counter should increment whenever the input value exceeds a specified threshold. 


I assume you want to increment whenever the value goes from below to above the threshold. Do you also want to count if it is already above and stays there?

 

Some other observations:

  • Why would you call a speed control "change speed". You are entering a speed, not an acceleration, (right?) so the name should just be "speed".
  • There is no way to tell which position of the start_pause switch is what.
  • The user needs to be aware what the difference between stop and exit is.
0 Kudos
Message 3 of 3
(104 Views)