LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

I need something like a Queue but different

It sounds like you're doing something pretty similar to what I do quite regularly using a QMH structure.  I have independent loops for each instrument / DAQ device / etc.  They *predominantly* play the role of producers which send their data up to the Main loop.  Once they get started into acquisition mode, they just keep pumping data up to Main.

 

However, they *also* have their own message queue where they can receive messages such as "start", "stop", "fast", "slow", etc. to control their operation.  These messages either cause an action or change the "state" of the instrument loop.  The way you change "state" is by manipulating the "state variables" in a typedef'ed cluster that passes through all the message cases.  

 

There are different mechanisms to keep an instrument loop iterating and reading autonomously.  Opinions vary, and each has pros and cons.  The simplest to describe is the one that comp sci theorists shudder at.  At the end of a successful "Read" operation, enqueue another "Read" operation for yourself (unless the state variables are telling you otherwise).   There's a certain inherent danger in feeding messages into your own queue though, so it's better to find methods that use the Dequeue timeout. 

 

A better method is to have state variables for the timeout value and the default message to process on a timeout.  Your "fast" and "slow" messages might merely change the timeout value.  Your "start" message might set the default action to "Read".  Your "stop" message might set the timeout to -1 (infinite).   This kind of approach is more robust and deterministic than just having the "Read" case feed itself another "Read" message.

 

Over time, I've built up a library of functions that let me incorporate "scheduled messages" into my QMH loops.  This makes it easy to do things like schedule a Read every 0.1 sec while also scheduling a health check every 5 seconds.  But the simpler approach above works just fine if there's never more than one 1 periodic repeating message at a time.

 

 

-Kevin P

 

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 11 of 43
(1,227 Views)

@Yamaeda wrote:

Your Scan Interval delay shouldn't be in the Consumer, but in the producer.

/Y

 

I don't want the instrument to only measure once a minute if that is the data logging rate,

 

I want the instrument to continue to measure at its configured update rate and save the last reading once a minute.

 

 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 12 of 43
(1,203 Views)

I do like Kevin's approach.  I often have a "Dual" Message structure.  I don't however shy away from a self enqueuing Message handler.

 

Let look at this from a recent project of mine

:1TG.PNG

Here you'll see in the "Actor" are several types of synchronizations each with there unique purpose:

  1. A Command Queue: Yes the old Cluster of String, Var.  I have a few Use case provisos that are checked by review and a style guide when using this type of Queue.
    1. DO NOT NAME THEM! If I want someone else to jump into the Actor's business I can always pass a queue ref to them explicitly but the actor is in control of who can get in its business
    2. Strings suck so I require some "Default" case and will throw this puppy1Error.PNG
    3. The Event Structure always uses "Enqueue Opposite end"
    4. The QMH is responsible to flush the queue in the appropriate cases
    5. Why? contrast that to a named queue driven QMH from a "Typical" template wher the queue is named and some developer enqueues a close in the close case (common practice: If I ever find out who started it I'll punch them) and the QMH runs great once but when re-called to action - it sees that close on the queue first and enqueues another close while closing (the INIT should have enqueued opposite before the loop and flushed just in case some moron tried to close in an exit case but I digress).  Keep those things in mind and a self enqueueing actor is safe, simple to control and easy to maintain.
  2. A Notifier to pass state data to whomever cares: Notice this one IS named I don't care who wants to subscribe to the data the QMH is producing so its a public broadcast.
  3. User Events: these are "Generic UI Broadcasts", Or EXACTLY what I think RTSLVU meant by "..2TG.PNG ..something works like a Queue in a Producer/Consumer but in reverse or really in parallel"  These are tossed by the UI by the User interacting with the FP (or other event activity) Like So: the API for "Tour Guide" includes "Launch TG" seen before the loop, Close TG seen after the loop, TG Status that reads the Notifier in the status loop, and Pause TG seen in the Pause VC Event case which throws a "Pause/Resume" Event having a boolean value Constant "T"

 

 

Now, who's the producer and who's the consumer?

Ultimately the USER is both. 

 

 

 


"Should be" isn't "Is" -Jay
0 Kudos
Message 13 of 43
(1,201 Views)

@mcduff wrote:

Attached is a simple example. You will need to play around with them and learn how to use them.

 

Cheers

mcduff

 

 

 


That looks like what I want but I don't have really any user events once the program is started. This is more of a "set and forget" program that fully automates the majority of testing we do. The part you don't see is where it loads a "test script" and controls all the power sources and loads in the test rack based on the conditions and durations set in the scripts.

 

Sure I am polling the front panel controls but there are only four controls on the front panel, Load test script, Start, Abort, and Run Continuous to loop a script at the end.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 14 of 43
(1,198 Views)

I use a combination of USer Event and the JKI State Machine to make an architecture similar to a QMH only with user events.

 

See https://decibel.ni.com/content/docs/DOC-12159 for details.Snap3.jpg

 

As for the JKI State machine you can define macros/scripts within the state machine See below.

Snap5.jpg

 

 

mcduff

0 Kudos
Message 15 of 43
(1,196 Views)

@RTSLVU wrote:

@mcduff wrote:

Attached is a simple example. You will need to play around with them and learn how to use them.

 

Cheers

mcduff

 

 

 


That looks like what I want but I don't have really any user events once the program is started. This is more of a "set and forget" program that fully automates the majority of testing we do. The part you don't see is where it loads a "test script" and controls all the power sources and loads in the test rack based on the conditions and durations set in the scripts.

 

Sure I am polling the front panel controls but there are only four controls on the front panel, Load test script, Start, Abort, and Run Continuous to loop a script at the end.


Maybe I am not explaining what I want very well as most of the solutions involve User Events, but once my program is running I really do not have any User Events beyond someone hitting the "Stop" before the end of a test.

 

  1. This is an automated test.
  2. A "test script" is loaded that controls all the power sources, loads, etc. in the test rack
  3. Once a test is started there is no user interaction beyond the ability to stop a test in progress
    1. In the future I may add the ability to select and display live data on a chart or graph 
  4. Fast or Slow logging rates set per step by the test script
  5. Acquisition is using a Yokogawa power analyzer 
    1. High speed logging would be logging at the instruments sample rate (50mS)
    2. Low speed logging at user defined rate (usually 10 seconds to 1 minute
  6. The Yokogawa needs to be reconfigured when changeing from Slow to Fast or Fast to Slow logging
    1. Aquisition needs to be stopped 
    2. Analyzer reconfigured (averaging, update rate, etc.)
    3. Aquisition needs to be restarted
  7.   The main program needs to pass these to the acquisition loops
    1. Start, stop aquisition
    2. Fast, slow aquisition
    3. Low speed data file reference 
    4. New data file reference for each high speed acquisition step
    5. Low speed data logging interval
    6. VISA reference for power anaylizer (or instrument cluster)
========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 16 of 43
(1,184 Views)

I think you misunderstand User Events. They are not named very well.  User Events are are programmatically generated, and require no user intervention at all.

0 Kudos
Message 17 of 43
(1,174 Views)

@Mancho00 wrote:

I think you misunderstand User Events. User Events are not named very well.  User events are events that are programmatically generated, and need no user intervention at all.


You are right I do not understand them at all and in all of the User Events examples "events" are generated by an event structure that is triggered by the user changing the state of a front panel control. 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 18 of 43
(1,167 Views)

@RTSLVU wrote:

@Mancho00 wrote:

I think you misunderstand User Events. User Events are not named very well.  User events are events that are programmatically generated, and need no user intervention at all.


You are right I do not understand them at all and in all of the User Events examples "events" are generated by an event structure triggered by the user changing the state of a front panel control. 


OK, so you need to learn how to use "Generate Event"  After what you mentioned earlier I would really recommend events like.

 

  1. Start Sequence (File path, operator info, station info, Report path)
  2. Start Step (Step parameters like Acq Speed, Timeout, Limits, ....)
  3. End Step ( Result as enum <Error, aborted, Failed, unknown, skipped, invalid, Passed)
  4. End Sequence (Report)
  5. .....

and use  your step engine to hand off the events to your actors.

 

If we take a look at another part of that same library (TourGuide: a lightweight Turing complete, step sequence engine)

You'll see that when I end a sequence the actor throws a User event that the Example registers for dynamically

 

Capture.PNGCapture1.PNG


"Should be" isn't "Is" -Jay
0 Kudos
Message 19 of 43
(1,148 Views)

@RTSLVU wrote:

 

You are right I do not understand them at all and in all of the User Events examples "events" are generated by an event structure that is triggered by the user changing the state of a front panel control. 

User Events aren't generated by an event structure.  An event structure is registered for the event, so when the event is generated anywhere in the code, the event structure can respond to that event.

0 Kudos
Message 20 of 43
(1,145 Views)