LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

continuous data through serial port

Hi, im using a serial port to continuously read data from an external device with no flow control. Using the advanced serial read/write example, I have managed to keep reading the data (17 bytes at a time, using a while loop) and format it to obtain correct values, so that data is read faster than it is sent to LabView (so no buffer overflow can occur). However, once I start performing analysis on the data within the for loop (such as graphing and formatting the graph), this causes the data to be read slower than it is sent to labView, so that in the end the VI hangs. I was wondering what I could do about this. Maybe I could use multithreading like is described in http://zone.ni.com/devzone/cda/tut/p/id/4575 (Multiple tasks example - simple). I don't mind if I skip some data during analysis and graphing, as long as not too many bytes are skipped. Does anyone have any suggestions on how to fix this?

 

0 Kudos
Message 1 of 10
(17,614 Views)
From what you are saying it sounds like you are doing the acquisition and analysis in the same loop. If this is so what you probably want to do is move the analysis/display into another loop. Loop at some of the examples of producer/consumer. If you click on "file, new" one of the installed templates is of the producer/consumer concept.
Putnam
Certified LabVIEW Developer

Senior Test Engineer North Shore Technology, Inc.
Currently using LV 2012-LabVIEW 2018, RT8.5


LabVIEW Champion



Message 2 of 10
(17,611 Views)

Hi Putnam,

Yes, I am doing both acquisition and anlaysis in the same loop (I've only been using labView for a week or so). So what you are saying is to use separate loops for analysis. If I have multiple displays of data, each analysed in a different way (e.g. one is filtered, another is fft'd), would it be a good idea to use a seperate loop for each display? Also, I suspect that the analysis loop would run slower than the data acquisition loop, so if I used a queue to transfer data between the loops (like in the examples you cited), I assume there would be problems? In such a case would it be better to use local variables, or do you have any other suggestions? Thanks for your help.

0 Kudos
Message 3 of 10
(17,608 Views)
Actually using queues would probably be better as your problem is that the analysis part will fall behind the acquisition loop, a queue will at least let the acquisition get ahead, but eventually you will loose some of the data, when the queues buffer fills. In the examples, under "queue"  there is a "queue basics.vi" example. Also, if you can move the data acquisition into a seperate vi, possibly having a "main" program that calls both the acquisition vi and the display/analysis vi in parallel, with the acq passing its measurement data to the other via a queue you will have some improvement as the analysis part runs in the UI thread, the other can be set to run in a different thread (right click on the vi's icon when open in the edit mode, select Execution, this screen allows you to select the "Prefered Execution System"). Unfortunately it still doesn't solve the problem that if your data acquisition is faster than your processing you will eventually fill whatever daq buffer you have. The solution to this is to store the data elsewhere, i.e. stream to a file, and analize it later.
Putnam
Certified LabVIEW Developer

Senior Test Engineer North Shore Technology, Inc.
Currently using LV 2012-LabVIEW 2018, RT8.5


LabVIEW Champion



Message 4 of 10
(17,598 Views)

Ok, Im having a problem with using multiple while loops. If you look at the attached picture, you can see that i'm just reading data from the serial port once the number of bytes = 17, and then doing some data formatting in the topmost while loop. In the bottom while loop I want to simply add 1000 to a byte read from the serial port. However, the bottom while loop doesnt seem to run, only the top one runs, and channel 4 in the bottom loop never updates its value, while channel 3 in the top loop keeps updating its value. So it seems that the two loops dont run in parallel. Can anyone explain what I'm doing wrong? I want both loops to run in parallel and update their values together if possible.

serial.png

0 Kudos
Message 5 of 10
(17,582 Views)

Hi,

 

From your block diagram, it is clear that the two while loops will not run parallel.

 

1. To make it run parallel, create a local variable for the stop control in loop 1 and use it terminate loop 2. Disconnect the wire running between loop 1 and loop2.

 

2. Also include some time delay in both the loop say for instance 10ms. (No delay in while loop will take 100% CPU usage in causes your VI to hang or even your system to hang).

 

3. You can also shift all your analysis part to the loop2. acquire in loop 1 and transmit the data via Queue to loop2 and do analysis and display in loop 2.

 

Hope this solves your issue.

 

Regards,

Nanda

0 Kudos
Message 6 of 10
(17,572 Views)

Hi Nanda,

 

Thanks for the hints, it appears to work in parallel now. However, with the time delays, the problem I have is that since data is coming in so fast from the device without any flow control, if I have too high a delay, the buffer overflows and the VI hangs, but the second loop has enough time to get alot of data. If I have it too low, then the acquisition loop completely takes all resources and the second loop loses alot of the data, but there is no chance of hanging. I can find a balance between the two, but the problem is then that this particular chosen delay time to get a good balance will only work with this particular macine will it not? If i use the VI on a different machine, then I will run into problems right? Does anyone have any suggestions on how to solve this?

0 Kudos
Message 7 of 10
(17,569 Views)
When ever you have a loop that doesn't have anything else other than some basic LabVIEW functions (like your multiply) you want to put some time delay like "wait (mS)" or "wait until next ms multiple" to prevent the loop from taking all of the CPU. It can also, in your example, simulate more involved analysis' delay. Now, if you are going to have multiple displays you will want to move the analysis/display to a seperate vi, with a higher level vi calling both the analysis/display vi and the serial acq vi, to move the serial acq out of the user interface (UI) thread. As mentioned, without flow control if your data coming in is faster than you can process it, you will start loosing data. What is the device that doesn't have flow control? Can you run it at a lower baud rate? If so will you loose data on the input side, is what is being measured varying at a high speed?
Putnam
Certified LabVIEW Developer

Senior Test Engineer North Shore Technology, Inc.
Currently using LV 2012-LabVIEW 2018, RT8.5


LabVIEW Champion



0 Kudos
Message 8 of 10
(17,531 Views)
If you use a Dequeue or Wait in Notifier it will accomplish the same thing as a wait. What you want to do is basically give LabVIEW's scheduler a chance to see if other code is ready to run. Any action that will allow this such as a wait, wait for notifier, dequeue, etc. will accomplish this.


Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 9 of 10
(17,525 Views)

Thanks for your replies guys. The device I am using is basically an EEG/ECG instrument, and when I built it I decided not to connect RTS/CTS for flow control, or put in place any software/firmware flow control. I am currently running it at 57600/115200 baud, and although packets come into the pc at a constant rate, sometimes I lose packets. I will take your advice and implement the acq and analysis as sub-vi's, but I also had another idea. If I read data using the serial port every ms or so (so that data is read fast enough), and place datapoints into a circular buffer, I had the idea then that I could run the display loop every 10ms or so and just take a whole chunk of data that the acq loop has stored in the circular buffer. I was thinking that this approach would allow the acq loop to read data at a faster rate than it is sent to the pc, and also allow the display loop to display all datapoints, but in such a way that the display would update at a slower rate. Then the circular buffer should never overflow as long as I take a large enough chunk of stored data during each display loop. What do you guys think about this approach?

 

Also, I assume that the main reason to implement the acq and analy/disp loops as sub-vi's is to allow prioritization of each vi? If anyone knows of any similar VI's that continuously read and display data through the serial port, it would be helpful if you could link to them.

 

Thanks

0 Kudos
Message 10 of 10
(17,481 Views)