LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Prevent event structure from queueing items?

Solved!
Go to solution

@dthor wrote:

 I'd like to aviod using them because of just how many possible events I have...


 

Keep in mind you can register/unregister Dynamic Events in bulk by using arrays of references, as seen here (which is another great Idea to vote for)

 

0 Kudos
Message 11 of 16
(982 Views)

Here's what I've come up with for a solution using the Producer/Consumer architecture. It is also a slightly better example of how my actual program works. I needed to have the Dequeue Element inside the "wait for user" frames so that the loop would continue to process non-waiting frames.

 

I used the state machine's ENUM constant as the data type for the queue, and I added a case structure check on the waiting frames. If the queue element does not equal the current state, then it will send the queue element into the shift register.

 

Let me know if you have any comments on the Queue usage. Keep in mind that this is just a proof-of-concept, I'm not worrying about code efficiency or neatness. Some things may seem superfluous (such as unbundling the Header into separate Indicators or a STOP global variable), but those are there because I use them elsewhere in the real code.

Download All
0 Kudos
Message 12 of 16
(962 Views)
Solution
Accepted by dthor

 

  1. Everything in the Stacked Sequence structure can plop into your initialize case (actually, initialization of the Boolean locals is duplicated!)
  2. Use the Latching action for the Boolean controls, and place their terminals inside their respective Value Change Event Handler Cases. This makes for a more fluent UI, and actually removes the need for your local variable pre-initialization altogether.
  3. Use a "Format Into String" for building your filename from the header, and try a Format String something like "%s - %s - %s - %.3fmm.dat"
  4. I can't help but ignore your "Ignore here" comment - leverage autoindexing to your syntactical and execution efficiency advantage! 😉
Other than that, no low-hanging fruit pops out! Overall, respectable job in the state machine upgrade.

 

0 Kudos
Message 13 of 16
(955 Views)

One more item: I could butt heads with the suggestion that you split the UI into two loops. I commonly place Event Structure in a case structure (much more often than not, actually). Also, I only offload tasks from the event-driven UI loop if the task takes longer than 200-500msec or so to complete (which may actually be true in your case). You end up with better readability and maintainability if all UI ops are snappy enough to be handled by a single loop.

0 Kudos
Message 14 of 16
(951 Views)

Jack,

 

The stacked sequence does need to be there because it holds certain code that should only run once, such as verifying that instruments are active and communicating. That is, of course, unless I add a second "Initialize on startup" frame to the state machine that called only once. I also like the 2-sequence stack because I just throw most of the terminals on that page. You are correct that I have duplicate variable initialization. Opps 😛

 

I guess you missed my previous comment regarding the latched/switched booleans... They need to be switched because I use them as indicators as well: the "Run" button will stay on for any number of state machine frames. In this case, 7 frames.

 

I do normally use Format Into String... I actually love the damn thing. The concatenate was just quicker, especially before I changed "Size" from a string to a DBL.

 

And lastly, none of my tasks take more than 300ms, at least W.R.T. CPU time. Everything is speed-limited by either waiting for user input or by waiting for instruments to run voltage sweeps / return an SRQ.

 

Thanks for the feedback, it helps 🙂

0 Kudos
Message 15 of 16
(926 Views)
Commentary inserted in bold.

 


@dthor wrote:

 

Jack,  

The stacked sequence does need to be there because it holds certain code that should only run once, such as verifying that instruments are active and communicating. That is, of course, unless I add a second "Initialize on startup" frame to the state machine that called only once. Go for it! This is exactly what I do, and you'd be surprised at how often you can use this to your benefit: e.g., a "Reset Test" button. I also like the 2-sequence stack because I just throw most of the terminals on that page. You are correct that I have duplicate variable initialization. Opps 😛 

  

I guess you missed my previous comment regarding the latched/switched booleans... You're right. They need to be switched because I use them as indicators as well: the "Run" button will stay on for any number of state machine frames. In this case, 7 frames.

 

I do normally use Format Into String... I actually love the damn thing. Right on! The concatenate was just quicker, especially before I changed "Size" from a string to a DBL. Slacker! 😉

 

And lastly, none of my tasks take more than 300ms, at least W.R.T. CPU time. Everything is speed-limited by either waiting for user input or by waiting for instruments to run voltage sweeps / return an SRQ. This may be a good candidate for removing the QSM-PC in favor of a simple SM with embedded Event structures. Consider disabling/greying or hiding buttons when you don't want the user to click them to prohibit "stale/rogue" events from queueing up - this also boosts usability and intuitiveness. Again, folks can butt heads all day long over design patterns, but bottom line is readability and maintainability. The two biggest design patterns within the LabVIEW community are Producer/Consumer and State Machine (and the the hybrid QSM-PC). If you want to stump two-thirds of the LabVIEW community ask them to "name another design pattern". I find it worthwhile to point out that they're great patterns, but sometimes superfluous. The Law of the Instrument: "Give a small boy a hammer, and he will find that everything he encounters needs pounding."

 

Thanks for the feedback, it helps 🙂  


 

0 Kudos
Message 16 of 16
(917 Views)