11-11-2024 08:50 AM
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.
Solved! Go to Solution.
11-11-2024 02:29 PM
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:
11-11-2024 05:27 PM
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!
11-11-2024 07:04 PM - edited 11-11-2024 07:07 PM
@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:
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.
11-12-2024 09:53 AM
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.
11-14-2024 02:52 PM
@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:
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.
11-14-2024 03:01 PM
@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:
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.
11-15-2024 06:01 AM
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.