11-11-2011 01:02 PM
I started an old thread about this but I've got some new problems. My vi is controlling a Keithley sourceMeter to read measurements every 5 ms for 6-10 hours using GPIB-USB. The vi simply sends the commands as a complete script to the instrument and then reads the measurements (voltage and current) in one loop using the visa, and saves the data and displays them in a second loop using a queue. I decided to use a queue and a second loop because of the delay that was caused by reading the data + saving them in a file + displaying them, all in one loop! I want to be able to see all the data with the real time axis, so I used an xy-graph.
Solved! Go to Solution.
11-11-2011 03:37 PM
11-11-2011 05:21 PM
Thanks for replying. Here is the subvi.It's a very simple average and charge calculation.
11-11-2011 08:38 PM
You do not need the sequence structures inside the loops. Dataflow produces the same results. You also do not need a diagram which is 10000 pixels wide. The style guides recommend keeping a block diagram to the size of one screen. With a little effort I got it down to under 1200 x 2400 pixels.
I can explain the timing variations in the upper loop. I am not sure about the lower loop or the meter.
Loop 2 has a 4 ms Wait Until Next ms Multiple while loop one uses 5 ms. The Dequeue Element function in Loop one has the default time out, meaning that it will wait forever for an element to dequeue. Now let us look at the times which the loop actually gets data from the queue. First we will assume that the lower loop enqueues an element exactly every 5 ms starting at t = 0. The upper loop will start looking for data to dequeue every 4 ms multiple also starting at t = 0. But the time it actually has data to read depends on when the lower loop enqueues data. Look at the table below:
Ready to Dequeue048121620!!!283236!!!44
Actual Dequeue051015202530354045...
The upper loop skips the 24 and 40 ms multiples because the Dequeue was still waiting in the previous cycle.
In addition you are building arrays and writing to a file every 4 ms (actually 5 or 10 ms) in the upper loop. Building an array in a loop requires frequent memory re-allocations as the array grows. Arrays are stored in contiguous memory locations so the entire array gets moved every time a re-allocation takes place. To avoid the memory re-allocations Initialize the arrays outside the loop to a size equal to or greater than the maximum size you will allow for the array. Then inside the loop use Replace Array Subset where you now have the Build Array primitives. If you initialize the arrays with NaN values the array elements which have not be replaced by actual data will not plot.
Writing four points to the file 200 times per second is not very efficient. Each write involves a call to the OS and introduces indeterminate latencies which may be much larger than your desired 4-5 ms cycles. Accumulate data and write every few seconds or minutes. Use the same memory management scheme descibed in the previous paragraph for the data accumulation.
Updating the graphs on the front panel 200 times per second is useless and may slow things down. 1. The monitor probably only updates at about one third that rate. 2. The users eyes and brains cannot process more than 10-20 updates per second. And even if your data changes significantly at that time scale the user will not remain at attention all day to respond immediately to a change. Slow down the updates. One or two per second may be enough. Your graphs are about 750 pixels wide. If you write more data points to the graph than pixels in the width, LV will reduce the data to fit. You decide how you want to reduce the data and your users will see what you want. You can use averages, decimation, median, peak, or many other ways of looking at the data. But only write 750 points to the graphs at any time.
Lynn
11-12-2011 10:49 AM
11-12-2011 04:43 PM
Having a shorter delay in the upper loop is not a bad idea. Using the Wait Until Next ms Multiple rather than just the Dequeue timeout may cause the occasional timing jumps.
I do not have LV open now, so I am trying to recall your VI. I think you were collecting 3 data values and a time stamp every 5 ms. That is 800 elements each second. If you want to record all the data but only write to file every 5 seconds, you will need to accumulate 4000 elements. Since file writes are not always done exactly when you request them due to OS behavior, you need to allocate slightly larger spaces. You might initialize a 2D array as 1200X4 (1200 rows of 4 columns) of NaN. Put this array into a shift register. Every time you Dequeue data, replace the next row with the dequeued data. When you write to file, use Array Subset to get the part which has been replaced with real data and write only that part to the file. Put the initialized array of NaN in the shift register again and continue replacing data.
Lynn
11-13-2011 08:08 AM
Thanks for your help. I think I get it but I'll see when I test it tomorrow.
11-14-2011 12:10 PM
It works! Thanks again for the support!