From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
10-09-2019 03:27 PM
Hi folks,
A few months ago, I received some fantastic advice on how to modularize a large VI with many front panel items across several tabs. Having modularized much of the VI's architecture and implemented a loose actor framework, I'm now struggling to make the block diagram more manageable. When I look at some of the architecture (snippets attached), I can't help but feel that there must be a better way. I know there's no way I can fit everything on one screen with the current architecture, which currently spans 16 screens. Prominent examples that look wrong to me include:
I have read about some creative ideas in other forum posts, but want to make sure that my approach and understanding are sound before I go about applying them willy-nilly.
If there are other ways to simplify the block diagram, to improve either readability or functionality, I would love to hear it. Y'all are always super helpful and I appreciate your advice.
Thanks!
Solved! Go to Solution.
10-09-2019 04:20 PM
Your screen shots don't look bad to me.
One comment I do have regarding your cluster of arrays of queues. I've done a cluster of queue references so that I can send the references into different "modules" in a VI. Make that cluster a typedef! Otherwise later on you'll add another queue, or perhaps change a datatype in one of those existing queues and you'll find your wires break all over the places because the controls and indicators of that cluster will no longer be the correct type.
In general, any time I have a cluster or an enum, those items become a type definition.
10-09-2019 04:32 PM
@charleslu wrote:
- Passing a cluster of arrays of queues to a subVI. The subVI reads multiple data streams from an instrument and then parses it out to each queue. Arrays of queues in different cluster elements receive different data (in the same format). Queues in the same array (assigned to a cluster element) receive the same data (for different uses). Is there a less ugly way to do this?
I got tired of doing this and moved away from queues and queued message handlers. Queues are great, but sometimes can feel like one way streets. I haven't used Channel wires, but I believe they have cases of 1-to-N communications, that way you can send the same data to multiple places. I use User Events, coupled with JKI State Machines, to communicate across modules. I use something similar to this and this. This allows me to have "one" wire to pass messages around various modules.
@charleslu wrote:
I have all my indicators in a "single" loop that is called whenever a value needs to be updated. Never had a problem with this. The only exception I normally use, if I have a "busy" indicator, ie, a spinning beach ball. I usually have that in its own loop in order to have a smooth updates.
mcduff
10-09-2019 04:44 PM
If this is the kind of stuff you are fretting over now, I'd say you tamed the beast very well!
10-10-2019 02:33 PM
Thanks everyone for the helpful replies. These are good tips and I'm glad to hear that things seem to be headed in the right direction, albeit a bit disappointed that maybe not all VIs can look as nice as the examples I see in tutorials.
mcduff, can you tell me a bit more about how you update multiple asynchronous indicators in a single loop? I'm not aware of an elegant way to implement that.
Thanks!
10-10-2019 03:04 PM
@charleslu wrote:
Thanks everyone for the helpful replies. These are good tips and I'm glad to hear that things seem to be headed in the right direction, albeit a bit disappointed that maybe not all VIs can look as nice as the examples I see in tutorials.
mcduff, can you tell me a bit more about how you update multiple asynchronous indicators in a single loop? I'm not aware of an elegant way to implement that.
Thanks!
I operate under the assumption that it does not matter if all my indicators update exactly at the same time. In fact some indicators may update more frequently than others. However, updates greater than a 20-30Hz rate are usually not necessary for anything except video.
Below is a front panel that only has 3 indicators that need constant updating.
Plot, table, and progress bar all need to be updated.
Loop receives User Events which carry the update, the user event also includes a "state", that is, which indicator should be updated.
Table is updated here in this state
Progress bar updated here in this state
Plot updated here in this state
The progress bar is updated every 100ms, the table and plot updates are user dependent, that is, they depend on the acquisition settings. No reason to try and update everything at exactly the same time.
All of the pictures above are from 1 loop, for me, it is my indicator loop. I send all my messages to update the indicators to that loop and it takes care of them.
The block diagram for the front panel I showed earlier. Top loop handles all User Interactions (Menu clicks, resizing, button pushes, etc and sends appropriate messages to different loops, none of the "real" processing is handled in that loop), bottom loop updates indicators. The loops on the left hand side handle instrument, data, UI, and watchdog functions. For example the data loop may perform a FFT on the acquired data and when complete messages the indicator loop to update the plot. The watchdog may watch when the main window is minimized and then tell the data loop to stop processing data for display since the user cannot see it.
With one user event wire I am able to communicate to any loop that it connected to that wire, that is what you see in the block diagram.
mcduff