LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW OOP - Queued Message Handler

Solved!
Go to solution

Hi All,

I am developing an application for multiple cRIOs. I chose to use NI QMH architecture and all works well. To keep the base architecture common across all cRIOs, I attempted to make a class, then embed NI QMH to it.

So, I have following static dispatch methods: (1) Create Queue which initialises the queues for the two QMH loops. (2) Destroy Queues which releases the all the queues. (3) QMH 1 which is the primary module that receives messages from all QMH modules and distributes accordingly. e.g. if an error occurred in any of the module, QMH 1 receives that messages and it sends all QMH modules, the exit message. (4) QMH 2 which is a standard module responsible for handling another set of tasks. (5) Read Queue which is a VI for "data member access" that allows reading parent data at the child specific VIs.

I also have following dynamic dispatch methods with no functionality implemented: (1) Add Queues.

 

Then, I created a child of above class to implement specific features of each cRIO. I did an override on the Add Queue method and implemented another queue for QMH 3 which is only specific to the cRIO. I also created this child specific static dispatch method called QMH 3. Of cause, I couldn't unbundle the Queue reference in QMH3 in order to enqueue a message to QMH 1. That's where the Read queue (data for VI member access became handy) because it exposes the queue refnum, and I managed to wire into the enqueue element. 

 

So, up to this point my code has no errors and all seems logical. Then, I executed the VI and found that QMH 3 messages are not received at QMH1. Probing the wires showed "no refnum" which means although, I am not seeing an error, the queue refnum (in parent data) is not actually exposing the data at QMH3.

 

Probably I am doing something fundamentally wrong here. 

I would appreciate if someone can give me some tips. All I want is to access the Queue reference available in the parent class data, at a VI under the child class, thereby pass a message from child specific QMH3 to QMH1 implemented at the parent class.

 

Thanks in advance.   

0 Kudos
Message 1 of 8
(454 Views)

You haven't provided any code so all I can do is take a few stabs in the dark based on mistakes I have seen in the past:

  1. LabVIEW object wires are by value, not by reference
    avogadro5_0-1731356487600.png
  2. When you cast one class to another using "to more specific class" or "preserve runtime class," if the node errors the output value will be the default for the wire:
    avogadro5_1-1731356915963.png

     

Message 2 of 8
(412 Views)

Thanks for your reply.

The issue that I don't understand is that, unbundling of the parent data is not allowed in a VI under the child class - it gives a broken run arrow. But when I drop a VI for data member access in to the child class VI, the broken run arrow get fixed, but it doesn't function as expected.
Please see the project file attached.

Thanks again!

0 Kudos
Message 3 of 8
(393 Views)

@Asa77 wrote:

Thanks for your reply.

The issue that I don't understand is that, unbundling of the parent data is not allowed in a VI under the child class - it gives a broken run arrow. But when I drop a VI for data member access in to the child class VI, the broken run arrow get fixed, but it doesn't function as expected.
Please see the project file attached.

Thanks again!


I don't think all the files were saved correctly, however after digging a bit I believe what is happening is in "QMH 3.vi," you're passing an error into "Read Q.vi" which causes it to return the default value of the cluster instead of what's on the class wire:

avogadro5_0-1731373446480.png

Edit: unrelated since it's a pet peeve of mine, don't wire names to your queues just because you can, that turns them into effectively globals and means no one can trust the nice dataflow and encapsulation you put effort into using.

0 Kudos
Message 4 of 8
(377 Views)

yes... thanks for spotting that passing an error into it was the cause. But it still doesn't expose the parent data at the child VI. Let me rectify that issue and upload the files again. 

 

Also, thanks for the tip about naming the queues. I always wondered why such feature was available.

0 Kudos
Message 5 of 8
(328 Views)

@avogadro5 wrote:

@Asa77 wrote:

Thanks for your reply.

The issue that I don't understand is that, unbundling of the parent data is not allowed in a VI under the child class - it gives a broken run arrow. But when I drop a VI for data member access in to the child class VI, the broken run arrow get fixed, but it doesn't function as expected.
Please see the project file attached.

Thanks again!


I don't think all the files were saved correctly, however after digging a bit I believe what is happening is in "QMH 3.vi," you're passing an error into "Read Q.vi" which causes it to return the default value of the cluster instead of what's on the class wire:

avogadro5_0-1731373446480.png

Edit: unrelated since it's a pet peeve of mine, don't wire names to your queues just because you can, that turns them into effectively globals and means no one can trust the nice dataflow and encapsulation you put effort into using.


How does it "turn it into a global"?  I'm not sure what you mean.  I know it makes it somewhat difficult to use because you need to beware typos and duplicate names, but it still functions the same.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 6 of 8
(283 Views)

@billko wrote:

@avogadro5 wrote:

@Asa77 wrote:

Thanks for your reply.

The issue that I don't understand is that, unbundling of the parent data is not allowed in a VI under the child class - it gives a broken run arrow. But when I drop a VI for data member access in to the child class VI, the broken run arrow get fixed, but it doesn't function as expected.
Please see the project file attached.

Thanks again!


I don't think all the files were saved correctly, however after digging a bit I believe what is happening is in "QMH 3.vi," you're passing an error into "Read Q.vi" which causes it to return the default value of the cluster instead of what's on the class wire:

avogadro5_0-1731373446480.png

Edit: unrelated since it's a pet peeve of mine, don't wire names to your queues just because you can, that turns them into effectively globals and means no one can trust the nice dataflow and encapsulation you put effort into using.


How does it "turn it into a global"?  I'm not sure what you mean.  I know it makes it somewhat difficult to use because you need to beware typos and duplicate names, but it still functions the same.


A queue with no name can only be accessed via dataflow: if you follow the wire you can find everywhere the queue is used. A queue with a name can be accessed anywhere in the app instance. I call that a global.

0 Kudos
Message 7 of 8
(276 Views)
Solution
Accepted by topic author Asa77

I agree that naming the queue allows an undisciplined programmer to break the dataflow. However, I found it very useful when debugging. 
In fact, I manged to resolve my original question through some debugging. 

All I had to do: 
- create a data member access VI to with dynamic option, at the parent.

- Then, override that at child to read the parent queue.

- Also, overrise QMH1 at the child, so that it can include the child's queue. 

 

This works well and I have attached the project.

0 Kudos
Message 8 of 8
(241 Views)