LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Periodically updating a graph from a continually updating array

I'm back after a few weeks of playing around with LabVIEW to try to fix it myself. I've gotten pretty far, I think, considering I have only myself and the two books "Learning with LabVIEW 7 Express" and "LabVIEW Graphical Programming" to help me!

My previous post on this subject can be found here, though it is not necessary to read in order to help me with my current problem.

With this post you will find 3 VI's that I have created, these are:
"sub-test.vi" is my first attempt at creating a usefull sub-vi. I have documented it and made an icon for it, but all it does is really save me from a few extra blocks in my program.
"neat but not working.vi" or ex1: I think it looks neat, but it will not work the way I would expect it too.
"messy and still not working.vi" or ex2: this one looks more messy, uses a for loop instead of a while loop and is not working the way I want it too either.

-----------------------------------------------------

What I am trying to do:
I have incomming serial data tagged with the channel name. I know how to extract the data (16bit unsigned int) from the header and footer using match patterns and type-cast (see sub-test.vi). I now want to "save" the incomming channel data (for simplicity lets assume that I only have one channel, called T1) in an array called T1. Naturally, I need to be relativly sure that my array actually does store my data (coming in at about 2/second). I then want to display that array in a graph at a set interval, say, every 2 seconds for example.
-------------------------

So far I have been playing around like a blind person on an open field, feeling my way in the dark. I have tried a lot of solutions that seemed like good and logical solutions to me, but they didn't work, so obviously my logic is flawed.

In Ex1 I tried to time the graphing by placing the graph and array in a sepparate while loop along with a "Wait until next ms multiple". The reading of the serial port is handled in a separate while loop running at max speed to catch all incomming data. It doesn't work the way I want it too.

In Ex2 I tried to achieve my goal with another tactic. In this I get the graph to display stuff all the time, but I am unable to time the "refresh" of the graph.

----------------

You may notice that I use the "old" serial port VI's (if you take context help on the Serial Port Init VI you will see a note explaining how it has been replaced with VISA VI's in the functions palette.. I have tried to use those, but I find them to be more difficult to set up. That is, I got it up and running and accepting data, but I got some errors and crashes from time to time, so I guess I used them incorrectly. Anyway, what I want to say is that if you feel that I should use the VISA VI's instead, I will need someone to set them up correctly for me the first time so I can see how it should be done.

------------------------

Both Greg McKaskle and Brian Powell provided a lot of help in my first thread at the very beginning of my project, and I hope that someone will be just as helpfull this time around!

I use LabView 7 (the posted VI's from school) and Labview 7 Express on my personal laptop. (what -is- the functional difference between the two? I have not found anything? The only difference beeing that the Express have a watermark on the VI's?

All the systems use Windows XP
0 Kudos
Message 1 of 7
(3,643 Views)
There are a number of issues here, but the main one is that you need to understand how data flow works. If you have a loop running and the graph is in another loop expecting data from the other one it will not receive anything, it won't even run...until all that data is available. In the "Neat but not working" example that means that the serial reading loop will run as fast as it can and because you have auto-indexing on it will even report values all the times it reads nothing at all on the port (you need to expand the logic to handle the fact that the signal transfer takes time and is not continous)..so that loop is generating an array and doing it fast with lots of empty (0) elements. It's not until the stop button is hit that the second loops starts, and th
en all that happens is that the graph gets the same array over and over again on each iteration (no need to build a 2D).

So - what should you do. Well, first of all you need to create a VI that will read the serial data properly (waits until all the expected data is there before parsing it to get the value). If you do that then you could use a chart (instead of a graph) and wire the output value to the chart...Charts remember the previous values and plots them all (a certain buffer size) whenever new data is available. A graph however does not remember previous values so in that case you will need to hold all the previous numbers in an array in a shift register and then append the new values as they are read using the build array function. This however is not very effective since it rebuilds the array each time, chich involves memory allocations etc...costs memory and execution speed. The best therefor is to have e.g. a circular buffer to hold the array. That way you work with a fix
ed sized array and the replace array element function which is much more efficient. You can find descriptions of circular buffers here...make sure you get the consept of shift registers first though.
Message 2 of 7
(3,643 Views)
aha! I thougth that when I used the "counter" to see how many bytes waited for me at the port, then it wouldn't put lots of 0's in my array.

I guess I could save the incomming stream to a file (that is a requirement, I need to log the data to a file) and then read the port every n'th second so that I know it contains roughly x samples and then parse and display all of that data. If I manually allocate the port-buffer size to hold the expected number of bytes + a marginal, that could work, right? In which case I should use a case structure (if "graph on" is true, then, say, every second, read the port buffer, parse the data into their respective arrays and graph/chart them).
I don't need to display all the received data, but if I use a chart I don't have to worry about the buffers since my total data ammount (per. chart) will be less than 45000.

I will look into charts again, I just tested to pass arrays to a chart, and that works too, with the added benefit that I can, as you say, have a display buffer so that I don't have to worry about that with my arrays. I can pass fixed size arrays to the chart and the chart will keep a (limited) history for me. I think that will work out great. The total number of data points at the end of the 6 hours should be around 43200, menaning I can hold the entire 6 hours in the chart buffer too without it impacting the performance to much.


---------------------
So what I need to fix now, regardless, is the "read from port" function so that it does not fill up my array with zeros!

And I noticed in a test VI that generates 3 constant value arrays and one "random number 0 to 1" array, that if I pass it all to the chart, the data is not displayed as expected. In the included VI, the graph shows 3 straight lines and the random number, while the chart doesnt. In the chart there are no stright lines. Also, the top one in the chart (I have 4 on display, and I run them stacked) has all the lines, while in the other 3 I get one line (channel) just as I wanted. Why is that? I'll look into all the problems myself, but if someone could give a tip that would be great because I am still very much a student and learning by trial and error can be very frustrating.
0 Kudos
Message 3 of 7
(3,643 Views)
The reason why the chart does not do what you wnat it to is because you have not yet understood how charts work. In your case you could take that single value that you read from the serial port and wire that to a chart. The chart can accept multiple values at a time, but it's really oriented twards single values. Attached is a modified version of your code that illustrates how it should be coded. I've also added a chart that only takes one of the values the instant it is available..much like the data from the serial port. I've removed the while loop to make it easier to see that the graph will only hold the data from the last run, while the charts will keep on filling in new data if you run it multiple times. There are great examples on how t
o do all kinds of graphing/charting in the examples that come with LV, if you try the find example section available from the help menu you will find out pretty much all basic stuff you need to know.

As for the serial communication by wiring the expected bytes all you do is tell the read part that it needs to read 0 bytes. It will still return with 0 bytes and the data flow will go on...and since you do not check whether the number of bytes was 0 as a condition for whether to generate a new array element...it takes those zero bytes and runs it through the type cast etc...If you were using VISA you could get far just by specifying the expected number of bytes (if it's fixed in each package anyway) and then VISA would use a timeout, not returning until the bytes have been received and read..or the timeout kicked in. With the old serial VIs you'll need to create something similar yourself (or find an ecxample that does something similar. There are examples on this as well included with
LV and on this site, but I haven't checked how good the fit for you).
0 Kudos
Message 4 of 7
(3,643 Views)
The data in the chart display needs to be transposed in order for it to display as you are expecting. Right click on the waveform chart and turn off transpose. When you run your code now you should get what you expect, both in stacked and overlay mode.

I often get caught out by this. The fanning out of the coloured lines usualy indicate the problem.
0 Kudos
Message 5 of 7
(3,643 Views)
My comment came out in the wrong place, It was for ment for Dagar's 'graph okay chart not as expected'

Mads' chart is perfect !!!
0 Kudos
Message 6 of 7
(3,643 Views)
Thanks IanW!
0 Kudos
Message 7 of 7
(3,643 Views)