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.

DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Implement Application State machine with DQMH Module?

We are finishing up the on paper design of an application for a test system.  This will be our first application using DQMH.  We have been studying it in detail, have watched most of the videos, and read many articles (Including the DQMH best practices article).

 

For this test application, we have broken the functionality into the following modules: AppMgr, UI, TestSequencer and Database.  Our UI has no logic (simply requests to show things, and broadcasts when the user interacts with it).  The Test Sequencer manages the execution of a list of tests and has a helper loop that executes the tests as state machines.  The Database module simply retrieves settings and records data in a database.  To promote responsiveness we are leaning towards using only requests and broadcasts instead of Request and Wait for Reply.

 

Our question is... how we should implement the state machine that we designed for managing the application? As currently designed, our AppMgr module needs to register for lots of broadcasts from each of the other modules.  We have modeled the AppMgr with a state machine that contains 8+ states.  The states do something upon entry and then perform various operations and sequences of operations when certain events are detected.  There are currently 14 broadcast events from other modules that the AppMgr would need to register for. This is a relatively complex application. 

 

Should this be implemented within a DQMH module? Our concern with using a DQMH module for the AppMgr is that although we can pass around a state enum through the MHL, the code seems like it might be harder to maintain since each message case would need to look at the state enum and any other state data to determine if the message should be handled and how to handle it.  This seems like the same way state was managed in the NI QMH pattern.  It seems like it would be easier to maintain the code if there was a case structure that had the state enum wired to the case selector, thus you could "see" everything related to a state within a single case.  It also seems like we can't use Request and Wait for Reply events in the AppMgr if we are trying to put all of the business logic in the MHL instead of helper loops.

 

As an alternative to using a DQMH module for the AppMgr, we were thinking the state machine structure might look something like this (it would need to register for more than 1 module's broadcast events, but the images below should illustrate our thinking):

AppMgr_eventstructure_statemachine_timeout.pngAppMgr_eventstructure_statemachine_eventcase.png

 

With that being said, is it better to simply use a DQMH module and check/change states within MHL message cases? Is our maintainability concern valid if we follow DQMH Best Practices?

 

Thanks,

Gary

 

0 Kudos
Message 1 of 4
(3,340 Views)

Hey Gary, have you looked into moving the state machine to a separate loop?

 

A blog post on helper loops: https://delacor.com/dqmh-actors/




DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)


Message 2 of 4
(3,311 Views)

Hi Gary,

You mentioned that you have done extensive reading, so before I go repeating something that you already checked out, have you checked any of the following?:

  1. Create a project from the DQMH project template: the Application.lvlib:Main.vi is implemented as a state machine
  2. Create a project from the DQMH CML sample project template: 
    • look at the Application module's Main.vi, it is implemented as a DQMH module. That VI could be executed as the main application VI.
    • look at the Top-level VI, it is a launcher that looks very similar to the API tester and it is created to show only when running in debugging mode
  3. Tip 4 "Tip 4: Create State Machine Inside MHL Case" at http://delacor.com/tips-and-tricks-for-a-successful-dqmh-based-project/

Thanks for your trust on DQMH,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
Message 3 of 4
(3,289 Views)

Hi Fab and Joerg,

Thank you both for your suggestions.  As we've looked into this more and evaluated the various approaches, it became more clear that there are several ways that we could implement our state machine.  We decided to end up splitting up some of our states that had a lot of functionality into into separate states (e.g. Init became Init UI, Init Equipment, etc.).  This seemed to address the maintainability concerns and removed some complexity because we could respond to broadcast events to know when certain operations were completed in order to transition states.  We ultimately decided to use a DQMH module as the top-level VI for our Test Application.  This Module is responsible for managing the application states and simply included a state enum on a shift register in the MHL.  So far it's been very clean and easy to implement.

Once again, thank you for the suggestions and we look forward to developing our application with DQMH!

Thanks,

Gary

Message 4 of 4
(3,221 Views)