03-06-2018 07:52 AM - edited 03-06-2018 07:55 AM
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
03-06-2018 09:11 AM
@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.
03-06-2018 09:21 AM
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
:
Here you'll see in the "Actor" are several types of synchronizations each with there unique purpose:
Now, who's the producer and who's the consumer?
Ultimately the USER is both.
03-06-2018 09:30 AM - edited 03-06-2018 09:52 AM
@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.
03-06-2018 09:46 AM
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.
As for the JKI State machine you can define macros/scripts within the state machine See below.
mcduff
03-06-2018 10:33 AM
@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.
03-06-2018 11:52 AM - edited 03-06-2018 11:58 AM
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.
03-06-2018 12:00 PM - edited 03-06-2018 12:11 PM
@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.
03-06-2018 12:25 PM
@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.
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
03-06-2018 12:27 PM - edited 03-06-2018 12:28 PM
@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.