LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DQMH: register for event in one module before start in another module

Solved!
Go to solution

Hi everyone,

 

So I have a DQMH project with three modules (well... in the real project, I have more, but three will be enough to explain my problem):

- Controler: cental unit of the application, that processes data for example...

- Hardware: controls connection with hardware, configure it, reads data...

- TCP: manages connection with other applications that want to communicate with my application.

 

Immediately after it initialises, the Hardware module broadcasts some values read from the different devices. This basically gives us information about the hardware status when the application starts. I want this information to be available in the Controler of course, but also in the TCP module so that I can sent it to other applications.

 

One solution is to have the Controler module catch the broadcast from the Hardware module, and save the "init status" locally in the Controler. And then for example have the TCP module ask the Controler to send the data. That would work, yes. And the advantage here is also that the Controler acts as a "central unit", and as a reference for what is to consider as valid initiale data.

 

But then, I thouhgt... In the TCP module, I could also use the node Register For Events and register the Hardware module. That way, the TCP module can also catch the broadcast event that the Hardware module generates at initialisation, and immediately has the information, without asking the Controler for update. And here is my problem. I can't make this to work!

 

One important information to take into account: all modules have to be started from the Controler. I cannot, for example start the Hardware module in the TCP module. That will not work in my application, because there are several other modules to start, and they follow a global initialisation sequence that is managed by the Controler.

 

So, how can I do this?

- Start the Controler (manually)

- Make the Controler start the TCP module first

- When TCP "did init", have the Controler start the Hardware module

- Have the Controler AND the TCP module see the broadcast event generated by the Hardware module at initialisation

 

The three first points are done. It works. But I cannot find a way to make the last point work. Only the Controler sees the event form the Hardware module. The TCP module does not see any broadcast.

 

I prepared a little project, as an example (Saved in LV2016. But code is available in LV2020 if needed. Just ask.)

In the TCP module, I did register for events from the Hardware module, thinking that would be enough to catch broadcast events. But if I start the TCP module before the Hardware module, it seems this registration is useless (or at best not enough). The TCP module does not see anything.

And of course, I cannot start the Hardware module before the TCP module. Because then, since TCP is not running when Hardware generates the broadcast events, then TCP will not see anything either...

 

LucG_1-1648914892162.png

 

 

Please test the project to see what happens.

 

Any suggestions...?  (if that is even feasible...)

 

Thanks for your help.

Luc

0 Kudos
Message 1 of 6
(1,480 Views)

Hello,

 

Any solution on this? I'm experiencing the same issue.

0 Kudos
Message 2 of 6
(1,028 Views)
Solution
Accepted by topic author LucG

@LucG:

DQMH has the drawback of only creating the user events when starting the module. So at the initialization of the TCP module (the screenshot you have attached), since the HW module has not been started yet, all you do is specifying the type of the broadcasts, but not actually registering them (because the references are invalid):

raphschru_1-1693396266730.png

 

 

On the contrary, in the Controller module, you are correctly registering HW broadcasts because you use the events coming from the "Start Module" VI. Here you can be sure the events were created:

raphschru_0-1693396228899.png

 

 

So you have 3 options:

 

1. Only the caller module (Controller) listens to the broadcasts of its submodules (like you had initially)

 

2. Start HW first, to ensure the events are valid, then TCP. You may miss the initial events, but at least you correctly register for later HW broadcasts:

raphschru_2-1693398257306.png

 

3. You could theoretically send a request-reply to the TCP module right between the HW Start Module and the HW Synchronize Module Events to order the TCP to register to the HW events (now that you know they are valid), but that feels a bit like hacking the DQMH pattern. In my opinion, only the caller module (here Controller) should listen to the initial events (like "Did Init" or any other broadcast sent at initialization) of a "submodule" (here HW):

 

raphschru_3-1693399332691.png

 

Find attached modified projects for option 2 and 3.

 

 

@IPach:

If you have a different situation, you can also start a new topic, and in the appropriate forum .

 

 

Regards,

Raphaël.

0 Kudos
Message 3 of 6
(1,010 Views)

If the Controller module manages the initialization for several modules including the Hardware module, it should be able to trigger the initialization in the hardware module only after the TCP module has registered for its broadcasts.

 

  1. Controller launches/starts Hardware
  2. Upon Hardware:Did Init, Controller launches TCP
  3. Upon TCP:Did Init, Controller triggers (requests) Hardware initialization

 

Inside TCP, you register for Hardware broadcasts just like you have shown. The registration should succeed because we made sure the Hardware module was started by waiting for its "Did Init" broadcast.

 

Message 4 of 6
(993 Views)

Hi,

Nice dilemma 🙂

 

IMO, since you have a controller I would use it to handle this situation !

You can start the HW module and use a helper loop to capture its broadcasts for example.

You can the bufferise the data (in a queue for example) until the TCP module is ready to handle requests.

You can then dequeue the data in the buffer to send requests to the TCP module (could be done also in a helper loop).

This is an example.

 

Another way to handle the situation is to launch both the HW module and TCP module.

Wait for both 'Did Init' broadcast in the controller, and send a specific request to the HW module to tell the controller is ready to receive data points.

At this point any broadcast received by the controller can be pushed back to the TCP module.

 

In any case I would leverage the controller instead of having the HW module speaking to the TCP module.

It would avoid coupling the modules together and allow you to use the controller to modify the data produced by the HW modules (if needs be) before treating it into the TCP module.

 

Reading your use case makes me wonder :

Why do you need that be that 'speedy' capturing the HW data that you can't wait for the TCP module to be started ?

It is usually fast (if the module is lightweight) to start a module. You may miss some points of course, but if these points are important I guess that starting the HW module way sooner would be valuable. And bufferize them is mandatory.

Otherwise, simply accept to loose some data points to ensure proper sync of the modules using the controller as a gateway.

 

My 2 cents.

CLA, CTA, LV Champion
View Cyril Gambini's profile on LinkedIn
This post is made under CC BY 4.0 DEED licensing
Message 5 of 6
(973 Views)

Hi all,

 

Thank you very much for your feedback.

 

I will mark the answer from raphschru as answer, as it is a more direct answer to my question (basically stating that what I want to do is not possible as is).

 

I like the approach of Photon_Dan. I didn’t think about decoupling the Labview code from the actual hardware. Starting the HW module first (as in just the code), and delaying the start of the hardware (as in the actual machinery) is a nice trick. It is kind of obvious once someone says it to you. But that did not come to my mind at that time. I was too blindfolded by the idea that when the HW module starts, then the actual “hardware” should also be triggered.

 

The idea from CyGa to buffer the init data and transmit them later is also nice. That way, the data can also be processed and logged for further analysis.

 

What I implemented in the end is what CyGa suggested: use the Controller for what it is; a central unit. All modules are started from the Controller. When new data come from the hardware, the Controller catches them and sends them to TCP.

 

As of your question, CyGa, regarding why such a “speedy” capturing of HW Data: It was just for the beauty of the art, I must say. In practice, yes, I can wait for two seconds for all modules to initialize, and the get the data from the hardware, whether they are actual (buffered) init data, or some fresh data accepting some loss at init. I simply had this particular pattern in mind, and I wanted to ask the community if there was a solution.

Thank you all for your contributions.

Have a nice day.

Luc

0 Kudos
Message 6 of 6
(940 Views)