DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

DQMH Broadcasting into Helper Loops

Solved!
Go to solution

Hi all,

 

I've recently started learning DQMH and have attempted to get started with a project involving valves. I have two modules so far, one to initialize the DAQ tasks and communicate with the valves, and one module to handle the configuration settings (read, edit and write to an .ini file). 

 

For the configuration settings module, this is my attempt:

 

1) I first send a request to launch the  process. I realise the "Initialize Module" in the Tester API is basically already launching the window and showing the front panel but I didn't want to change the code in the MHL so I created a Boolean named "Launch Window". Later this will be integrated together. It will call up an existing .ini file or create one and reads the data. A private request is then sent to wakeup the helper loop and data from the .ini file is broadcasted.

 

nikvl_0-1746199203662.png

 

2) Based on this article on helper loops, I tried loading the the helper loop, and "arm" it when the private request to "wakeup" the helper loop is triggered. However, I notice that the user event for the broadcasted data isn't registered properly and hence the data is not loaded into the helper loop at all.

 

nikvl_1-1746199802356.png

 

In the False case above, it is just the user event constant.

 

nikvl_2-1746200100312.png

 

When I use the Tester API, this is how it looks like and the data is broadcasted properly.

nikvl_3-1746200237716.png

 

In the Tester API, the Event is registered as "<ValveConfig Broadcast Events.Populate Config Menu>: User Event" while in the Helper Loop, it is "<Populate Config Menu>:User Event", so I believe this is the cause of the issue.

 

My questions are:

1) I read that we are not supposed to fork the event refnum, but can I copy the Register for Events node as I did here? My reasoning was so as to not change the DQMH labels

2) Under the Broadcasts in the module library, there is "Obtain Broadcast Events.vi". How does this differ from "Obtain Broadcast Events for Registration"? When do I use which one?

3) What is best practice to broadcast data from MHL to Helper loops?

4) On the module's front panel, there are additional buttons with functionalities such as "Add", "Remove", "Save" and "Cancel". Should I handle these booleans like normal events in the helper loop or should I create DQMH events for them as private requests? What is best practice?

 

I would greatly appreciate any help in the right direction before I continue. Thank you in advance!

0 Kudos
Message 1 of 5
(246 Views)

Hey nicvl,

 

I'm happy to hear that you've started looking into DQMH. For your questions at the end of your post, I can give a first set of answers. 

 


1) I read that we are not supposed to fork the event refnum, but can I copy the Register for Events node as I did here? My reasoning was so as to not change the DQMH labels

This is correct. You just have to make sure that you're renaming the label of the node. I know that the article uses DQMH_REG_HELPER, but today I would recommend removing the DQMH part from the label.

 

2) Under the Broadcasts in the module library, there is "Obtain Broadcast Events.vi". How does this differ from "Obtain Broadcast Events for Registration"? When do I use which one?


The "Obtain Broadcast Events for Registration.vi" is placed in the Public API folder, as this is the VI you're supposed to use outside the module - i.e. in any other module or VI that wants to register for the module's broadcasts. 

 

The "Obtain Broadcast Events.vi" is set to private and is a framework VI that you cannot use outside of the module. In fact, I cannot imagine a single use case where you would manually place this VI at all.

 

3) What is best practice to broadcast data from MHL to Helper loops?

There are a number of ways to transfer data from MHL to HL(s). Usually, one would not use a broadcast but a (private) request. Depending on the situation - and if you need to keep data between MHL and HL in sync - perhaps a local or global variable or any other construct might be a fitting solution, too.

 

4) On the module's front panel, there are additional buttons with functionalities such as "Add", "Remove", "Save" and "Cancel". Should I handle these booleans like normal events in the helper loop or should I create DQMH events for them as private requests? What is best practice?

If your module does not need the request, do not create it. There speaks nothing against having buttons on your module's front panel and using the ui events for handling them. 

 

For your application example, my assumption is that you want to use the Configuration module to be a generic reuse module that you can use with all sorts of DAQ modules. Hence the broadcast for sharing config data with multiple modules at once without creating a static dependency to any other module. By registering for the config broadcast in the DAQ module, you create a static dependency and now cannot use the DAQ module without the Configuration module anymore.

 

It would be helpful to learn more about your intentions: Is my description of your architecture correct? What is the purpose of the Helper Loop in the configuration module? 




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 )


Message 2 of 5
(202 Views)

Hi Joerg, 

 

thank you very much for your response!

 


@joerg.hampel wrote:

Hey nicvl,

 

I'm happy to hear that you've started looking into DQMH. For your questions at the end of your post, I can give a first set of answers. 

 

This is correct. You just have to make sure that you're renaming the label of the node. I know that the article uses DQMH_REG_HELPER, but today I would recommend removing the DQMH part from the label.

 

Do I rename only the node inside the case structure, or also the node outside the while loops (the one provided by the scripting tool) as well? Based on the article, I had assumed both nodes had to have the same name.

 

The "Obtain Broadcast Events for Registration.vi" is placed in the Public API folder, as this is the VI you're supposed to use outside the module - i.e. in any other module or VI that wants to register for the module's broadcasts. 

 

The "Obtain Broadcast Events.vi" is set to private and is a framework VI that you cannot use outside of the module. In fact, I cannot imagine a single use case where you would manually place this VI at all.


Okay, noted.

 

There are a number of ways to transfer data from MHL to HL(s). Usually, one would not use a broadcast but a (private) request. Depending on the situation - and if you need to keep data between MHL and HL in sync - perhaps a local or global variable or any other construct might be a fitting solution, too.

 

Ok, thank you. I believe I made it a broadcast in this case because I was not sure if I would need that data in a different module (more details below in the response to your follow-up question).

 



If your module does not need the request, do not create it. There speaks nothing against having buttons on your module's front panel and using the ui events for handling them. 

 

For your application example, my assumption is that you want to use the Configuration module to be a generic reuse module that you can use with all sorts of DAQ modules. Hence the broadcast for sharing config data with multiple modules at once without creating a static dependency to any other module. By registering for the config broadcast in the DAQ module, you create a static dependency and now cannot use the DAQ module without the Configuration module anymore.

 

It would be helpful to learn more about your intentions: Is my description of your architecture correct? What is the purpose of the Helper Loop in the configuration module? 


Ok, that makes sense regarding ui events. Regarding the architecture, I thought of having separate configuration modules for different functions, such as a configuration module for the acquisition sensors, and a configuration module for valves. And there would be a separate module (the user interface that one interacts with and serves as an overview of all the configurable settings) that could call and write into both modules. And yes, you're right, the configuration UI module would have dependency on other configuration modules.

 

Is that OK? Does this structure make sense? 

 

The "Register for the Broadcast" is in the Configuration module itself, not the calling DAQ module. And you're also right again, in this case, the helper loop isn't strictly necessary but I felt perhaps it was neater to not clog up the EHL with additional UI events from the booleans. Is that OK? Or is it better to handle everything in the EHL if it is not timing-dependent?

 

Coming back to my original problem, do you maybe know why the Event is registered as "<ValveConfig Broadcast Events.Populate Config Menu>: User Event" in the Tester API while in the Helper Loop, it is only listed as "<Populate Config Menu>:User Event"?

 

Is there a step that the scripting tool did for the tester API that I missed when creating the node for Broadcast Events for Registration in the helper loop? Is it due to the naming of the nodes? 

 

Thank you again for your answers and tips!

 

Best regards,

Nik

0 Kudos
Message 3 of 5
(187 Views)
Solution
Accepted by topic author nikvl

Do I rename only the node inside the case structure, or also the node outside the while loops (the one provided by the scripting tool) as well? Based on the article, I had assumed both nodes had to have the same name.


Actually, the labels have no impact at all on the event or event registration functionality. The only important thing is making sure that you do not duplicate existing labels starting with "DQMH_". This would break the DQMH scripting, as it relies on finding nodes on the block diagram via these labels. 

 

Personally, I would probably keep labels, but rename every single node to a unique name not starting with "DQMH_".

 


Ok, that makes sense regarding ui events. Regarding the architecture, I thought of having separate configuration modules for different functions, such as a configuration module for the acquisition sensors, and a configuration module for valves. And there would be a separate module (the user interface that one interacts with and serves as an overview of all the configurable settings) that could call and write into both modules. And yes, you're right, the configuration UI module would have dependency on other configuration modules.

 

Is that OK? Does this structure make sense? 


That sounds reasonable, but there are still questions: Would you ever want to use a DAQ/hardware module without the corresponding configuration module? Or will you always use them as a pair? And will you want to use the config modules without the UI module? Should the UI module be generic and independent of the actual config modules (i.e. no static linking to any specific config module)? These decisions will influence how you want to design your dependencies. 

 

Or is it better to handle everything in the EHL if it is not timing-dependent?

I would definitely add the UI events for buttons on the front panel to the EHL. I don't feel there's an advantage of separating them into a HL, generally speaking. 

 


Coming back to my original problem, do you maybe know why the Event is registered as "<ValveConfig Broadcast Events.Populate Config Menu>: User Event" in the Tester API while in the Helper Loop, it is only listed as "<Populate Config Menu>:User Event"?

 

Is there a step that the scripting tool did for the tester API that I missed when creating the node for Broadcast Events for Registration in the helper loop? Is it due to the naming of the nodes? 


The name of the event comes from the label of the cluster that is wired into the event registration node. Also, the name of the event really is irrelevant to its function. Put differently, no matter what you call your event, it will execute just the same.

 

I think your problem lies within the sequence of steps, and that you're assuming they are executed sequentially. I'm wondering if your code works if you put a pause (eg 500ms) between the private "wake up HL" request and the broadcast. 

 

Anyhow, I would recommend not using the broadcast but another private request to send data from the MHL to the HL - or perhaps just make the config data the payload of the "wake up HL" request?




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 5
(157 Views)

@joerg.hampel wrote:

Actually, the labels have no impact at all on the event or event registration functionality. The only important thing is making sure that you do not duplicate existing labels starting with "DQMH_". This would break the DQMH scripting, as it relies on finding nodes on the block diagram via these labels. 

 

Personally, I would probably keep labels, but rename every single node to a unique name not starting with "DQMH_".

 

That sounds reasonable, but there are still questions: Would you ever want to use a DAQ/hardware module without the corresponding configuration module? Or will you always use them as a pair? And will you want to use the config modules without the UI module? Should the UI module be generic and independent of the actual config modules (i.e. no static linking to any specific config module)? These decisions will influence how you want to design your dependencies. 


I would definitely add the UI events for buttons on the front panel to the EHL. I don't feel there's an advantage of separating them into a HL, generally speaking. 


Thank you for your helpful insights and tips. They have helped me reflect on what I'm trying to achieve and go back to the drawing board.

 

 

 

I think your problem lies within the sequence of steps, and that you're assuming they are executed sequentially. I'm wondering if your code works if you put a pause (eg 500ms) between the private "wake up HL" request and the broadcast. 

 

Anyhow, I would recommend not using the broadcast but another private request to send data from the MHL to the HL - or perhaps just make the config data the payload of the "wake up HL" request?


I reworked the module and removed the broadcast and used another private request as per your recommendation and it now works as expected. DQMH has been an interesting learning experience. Thanks again!

0 Kudos
Message 5 of 5
(140 Views)