10-05-2010 12:22 PM
Currently, I have a program contained within a PXI chassis that has an FPGA, Relay Card, and a DAQ card. Running LabVIEW 8.6 on a Windows XP 32-bit
The front panel contains:
Buttons for each relay, a numeric indicator for the DAQ, and a Table with 4 columns that logs events with a timestamp and misc data. It might be important to note that the log contains a Table, which acts as a 2-D string array, but is scrollable, etc.
The main section of the Block Diagram contains the following tasks:
1)Event structure that contains actions to Front Panel buttons being pressed.
2)An automated sequence that reads a script from a file, and presses buttons using Property Node: Val (signaling)
If I have a script that tells the program to press Button A, wait 1ms, Button B, wait 1ms, Button C, wait 1ms, loop....
Example 1: Script with delay of 1ms between Buttons (Milliseconds since previous) Example 2: Script with delay of 100ms between Buttons (Milliseconds since previous) Example 3: Script with delay of 1ms between Buttons; Logging occurring in a seperate event structure with a loop timer of 20ms. (Milliseconds since previous) Example 4: Script with delay of 1ms between Buttons; Using Shift Register/Concantonate Array and only writing to Local Variable for Table during Timeout of Event Structure. Example 1:[0, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 15, 16, 17, 18, 19, 20... as high as 100ms... to infinite] Example 2:[0, 100, 100, 100, (Don't see it here since it occurs during delay) .......... 101, 102, 103, 104, 105, 106] Example 3:[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, ...] Example 4:[0,1,1,1,1,1,1,1,1,1,1,1,1,1......1,1,1,1,1,1... Update Screen when finished] --- WINNER! Sort of.
I guess I can't wrap my head around why that fixed the problem. It's just a simple variable write. My task manager shows that processor and RAM are virtually asleep, and I'm only writing an (i x 4) element string array to a local variable. Literally, leaving everything else in place and JUST commenting out the "Write to Local Variable" it runs absolutely perfect.
Why is it taking so long to write? How big of a buffer does LabVIEW use to write to the front panel? Is there a better way to do this so I can gain back that update rate?
I appreciate the time and effort. Hopefully, there's a way to get my log closer to real-time without impacting the timing of the events.
10-05-2010 02:29 PM - edited 10-05-2010 02:35 PM
It sounds like you are trying to update your GUI at 1KHz and in Windows that just doesn't make sense (30 Hz screen update rate).
The issue is probably allocating more memory for the screen updates (must be a single buffer and if old is not large enough, allocat more and continue).
So the clasic answer is Producer/Consumer where the consumer keeps the GUI updated but can run behind if required but let teh Producer keep running with the delasy from screen updates.
BTW:
One of my associates conciders getting a table to update in a finite amount of time, one of his biggest accomplishements. If you get to the point were you recognize that all of that data in one object is what is hitting you, you could go the route he walked which involved only showing part of the data but making it look like all of the data was there.
Ben
10-06-2010 12:25 PM - edited 10-06-2010 12:31 PM
Ben,
Thanks for the helpful reply. Unfortunately, I had already considered that.
So to reiterate more succintly, In Example 2, I used a lower update rate of 10Hz. And in Example 3, my "consumer loop" I used a shift register to store the updates, and only wrote to the front panel object at a 1Hz rate... and was still experiencing a delay within my "producer" loop when this occurred. Granted, the delay was only once per second (less frequent than if I was updating at 100Hz) but still there.
Disclaimer:
My examples used arbitrary numbers in order to show the patterns I have experienced. These numbers have been varied as a means of eliminating variables throughout this process, and sure enough the patterns remain the same no matter the rates. These examples are meant as a qualitative analysis. It would be too clutterd to include the hundreds of tests that I've run. I must've deleted that part of the OP somewhere along the line.
I've been thinking about it, and I am wondering what priority Windows/LabVIEW sets for screen updates. One would think it would have low priority... but who knows?
10-06-2010 12:31 PM
THe issue is allocating the memory for a larger buffer (If I understand your sceranio correctly).
LV manages the memory for us but when we grow an existing buffer (like when appending ) the thread goes into a "Page Fail wait" state, the OS kernal is woke-up the memory is allocated, the data is copied to the new buffer (must be contiguous memory) the pointers are updated and onlt after all of that (any anything else that Windows thinks is executable) that the code will resume.
The producer loop should be building anything. Pas the data and let the consumer do the building.
Ben
10-06-2010 12:45 PM - edited 10-06-2010 12:47 PM
Producer:Flips relays, sends digital data through FPGA, and flags the consumer's event structure to process the data.
Consumer:Taking the timestamp, Analyzes the data, Builds the next line of the array, and appends it to the value passed to it from the shift register. In example 3, the value in the shift register was passed to the UI once every "X" milliseconds. In Example 4, the shift register's value was only passed to the UI upon a 100ms Timeout. Which basically means when the test is done.
The interesting thing is that ALL of that, with the exception of passing the array into the local variable, can be done at a rate of approx. 3kHz with no additional delays of any kind. A shift register acts nearly identical to a local variable, though it lacks a front panel object. So I'm still allocating the memory, appending the array, etc. And I have no problems so long as I keep it in the shift register.
That's why I'm completely perplexed about this. I would think that using a shift register would have less overhead as a front panel object, but 3kHz vs 1Hz? And even then, 1Hz still gives me a delay.
Edit: And since I am using Seperate loops and Event Structure to pass the flag and data to the Consumer, the Producer can continue to produce even if the Consumer gets behind.
10-06-2010 01:16 PM
Post screenshots of the code to go with your words please.*
Thank you,
Ben
* I have an app in my head while at work and answer customers Q's about other apps so trying to envision your code while still doing my normal work... aint easy. If you post code images I/we can give beter replies.
Ben
10-06-2010 02:38 PM - edited 10-06-2010 02:43 PM
I can't show you my actual VI, so I did it in paint. *puffs out chest* Hahha, anyhow. As you can see... no writing to local variable. Just appending to shift register.
In Example 4's setup, the top event loop has a timeout of 100ms, and if 100ms passes without (4) occurring, it writes to the Local Variable.
In Example 3's setup, the top event loop will write to the Local Variable (after creating the 2-D array) if "x" milliseconds has passed since the last write.
Hope that helps. If not, I might be able to use an Eval copy at home and screenshot it.
Edit: Obviously I have my loops timed and stoppable. And the reference and values passed in (1) changes, blah dee blah. You get the idea though. =P