06-13-2025 01:35 AM
I have a Test Equipment that was delivered in 2019 . Hardware used is 2x PCI6229 cards + 1xPCI6514 card running in a WIN11 PC. It was recently ported from LV2017 to 2024.
Structure is simple with a Main.VI acquiring all I/Os , averaging them ; and writing back to DOs and AOs ; This Main.VI is the primary UI.
As the number of Auto sequences were very large , we coded each of the sequence as a separate VI. So each of the Auto sequence thats required will be loaded as a sub panel inside the Main.VI. IO data exchange between the Main VI and subPanel VI is via Functional Globals.
The Main and SubPanel VIs have While loops running at 25ms initially but had to later increase to 50ms as we added more functionality. Also right from start we have been using two 31" monitors - first monitor is for User Interaction to choose the sequence and then start the sequence. It shows the plot of some three or four channels. The second monitor shows all the analog gauges and digital input status.
Now we have reached a stage that even the 50ms loops finish late mostly ( I have an LED showing the Finished Late status - instead of occasionally coming ON, its now ON mostly ) But even now the test stand is quite functional 24/7 .
So planning to upgrade the hardware to cRIO [ or ] PXI . Even now I dont think I need an RTOS, and also it will be a major upgrade. I will be glad to get a consistent execution with 5ms loop time with a Windows based system.
The question is how does one find out which is the one that is occupying the CPU the most - is it the display refresh as there are two monitors and one of them shows more than one plot ? Or is it that the I/O count is large and the PCI bus struggles to keep track ??
Any pointers will help.
06-13-2025 10:17 AM
Without seeing anything, can mostly guess.
06-13-2025 10:18 AM
Because LabVIEW is an inherently parallel programming language, it should be possible to acquire data at a fairly high data rate (say 1 to 100 kHz), much faster than one can "look at it" (more like 30-50 Hz) but certainly in the range of "streaming to disk" (for off-line examination using manual scrolling or playback at a slowed-down rate). What you need to do is to have one task that acquires the data and "ships it out" to a second, parallel task that streams it to disk and maybe streams a much-decimated version of the data to a third "show me the data" task.
Have you heard about the Producer/Consumer Design Pattern (a template of which can be found by opening LabVIEW and clicking "New ..." (those dots are important) on the File menu and poking around)?
Attach your VI (please use Save for Previous Version, and specify LabVIEW 2019 or 2021, which seem to be the most-requested) and we'll take a look.
Bob Schor
06-14-2025 02:00 AM
I know without seeing anything its difficult to say whats wrong. .
But I liked your bullet points that serve as a good starting point to revisit the code ( it is anyway 5 years old !)
Will carryout a reality check and revert back here...
Thanks
06-14-2025 02:08 AM
Sorry to just ask for help without sharing a VI .... each VI is quite large and needs lots of third party software to even open without errors. Anyway will try to edit thee Main.vi which exchanges data with the hardware and the Auto.vi which uses the acquired data and also creates data to write to the HW.
We in fact do use the Queue structure to handle the statemachine states. Its fine to pass info between loops on the same VI.
But in our case we need to pass data BETWEEN VIs ... so we chose the FGs . I thought these were efficient. I am sure there are other means but generally we stick to one methodology as it helps to reuse basic codes for different applications and save time. But now I think its time to look further ... ??
06-14-2025 09:37 AM
@MogaRaghu wrote:But in our case we need to pass data BETWEEN VIs ... so we chose the FGs . I thought these were efficient. I am sure there are other means but generally we stick to one methodology as it helps to reuse basic codes for different applications and save time. But now I think its time to look further ... ??
FGV's can block execution if they are called in parallel; does not always happen, but it can happen. I would recommend switching to DVRs instead; they offer the same protection as FGV's, can offer parallel Read access, and it is easy to pass around a DVR reference to other parts of the code if needed. They are probably faster than FGV's, but I am not sure. Most likely FGV's are not your rate limiting step. Switches to the UI thread can undermine performance; I would look for these first, (property nodes, DLLs, etc)
06-14-2025 10:01 AM
The "best" way to pass data "between" VIs is to use wires. Note by "VIs", I (of course) include sub-VIs. Wires have a "beginning" and an "ending", so you can literally "follow the data".
There are also a variety of "named References", including Global Variables, Functional or otherwise, which "encapsulate" data and can "accept" or "produce" the data on request, but don't show where the data originated and/or terminates.
Queues are a little better, as they include a "reference wire" that you can follow to find the origin or destination of the data, although the "flow of data" is not always clear. An improvement that allows asynchronous data transmission is the Asynchronous Channel Wire, such as the Stream Channel Wire that lets you send data immediately "out" of one VI, "jumping over" any loop structures inside the VI and the VI's output boundary and "jumping into" a "receiving" sub-VI without "going backwards over a Queue reference wire" to find the target sub-VI with the Dequeue Element function.
Bob Schor
06-14-2025 12:54 PM
One more thing that I forgot to add: Look for unnecessary data copies, especially of large arrays/structures. Use the show buffer allocations to see where you may have data copies.