From Saturday, Nov 23rd 7:00 PM CST - Sunday, Nov 24th 7:45 AM CST, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

LabWindows CVI RS-232 isn't fast enough

Solved!
Go to solution

Hello,

Is it possible to write a program in C that takes RS-232 data into buffers and prints it on the screen?

I ask this because I am writing a program in LabWindows CVI and the data isn't coming in correct. I have used SimpleTerm Gold to see what the data is supposed to look like, but CVI misses some. I believe that it isn't fast enough and therefore misses data.

Would a C program (not using CVI callbacks or functions) be possible and better?

Is there any way to make CVI work faster? I have changed the environment sleep policy to 'Do not sleep'. There are two ComRdTerm because one only gets every other packet.

Baud Rate 115200, no parity, 8 data bits and 1 stop bit. The most data I receive is 313 bytes and the smallest is 17.

Any help would be VERY appreciated as I am completely stumped.
Thank you,

 

Code is below.

 

OpenComConfig (com, "COM9", 115200, 0, 8, 1, 1024, 1024);//< Opens serial ports
SetComTime (com, 0);//< Sets serial port to never time out
t0 = clock();//< Calculate how fast ComRdTerm is
bytes_read0 = ComRdTerm (com, &buffer0[0], 314, 10);// Read com and store in buffer
sprintf(p_check0,"%.4s", &buffer0[0]);
t0 = clock() - t0;
double time_taken0 = ((double)t0)/CLOCKS_PER_SEC;// in seconds
printf("%d\t%f\t%s\n",bytes_read0,time_taken0,&buffer0[0]);
memset(buffer0, 0, strlen(buffer0));// Clear buffer

t1 = clock();
bytes_read1 = ComRdTerm (com, &buffer1[0], 314, 10);
sprintf(p_check1,"%.4s", &buffer1[0]);
t1 = clock() - t1;
double time_taken1 = ((double)t1)/CLOCKS_PER_SEC;
printf("%d\t%f\t%s\n",bytes_read1,time_taken1,&buffer1[0]);
memset(buffer1, 0, strlen(buffer1));

0 Kudos
Message 1 of 11
(5,990 Views)

I can hardly imagine that CVI cannot handle such a limited amount of data but you don't specify how frequent is the transmission. Nevertheless, I work at 38400 baud and can sustain 50 Hz reading without problem in a complex CVI application that handles all the user interface and othe operative tasks in the same moment.

You are using linefeed as the read terminator: are you sure it cannob be received inside the strings?

As a general hint, i would avoid using printhf to print to the standard output as it will consume more time than using some simple indicators on a panel.,



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 11
(5,985 Views)

Hi,

 

I can read more than 2000 bytes/s with the baud rate 115200 (that is the fastest transfer mode from the sending hardware).

I am using the viRead command an read the serial input byte per byte using in a TIMER Callback, so no other programs or services can interrupt the reading.

 

err = viRead (Device, &byte1, 1, &readbytes);

 

The problem is the slow plotting of the data using PlotXY. Therefore you cannot plot each incoming value but only each 20th value.

 

Gunther

0 Kudos
Message 3 of 11
(5,978 Views)

Thank you for the response,


I am receiving packets of data every 200ms, and when I analyze the data afterwards I am getting the whole string so it doesn't seem like the linefeed is getting received early but i'll look more into that.  Every now and then it takes 0.5s to read a packet that usually takes 0.01s. That is why I thought it just wasn't fast enough, but it definitely sounds like should be able to handle it.  Thanks for the hint, I was using the printf to debug but it would be just as easy and fast to put some indicators on a panel.

 

Keegan.R

0 Kudos
Message 4 of 11
(5,960 Views)

Thank you for responding,

 

Yes, so I should definitely be able to read my data if you are able to do that.  I will try using viRead with a timer and see if that helps.

 

Thank you for your insight.

 

Keegan.R

0 Kudos
Message 5 of 11
(5,953 Views)

Keegan,

using viRead implies you convert all your code to using VISA, which is a different thing with respect to the built-in RS232 library.

In particular, using VISA you will need also to distribute it to the end user of the equipment, which may complicate making a distribution of your software.

 

Given this, in my experience I have seen no difference in program performance between RS232 library and VISA, so it's your choice whether to use one or the other approach.

 

You should investigate on the events when reading takes 0.5 sec or more: is it a problemi in the external device or is a problem in the code? Even if it is your program that waits, nevertheless serial communications uses a buffer, so you should be able to read all following messages without losing any of them.

An alternative approach to using ComRdTerm, if you know how many characters to expect on every read, is to use a simple ComRd with the proper number of characters inside. Alternatively, you could try using a fast timer, reading all avvailable characters and accumulating them in a buffer, scanning the buffer in search of the termination character and discarding the resulting message after it is completed.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 11
(5,940 Views)
Solution
Accepted by K.R
Thanks for all the help guys. I finally figured out the solution. The program was running too slow because I kept opening and configuring the ports (not shown in this code) I simply kept the ports open and it works great.

I really appreciate all the comments and insight. All of them will definitely help me further along with developing with CVI.

Regards,
Keegan.R
0 Kudos
Message 7 of 11
(5,937 Views)

I didn`t fucused on it!

I`m happy you solved your problem!



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 8 of 11
(5,921 Views)

Hello, 

 

    I have similar issue.  First I used asynchronous timer to check for received data using ComRd with minimum timeout.  I find that there is always a 10 - 15 millisecond delay which really slows my communications.  I use virtual CAN implementation which uses CANopen SDOs which require acknowledge.  There blasting is not possible and bursts are required where it waits on ackowledge.  I find the ack happens quickly but CVI doesn't seem to detect received packet for anywhere between 10 - 15 milliseconds.  I even switched over to InstallComCallback and used callback function.  Still same delay there as well.  I believe it is due to task switching/multithreading delays.  I tried to make priority of timer higher but that doesn't work either.  Appreciate any help.  I need to receive the data immediately similar to an ISR on an embedded target.  Any delay will drastically slow my bootloader application.  Theoretically I should be able to load 60K in 20 seconds but it is taking 2.5 - 3 seconds.

0 Kudos
Message 9 of 11
(3,817 Views)

Sorry not 2.5 - 3 seconds, but minutes

0 Kudos
Message 10 of 11
(3,814 Views)