Christopher Farmer is a guest blogger. He is an accomplished systems engineer and manager with nearly 20 years of experience, and runs Wired-in Software, an NI Alliance Partner based in Melbourne, Australia.
At Wired-in Software, we embraced DQMH in 2016 as a key tool for our LabVIEW Development. DQMH fitted our needs as a young and growing team. It provides us with good structure, and doesn’t require advanced LabVIEW knowledge or extensive OOP experience.
Recently, our company developed a “prototype” application for a customer’s product. After the first release, the customer requested some substantial changes in workflow and UI design. Making these changes fell to me, as the original developer was no longer available. The original developer had done an ok job with the prototype. They are an experienced and trusted developer, and I wouldn’t hesitate to work with them again. However the framework they created left me baffled. I found it difficult to locate things. UI buttons changed function depending on where in the workflow you were, and this made it hard to debug and figure out. It reiterated why a consistent framework within our organization was important. Granted, you can’t apply the same framework to every application.
So I decided to refactor the application using DQMH as the framework. It was a great chance for myself to actually develop with it properly for the first time. Since the application is not large, this was a risk worth trying.
I always sketch a design out for my applications, even if it’s just on a scrap bit of paper. Doing this helped define the modules and identify the critical messages occurring between the modules. This easily transitions to the development of the DQMH module and event creation. One day I’d love to see a tool that does this bit for you!
DQMH has a great sense of modular code. Creating a DQMH module allows for the most part for these modules to run in isolation.
One thing I noted is that I spent more time thinking about whether I needed a separate module for specific functionality. This seemed slow at the time, but on reflection, it meant I spent more time designing, and less time coding (ie. designing on the fly). So DQMH encourages me to consider my design more carefully from the outset. Once the decisions were made, implementation was quick and easy.
Picking out the meatballs
As Fabiola put it recently, pick out the meatballs of your code to reuse, and throw away the spaghetti! I was able to reuse specific code such as:
- The RS232 communications driver – already a lvlib full of functions specific to the device.
- Error Analysis functions
- Print functions
- Logging functions
The original UI was not reused, but it’s always been pretty easy to put a fairly good UI together in LabVIEW. I use a combination of Silver and System controls.
Modules can act as daemons
The modules can act as daemons. For instance, the Printer module has three simple requirements:
- Register for System Config broadcast messages to stay informed about which printer the software will use
- Periodically check that the afore-mentioned printer is “available”, and broadcast this information to a status panel
- Receive a request to print, and carry this task out.
In the past these would have all been regular sub-Vis being called throughout the application. Now with DQMH, the Printer module is a self-contained daemon that manages itself, and handles any printing-associated tasks.
This project was a great opportunity to start creating some Wired-in DQMH templates. We created a HMI framework module, a headless module, and a Sub Panel module (a module that will sit inside a sub panel container on the HMI framework front panel). By setting these up with Wired-in default items, I was then able to leverage these in building this application. So DQMH encourages reuse, and building the templates made it easy for me to invest in technical wealth. As a result, Wired-in are currently in the process of reviewing all of our past projects that use DQMH, and any modules that can be reused are being included in our Templates repository, to encourage more reuse amongst the team moving forward.
DQMH Modules resemble Classes
Something I realized is that the module is also like an object. The internal data cluster that feeds around the Message Handling Loop is the class data. If you set up the module as cloneable, then you can instantiate one or more clones of the same module. The data and methods are encapsulated. It doesn’t do inheritance, but I’m sure Fab will think of something! 😉
Working within Modules
DQMH is a wonderful example of the power of VI Scripting. Once created, a module is fairly easy to work within. I felt like I was able to concentrate on the code more, rather than facing architectural challenges. Code documentation felt easier, because I just had to concentrate on documenting the bits I added, and the structure is already documented. Like I said earlier, more time was spent considering how each module and its messages would be constructed, but once those decisions were made, the actual coding was simple. Some people say that a framework is all assumptions, no business logic. But here I feel like it was very easy for me to insert the business logic. There are a lot of supporting Vis that makes up a DQMH module that I am yet to learn their role, but I have trusted in the design, and so far it has not let me down. Delacor’s response to any issues has been swift.
The Bigger Picture
If there is anything a DQMH application lacks, it is the bigger picture. Mind you, this is often true for many other frameworks. Since LabVIEW is all about graphical representation and data-flow, I would love to see a bigger picture of my application – a bird’s eye view of all of the modules and how they relate to each other. It’s easy enough to sketch this up with Powerpoint or other drawing package. I was wondering whether a future version of DQMH might consider how it could use channel wires instead of events – this would provide a top level picture of how loops communicate with each other perhaps?
The project was a success. The software works reliably. The re-write took a little longer than I budgeted, but I have not heard of any issues from the customer since the last release, so the investment was worth it. I feel like the design makes sense, and I can understand the “flow”. My next exercise is to ask my team to review the code, to find out how easy it is to understand, and follow. We have identified some future expansion modules that will slot in quite nicely without interrupting too much of the present design.
LabVIEW Solutions Architect