LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Multithreading and RS232 data too slow processed

Solved!
Go to solution

Hello,

Hope someone could help with this issue.  I have simple application which process ASCII data coma separated from serial port at speed of 115.2kbps. There is 6 columns  of unsigned short data .  I set-up COM call back function to receive data and I created separate thread function to plot data  on a 6 graphs - PlotWaveform() used.  Plots roll-over from beginning every time it receives more then 3000 samples. There is couple of more command buttons to set-up serial port, save data to a file, and exit application.

What is problem?  Application runs as intended but more and more slow with each received data sample. It is visible how graph plotting slows down. Apart from this,  all command buttons do not respond on cliks. (I need to click few minutes on them to get attention.)

Thanks

 

0 Kudos
Message 1 of 4
(4,255 Views)

There may be several reasons for the behaviour you are observing.

First of all, if I'm not wrong you have RS232 communications in the main thread and only graph plotting in the second one: one possible alternative is to move serial communications in a separate thread and leave all user interface, including graph plotting, in the main one.

 

To help you further you will need to answer some additional questions or add some code that we can look at:

  • How are you performing RS232 communications? Polling method? The device is continuously sending data without requests? And how are you reading data? Are you using a finite timeout or may you get stuck in ComRd until data arrives?
  • How long lasts your RS232 communications activity? Since it is in the main thread, if it takes too much time user interaction will be seriously affected. As an example, in an application of mine which was performing serial communications with a 500 msec timer I noticed visible effects on the UI if the timer callback was 250 msec long; the UI was seriously affected with 300-350 msec time. After moving all serial stuff into a separate thread the situation normalized
  • How are you passing data between threads?
  • Are you plotting new data only or are you plotting every time the whole set of data acquired (which is increasing more and more in time)?
  • What do you mean by "Plots roll-over from beginning every time it receives more then 3000 samples"?


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 4
(4,250 Views)

Thanks Roberto,

a) I continiously receive RS232 data from external device without request. I install  COM callback func.

InstallComCallback (comport, eventMask, notifyCount,eventChar, ComCallback, NULL);  where is:

static int eventChar =13;   

static int notifyCount =115;

Call back functions where I process data and store them into 6 arrays of 3000 elements:

void CVICALLBACK ComCallback(int portNo, int eventMask,void *datax);

b)  I assume ComCallback is called every notifyCount samples.

c)  Second thread what I installed plots only 6 received data arrays in the ComCallback(). 

static int CVICALLBACK PlotingThreadFunc (void *functionData)

{

  while(1)

  {

                  if(plotFLAG == TRUE)

                  {  

                                    plotFLAG = FALSE;

                                    //Plot Array1

                                    PlotWaveform (panelHandle, PANEL_GRAPH, CapMeasureArrayData1,

                                                                                            u16_DataIndexC, VAL_UNSIGNED_SHORT_INTEGER, 1.0, 0.0,

                                                                                            0.0, 1.0, VAL_FAT_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1,

                                                                                            VAL_RED);

                                         to ..........

                                    //Plot Array6

                                    PlotWaveform (panelHandle, PANEL_GRAPH_CAP6,

                                                                                            CapMeasureArrayData6, u16_DataIndexT,

                                                                                            VAL_UNSIGNED_SHORT_INTEGER, 1.0, 0.0, 0.0, 1.0,

                                                                                            VAL_FAT_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1,

                                                                                            VAL_RED);

                                                                   

                  }

   }

 return 0;

}

The plotFLAG is set in the ComCallback() when data is received.

d)  I plot as above, whoole data arrays when data is received.

e)  “Plots Roll-Over”  I meant: Plots are window into data steram and when it is plotted max. number of elements (3000) then arrays are erased and start new data plot from beginning.

0 Kudos
Message 3 of 4
(4,235 Views)
Solution
Accepted by Miki2006

From what you say about user interface not reacting to user clicks, it appears as if the program is continuously stuck into the com callback. At what rate are you receiving data from external device? Can you trace somewhat the time spent in ComCallback? This is the main reason why I suggested you to move serial comms into the second thread and keep graph plotting in the main one. Slowing down the rate at which the callback executes may improve user interaction.

 

Another relevant point can be the rate of plotting to graphs: you told that every 3000 samples you are clearing arrays and start plotting again from 0, but how often you plot data? only when 3000 samples are received or every time you receive data? In the second case are you plotting, for example, data 0 to 100 on the first step, 0 to 150 on the second, 0 to 200 on the third and so on until you plot data 0 to 3000 on the last one? This can be a inefficient way and can effectively slow down the process: you could keep an index on the amount of data plotted and plot only the new one: in the example above you will be plotting data 150 to 200 on the second step, data 200 to 250 on the third and so on.

Additionally: are you clearing the graphs also or only the arrays?

 

Third item: how are you passing data between threads? When using multithreading special attention must be taken in this matter: using a thread safe queue is normally the safest way to pass data between threads, as queues can dinamically grow and ensures a FIFO operation by itself, while keeping threads effectively independent between them.

 

As a last point, when ComCallback executes depends on the event mask you have set in InstallComCallback: the following cases may apply:

  • eventMask = LWRS_RXFLAG: in this case the callback is fired when return character (0x13) is received
  • eventMask = LWRS_RECEIVE: the callback is fired when 115 bytes are received
  • eventMask = LWRS_RECEIVELWRS_RXFLAG: in this case the callback is fired on any of the above events


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 4 of 4
(4,222 Views)