DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Questions about a module to monitor an analog input

Hi,

 

I my test sequences, I usually make the user press a "start button" to start the test sequence (or press "enter" on keyboard).

 

Now I want to make this also automatic, so there is an USB6001 analog input that when it's 0V when the fixture (bed of nails) is open, and 5V when it's closed. When the fixture is closed, my loop will receive the event to start (just like the click on the start button, or the enter key pressed).

 

So I thought about DQMH module would be a perfect fit for this.

 

I originally thought that a DQMH is a "state machine that can communicate with external modules or VIs".

But after the following considerations, I think a DQMH is not always a state machine.

 

I am doing this module like this:

 

MESSAGES TO THE MODULE (from outside):

 

  • "CHECK" (this message is basically the start of the module, to check if analog input (ai) is >4,5V or not). The data acquisition is very quick so I am evaluating self-messaging every 500ms vs helper loop.
  • "TEST FINISHED" (this message is sent from my test sequence, and it will automate the opening of the fixture. Once test sequence is finished, the fixture is closed and I need to be in different state otherwise the test will start again), I will auto message this if ai<0.5V, otherways I will automessage "CHECK"

 

MESSAGES (BROADCASTS) FROM THE MODULE (to registered handlers that are outside):

 

  • "TEST STARTED" : when ai > 5, this message is broadcasted and then I dont auto-message anything, so the module will just wait other messages (TEST FINISHED or STOP/QUIT)

 

0 Kudos
Message 1 of 6
(2,314 Views)

Hi Konan,

 

You are correct - a DQMH module in its default state (or more simply the Queued Message Handler design pattern), is not a state machine. For a good discussion on state machines with DQMH, take a look at Joerg's reference design here: https://forums.ni.com/t5/Random-Ramblings-on-LabVIEW/Parsing-State-Machines-An-Iterative-Design-Proc...

 

With regard to Check, be careful about using "Self messaging" in a Queued Message Handler. We used to do this a fair bit and it got us into trouble in the early days of us using DQMH, because you can't guarantee things will happen when you need them to, or in the order you're expecting. A helper loop might require more code, but it is a safer choice.

 

One way to handle this is to have a helper loop do regular quick reads of the input, and call the TEST STARTED broadcast when AI > 5V. From here, you can put the state (Open or Closed) onto the MHL queue each time the state changes, and place it in the MHL internal data.

 

So when the Check Request is received, you can simply reply with the current state.

 

I don't see why you need Test Finished. Is your DQMH module also controlling a digital output? I wouldn't expect your DQMH module needs to know the test status.

Christopher Farmer

Certified LabVIEW Architect and LabVIEW Champion
DQMH Trusted Advisor
https://wiredinsoftware.com.au

Message 2 of 6
(2,273 Views)

I have an INGUN fixture/bed of nail.

It is manual so the operator will have to "close it" so the nails contacts the DUT and the test sequence can start.

 

I am using a USB6001 (among other things), in particular I have cabled things so that:

  • when fixture is closed --> Dev1/ai6  will measure 5V ---> I can start my test sequence on the DUT
  • when fixture is open --> Dev1/ai6 will measure 0V

I call my DQMH module as "AutoStart".

 

When my Functional Test Software starts, I do this:

  1. configure all my objects (HAL) and UI.
  2. start "AutoStart" module (it has a copy of an object that has a method to read Dev1/ai6)
  3. register my loop for "AutoStart's events" & sync it (usual stuffs from DQMH howto)
  4. send a "check" message: in the event handler, x = read(Dev1/ai6) --> if x >4,5V fireBroadCastEvent("StartTest"), else { wait(500ms), send "check" message (auto-message)}

 

In my FunctionalTest, I handle the "StartTest" broadcast event (I am registered to it as user event), and inside the event handler I just call ButtonStart.ValueSignal(True) on my UI button.

 

In this way I have automatically binded the start of the test sequence to an analog input.

 

Now the test will start....

Notice that in this moment the DQMH module is IDLE. It has only fired the event "StartTest" and it's just idle, waiting other messages.

 

after some seconds.... when test sequence state machine will end (either PASS or FAIL), I SEND a "TestFinished" to my DQMH module.

 

I need to send this because I need to "rearm" the start. 

 

The user must OPEN the fixture (and I need to know this), insert another DUT, and close the fixture

 

So inside the "TestFinished" DQMH event handler, I check for the opening (read Dev1/ai6, and see if it is <0,5 --> still closed --> automessage TestFinished, ELSE send "Check" message ---> the fixture has been opened and now I will check for the closure.

0 Kudos
Message 3 of 6
(2,269 Views)

I would definitely go with a "proper" state machine in a separate helper loop. Of course I'm biased because we took some time to develop such a reference design based on SSDC's fantastic design (thanks Chris for mentioning it) for ourselves and we're very happy with it; it's quite easily reusable, too.

 

Putting myself out there, and trying not to sound too dogmatic, I'll say the following:

 

- In my opinion, a regular DQMH module is not a state machine. Steve Watts gave a very interesting presentation on state machines at GDevCon #2, talking about many aspects and going into the details.

- Self-messaging is not a tool we use in our work (i.e. we don't allow it). It is much harder to read/follow, and Chris already mentioned potential problems with the missing atomicity and race conditions.

- In the majority of cases, a helper loop takes much less effort to create than it pays you back in terms of readability and stability.

 

From the bottom of my heart, I suggest you take another look at creating a proper state machine in a helper loop.

 

Also, feel free to use or copy our reference design. At the very least, you can make an informed decision to ignore it after giving it a brief glance. We're hosting the open-source repo containing our state machine template on GitLab: 
https://gitlab.com/hampel-soft/dqmh/hse-module-templates 

 




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® (Developer Experience that makes you smile )


0 Kudos
Message 4 of 6
(2,249 Views)

I'm not sure to get the right picture of the software architecture here, but I'm going to give my approach to this kind of situation.

This is obviously complementary to Joerg's reply. 🙂

 

I'd try to separate the autostart from the module that runs the test sequence:

  • 1 module for the test sequence with :
    • Start (request)
    • Obtain status (request and wait for reply) --> status: Idle, testing, on error
    • Status did Change (broadcast) --> status: Idle, testing, on error
  • 1 module to read Analog input
    • New Data (broadcast) --> Data acquired (waveform or array or map or whatever you are used to using to handle your data)
  • 1 module for managing the application
    • In the case of manual start, you use the start request when the user clicks the Start button. You can disable/enable the Start button with the status of the test sequence module.
    • In the case of an auto-start, the module listens to the data acquired in a helper loop and uses the Start request when ai > 4.5v, and handles the test rearm.

This approach gives you more modules, but 2 of them are simple and decoupled from the rest of the application.

There are also no differences for your test sequence module to be in auto-start or in manual, and you can reuse it in another application where the start is handled differently.

 

Does it make sense in your use case?

 

 

 

 

 

 


Olivier Jourdan

Wovalab founder | DQMH Consortium board member | LinkedIn

Stop writing your LabVIEW code documentation, use Antidoc!
Message 5 of 6
(2,233 Views)

I don't use DQMH myself, but I do have experience deciding on how to divide up a problem into "Modules", and I think you are not necessarily designing a simple/natural Module for your test "fixture".

 

Your fixture is something that is "Open" or "Closed", so the most natural and simple "Fixture" DQMH module would be one with a single Broadcast User Event called "fixture closed" true/false.  When the Fixture reports closed, then some other module (perhaps called "Test Executor") will decide what to do.  There is no need to complicate use of the Fixture Module by needing "Check" or "Test Started/Finished" messages.  And it needs no State beyond Open/Closed (possibly plus "Fault").

Message 6 of 6
(2,228 Views)