DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Fundamental Understanding of interaction of DQMH and TestStand

Hello everyone,

 

first and foremost: Thanks DELACOR for your DQMH and all the effort, especialy documentation-wise !

Made "understand the framework" a lot easier,.....but.....

 

I'm intending to use DQMH with TestStand as an abstraction layer / device daemon for test systems, and I would like some feedback if my ideas are somewhere on the right track..I'm a little confused, since there were some changes leading up to my version (DQMH V4.1.0.42), that left me a little "mixed up"....

 

My idea is as follows:

Start several DQMH modules from a LabVIEW application (might be deployed, might be dev env), which mainly control several pieces of test equipment. Prominent example: heating chamber, since that runs independently of TestStand (starts ahead of time to heat up, etc.). Similarly, I would like to maybe add an abstraction layer (including simulation), so I can switch out power supplies in the DQMH and not in TestStand. Mainly, because I don't like handling references to hardware in TestStand (might be due to lack of understanding how to do it properly, any tipps here?). Extending on this, if using DAQmx and continuous or triggered acquisition, I believe that I would be writing a lot of VIs that in itself open, read from and close a DAQmx task to avoid errors with DAQmx (wrong?) instead of having a DQMH module reading data and providing visual feedback on a graph, separate from TestStand and providing a sample (triggered recording of fixed length for example on demand to TestStand).
Another example that seems quite helpful to me would be a RS232 abstraction layer, that allows me to listen in and inject commands, without having to restart the TestStand sequence by separating the commands sent from TestStand and actually sending them to the device. Might even allow for "fixing" a device without restarting TestStand sequence. Another example is a sensor, that has no display, but provides measurements vis RS232 on request. I would like to see those measurements, even when the TestStand sequence doesn't need it at that moment.

 

Due to its details regarding TestStand I looked at the heating chamber example, but I don't understand some points behind the design of this example:

- Why would you start a heating chamber from TestStand? (see above, and also removes the need for the DQMH module "Test Stand Manager", if I'm not mistaken)

- Why would you trigger a broadcast event with a request that in itself already has a reply? I understand that the round-trip event event is useful in several cases (as described by the feature request author), but in this case? Or is it a relict from when this example was created? The only reason in this case I came up with, is that the API Tester seems the Request and Reply calls from TestStand.. (And one other remark regarding the API tester in this example: The x axis labeled "time" is misleading. It's rather "number of received messages")

 

Given all that, I was wondering if the following approach is recommended with current DQMH version 4.1.:

1. Start singleton modules separate from TestStand (Deployed or DevEnv)

2. Have TestStand access these singleton modules solely via API calls that do not start / stop module (Can I block those?) purely by Request-and-Reply messages (since broadcast events are not useful in this case) [Is the reply to a request distributed via the same notifier as the broadcast if the event is configured as Round-Trip? Idea: have the separate LabVIEW app listen to broadcast events only and not see TestStand communication, while TestStand does not see broadcast events]

3. Have clonable UUT-coupled modules being started from TestStand (being able to monitor those in the LabVIEW app as well: number running, etc.) and have TestStand handle their live-span. An example would be the interface to a UUT, which is a DQMH module in itself (where different communication methods can be handled independent of TestStand sequence) and the communication is monitored in that module. If problem occurs, TestStand can pause and have user fix / investigate communication problem and try again when instructed so. This seems very elegant, since after opening the block diagram of that UUT, it can be used for debugging including probes, etc. (as mentioned by https://delacor.com/peek-a-boo-using-your-api-tester-to-interact-with-a-running-dqmh-module/)

4. Have TestStand look for errors with the singleton modules (as discussed in the forum, this might be something that can be handled in a parallel thread in TestStand)

5. Above described approach for singleton modules might as well be used for clonable modules if useful

6. Maybe add a layer on top, which supervises the whole operation including preparing the chamber, heat up, etc. and, when ready, starts the TestStand sequence and handles replacing the UUT (robot-arm style) after successful completion of test (or is this something better handled in TestStand?)

 

Sorry for the long post and thanks for any feedback / comments !!

 

Cheers

Niels Göran

0 Kudos
Message 1 of 4
(4,663 Views)

Hi Niels,

 

Thanks for your compliment and for taking the time to contact us. 

 

I will try to answer all your questions. Before I go into the details, let me explain how we see the use of TestStand and DQMH and what were the things we were aiming for. 

 

  • This is an oversimplification: TestStand is great for sequencing and determining pass/fail. LabVIEW is great for programming. --> DQMH focuses on leaving all the programming aspects in LabVIEW and having TestStand just call the DQMH public requests. The DQMH Module owns its own references, including not only the references to its events but also the references to any device started directly in the DQMH. This facilitates the integration with TestStand, with no need to pass objects, references, state data or communication references between steps.
  • Debugging LabVIEW code directly in TestStand can be a headache. We wanted to facilitate debugging directly in LabVIEW. --> The DQMH API Tester excels at this and you can use them as sniffers as long as the API Tester is running in the Main Application instance (TestStand runs in the main application instance when its adapter is set to be the LabVIEW dev environment). 
    • Although we could use different threads to register for the broadcasts, we wanted to keep things simple in TestStand and only use synchronous communication between LabVIEW and TestStand. However, if we want to use the API Tester as a sniffer, we do need to have a broadcast as well as the request and wait for reply, otherwise, the API tester would not be able to sniff all the request and wait for replies sent from TestStand. 

Now to your questions


@ngblume wrote:

 

I'm a little confused, since there were some changes leading up to my version (DQMH V4.1.0.42), that left me a little "mixed up"....

 


Please let us know what made 4.1 confusing, we were aiming at improving the integration with TestStand not to making things more confusing. 

 


@ngblume wrote:

 

Start several DQMH modules from a LabVIEW application (might be deployed, might be dev env), which mainly control several pieces of test equipment. Prominent example: heating chamber, since that runs independently of TestStand (starts ahead of time to heat up, etc.).


If LabVIEW code and TestStand code are running in the same application instance, you can start singleton modules wherever you want and as many times as you want. When you call the Start Module.vi for a VI that is already running, it simply just establishes communication with the same singleton. For cloneable, you would have to figure out how to pass the Module IDs from TestStand and you could communicate with your cloneable from TestStand. Starting the module in TestStand can guarantee that the module is running. If for whatever reason the heating chamber was not already running, the TestStand sequence can call its start module and make sure it is up and running.

 


@ngblume wrote:

Similarly, I would like to maybe add an abstraction layer (including simulation), so I can switch out power supplies in the DQMH and not in TestStand. Mainly, because I don't like handling references to hardware in TestStand (might be due to lack of understanding how to do it properly, any tipps here?).


"Mainly because I don't like handling references to hardware in TestStand" This is exactly why you would be using a DQMH module to wrap your hardware. The DQMH module owns the reference to the hardware, all TestStand is doing is calling the "Switch Power ON" request and the DQMH already has the reference to the power supply. You might want to check out this blog post on Hardware Abstraction Layers and DQMH. (I know it is a little outdated and we do have it on our evergrowing to-do list to write an update).

 


@ngblume wrote:

Extending on this, if using DAQmx and continuous or triggered acquisition, I believe that I would be writing a lot of VIs that in itself open, read from and close a DAQmx task to avoid errors with DAQmx (wrong?) instead of having a DQMH module reading data and providing visual feedback on a graph, separate from TestStand and providing a sample (triggered recording of fixed length for example on demand to TestStand).


You are on the right track, for the DAQmx DQMH modules, I recommend reading up on helper loops. You can have your DQMH module running showing its front panel all the time and displaying a graph. Then have TestStand fire up a request that tells the DQMH to provide whatever sample it needs.

 


@ngblume wrote:

Another example that seems quite helpful to me would be a RS232 abstraction layer, that allows me to listen in and inject commands, without having to restart the TestStand sequence by separating the commands sent from TestStand and actually sending them to the device. Might even allow for "fixing" a device without restarting TestStand sequence. Another example is a sensor, that has no display, but provides measurements vis RS232 on request. I would like to see those measurements, even when the TestStand sequence doesn't need it at that moment.

 


Once a DQMH Module is running, you can call its Show Panel from wherever you want, it can be from TestStand or from the LabVIEW code to show what is going on independent of the TestStand sequence. Just as before, the TestStand Sequence might call the Start Module and Synchronize Module events just to ensure that the module is indeed running already.

 


@ngblume wrote:

Due to its details regarding TestStand I looked at the heating chamber example, but I don't understand some points behind the design of this example:

- Why would you start a heating chamber from TestStand? (see above, and also removes the need for the DQMH module "Test Stand Manager", if I'm not mistaken)

 


TestStand needs to start the DQMH module to guarantee that the DQMH module is already running so TestStand can communicate with it by firing requests, otherwise, there is no way for TestStand to know if there was another application already running the module. The key here again is for TestStand and the DQMH module to be running on the same application instance.


@ngblume wrote:

 

- Why would you trigger a broadcast event with a request that in itself already has a reply? I understand that the round-trip event event is useful in several cases (as described by the feature request author), but in this case? Or is it a relict from when this example was created? The only reason in this case I came up with, is that the API Tester seems the Request and Reply calls from TestStand.


Because the request and wait for reply might be fired by TestStand but you might have other modules registered for the broadcast of that DQMH modules and they would have no way of knowing that TestStand made that request. The best example for this is the DQMH API Tester running as a sniffer. If there were no broadcasts within the "request and wait for reply" the DQMH API Tester would not be sniffing everything. However this could apply to all sorts of other modules, perhaps you have a different monitor module that is registered for a specific broadcast and it would benefit from getting the latest value when another module calls the Request and Wait for Reply.

 


@ngblume wrote:

one other remark regarding the API tester in this example: The x axis labeled "time" is misleading. It's rather "number of received messages")

 


This is a left over from the default label in graphs in LabVIEW. I looked on the idea exchange to see if somebody had already suggested putting graphs and charts with X and Y for the label as opposed to Time and Amplitude, that way if we forget to change the label, it still always makes sense. We have filed case DQMH-547 for us to fix this in the next DQMH release. Thanks for bringing it up.


@ngblume wrote:

 

1. Start singleton modules separate from TestStand (Deployed or DevEnv)

Yes, this is OK as long as you start them as well in TestStand to guarantee that they are indeed already running. You do need to make sure that your TestStand code and your LabVIEW code are running on the same application instance.

 


@ngblume wrote:

2. Have TestStand access these singleton modules solely via API calls that do not start / stop module (Can I block those?) purely by Request-and-Reply messages 

 


You can eliminate calling the stop module, but I would not remove the start module. TestStand needs to guarantee that the module is indeed already running. Furthermore, what you could do is store somewhere whether the Start Module.vi reported if the module was already running (there is an ouptut for this) and if it was already running then do not call the stop module, but if it was not already running when TestStand called it then do call the stop module.

 


@ngblume wrote:

 

2. ... (since broadcast events are not useful in this case) [Is the reply to a request distributed via the same notifier as the broadcast if the event is configured as Round-Trip? Idea: have the separate LabVIEW app listen to broadcast events only and not see TestStand communication, while TestStand does not see broadcast events]

 


Broadcast events are very useful during troubleshooting and debugging. Implement your application and come back and let us know if we were wrong suggesting to have a broadcast for every request and wait for reply. My hunch is it will come a time where you are troubleshooting a bug and you will be thankful that the DQMH API Tester was registered for those broadcasts.

 


@ngblume wrote:

 

3. Have clonable UUT-coupled modules being started from TestStand (being able to monitor those in the LabVIEW app as well: number running, etc.) and have TestStand handle their live-span. An example would be the interface to a UUT, which is a DQMH module in itself (where different communication methods can be handled independent of TestStand sequence) and the communication is monitored in that module. If problem occurs, TestStand can pause and have user fix / investigate communication problem and try again when instructed so. This seems very elegant, since after opening the block diagram of that UUT, it can be used for debugging including probes, etc. (as mentioned by https://delacor.com/peek-a-boo-using-your-api-tester-to-interact-with-a-running-dqmh-module/)


You got it!


@ngblume wrote:

 

 

Sorry for the long post and thanks for any feedback / comments !!

 


Sorry for the long response 😉 

 

Thanks for your feedback and comments, I hope this is useful and please do not hesitate to come back with more questions, comments, feedback and of course, let us know how things progress as you implement your application.

 

Happy wiring,

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 2 of 4
(4,632 Views)

In addition to what Fabiola has said it might be helpful to look at this article: http://www.ni.com/product-documentation/14335/en/

 

She referenced several time the importance of LV and TS being in the same app space.  This document defines how and when to do that. 

 

To Fabiola's point the nice thing about DQMH is that you can call them from either LV or TS as long as the app space is the same and the instr refs will be encapsulated in your module.  The hard part of this is trying to develop because you have to keep switching back and forth between run-time and dev environment for your LV adapter.  However, if you package up your DQMH modules into PPLs (packed project libraries) then you can develop in TS with the adapter set to run-time and just call the PPLs. 

 

Hope this helps,

jigg
CTA, CLA
testeract.com
~Will work for kudos and/or BBQ~
Message 3 of 4
(4,626 Views)

Hello Fab and jigg,

 

thank you for your replies !

They helped quite a bit, but some things need a little more unwinding in my head....

 


@FabiolaDelaCueva wrote:

I will try to answer all your questions. Before I go into the details, let me explain how we see the use of TestStand and DQMH and what were the things we were aiming for. .....

This is exactly the idea I had in mind.. One again, DELACOR (mostly) implemented already for me, what I had in my mind !

 


@FabiolaDelaCueva wrote:

Please let us know what made 4.1 confusing, we were aiming at improving the integration with TestStand not to making things more confusing. 

My issues is not something very specific, but the examples I looked at most (heating chamber with TestStand) sometimes did things differently than in later videos (why I assumed that it is due to newer versions). Not quite sure, if the way roundtrip events are implemented now than before threw me off a little. If I find something more specific, I will let you know.

 


http://delacor.com/documentation/dqmh-html/CreatingaNewDQMHEvent.html:

Round Trip: A request and wait for reply event and a broadcast event where the Reply Payload and the Broadcast Argument are the same typedef. The request and wait for reply event has an input to determine wether the code should wait or not for the reply. In the case where the code doesn't wait for the reply, these events are asynchronous but may be logically related (i.e., Do Something and Did Something). In the case where the code does wait for the reply, the broadcast provides the opportunity of notifying other VIs, registered to listen to the broadcast, when another VI has called the request and is waiting for a reply. This is particularly useful in TestStand projects where the TestStand step needs to wait for the reply and we might want to use the API Tester as a sniffer and still see the reply reported there via the broadcast event.

 

Note that DQMH versions before 4.1, created the Round Trip differently, in those versions the Round trip was a combination of a request and a broadcast where both events shared the same argument typedef. Based on feedback from the DQMH community and Dealcor team's own experience, we decided to change the round trip to be now the combination of a request and wait for reply and a broadcast.

This note might be part of my problem: I see your points for also sending out broadcast messages, but I find it sometimes irritating when you only register for a reguarly occuring broadcast, but then every once in a while, you see different times between received events (because some other module send a "Request and Wait for Reply" in between. Since I'm not fully aware of the framework, that might be just my understanding right now.

 


@FabiolaDelaCueva wrote:

"Mainly because I don't like handling references to hardware in TestStand" This is exactly why you would be using a DQMH module to wrap your hardware. The DQMH module owns the reference to the hardware, all TestStand is doing is calling the "Switch Power ON" request and the DQMH already has the reference to the power supply. You might want to check out this blog post on Hardware Abstraction Layers and DQMH. (I know it is a little outdated and we do have it on our evergrowing to-do list to write an update).

I looked at that post as well and got some ideas from it. As I said before, the slight differences between current and older versions might have thrown me off. But keeping everything updated is not a viable options (alternative: highlight that this is for an older version, and some details have been changed).

 


@FabiolaDelaCueva wrote:

"You are on the right track, for the DAQmx DQMH modules, I recommend reading up on helper loops. You can have your DQMH module running showing its front panel all the time and displaying a graph. Then have TestStand fire up a request that tells the DQMH to provide whatever sample it needs.

Also looking at helper loops as well. They appear to be what parallel loops are in actor cores.

 


@FabiolaDelaCueva wrote:

"TestStand needs to start the DQMH module to guarantee that the DQMH module is already running so TestStand can communicate with it by firing requests, otherwise, there is no way for TestStand to know if there was another application already running the module. The key here again is for TestStand and the DQMH module to be running on the same application instance.

I think that responsability should lie with the user powering up the system or restarting it (comparable to switching on devices in the real world). Having someone start the TestStand sequence and my heating chamber fires up is giving me nightmares. But I see your point to check if the module is running. Is there another way to check if a module is running from TestStand ? And reporting an error if not, instead of starting it...

 


@FabiolaDelaCueva wrote:

"This is a left over from the default label in graphs in LabVIEW. I looked on the idea exchange to see if somebody had already suggested putting graphs and charts with X and Y for the label as opposed to Time and Amplitude, that way if we forget to change the label, it still always makes sense. We have filed case DQMH-547 for us to fix this in the next DQMH release. Thanks for bringing it up.

Given that this axis might be time, wouldn't it be even more helpful to just change this to a chart and have it place the data points according to the time they were sent/received via the event structure?

 

What I most unclear about after this is the application instances (and here jigg's comments come into play):

Our current setup uses PPLs on the TestStand computers with LV runtimes.

I also read the article mentioned by jigg (http://www.ni.com/product-documentation/14335/en/) before hand, but was a little left in the dark, since there are no specific mentions to PPLs.

 


http://www.ni.com/product-documentation/14335/en/:

"By default, all VIs are called in the main application instance of the LabVIEW Run-Time Engine module loaded by the TestStand process*.  You can optionally select a LabVIEW project in the module tab in addition to selecting a VI.  In this case, the VI will execute within the application instance of the the "My Computer" target selected project in the TestStand process.

If steps are configured to use different LabVIEW runtime engine versions, a Main application instance is created for each LabVIEW Run-TIme Engine version used.

If I understand correctly, the way to go would be as follows:

  1. Develop the LabVIEW app with DQMH modules and some libraries for the hardware interface
  2. Put the DQMH modules (including the libs they call) in a PPL and replace the libraries in the LabVIEW app with the PPL
  3. Build the labVIEW app as stand-alone for deployment to the test systems

That way the LabVIEW stand-alone app calls the modules from the specific PPL (which puts them in the PPL application instance ?) and from the stand-alone app for example I can have a button start the API tester from the same PPL (therefore in same applicaiton instance?) and interact with those models. Using the LabVIWE project is not an option, since only run-time is available on the TestStand computers (no dev, no project to start individual VIs). TestStand also calls the API functions from that PPL and therefore operates in the same application instance.

 

What happens if you use the same PPL, but saved at different locations or in different versions?
Would that change the behavior and therefore be something to watch out for?

 

Thanks and sorry once more for long question lists!

Cheers

Niels Göran

 

P.S.: Given that this does not easily work over network, I assume wrapping the API in another API with messaging like ZMQ (http://labview-zmq.sourceforge.net/) would clear up the application instance issue and make the whole system network-ready? Defeats the eavesdropping via API-Tester from a project in the DevEnv but might be an option to call the API Testers from a menu of the deployed LabVIEW app...

0 Kudos
Message 4 of 4
(4,617 Views)