LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Strip chart does not display data

Hi,
 
Strip chart does not display data until the mouse is moved around. I am using a thread to set data an a timer to constantly "update" or display the data. The data is not displayed in the strip chart until the mouse is moved.
 
I have attached a similar application below that has the same problem.
 
Any help will be appreciated.
 
Thanks
Ruan
0 Kudos
Message 1 of 5
(3,630 Views)

Ruan,

I have taken a look at your program and have some information.  It looks as though the thread we create with our data loop seems to block the rest of the program until the mouse events occur.  Unfortunately I haven't been able to force the code to unblock or allow system events so that the graph will properly update (calling the timer tick function). 

I was able to find a workaround but it changes the flow of control in the program so it might not be a complete solution.  I created a 'Stop' button on the UIR panel and generated its callback function into which I put the following two lines of code:

 CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, threadFunctionId1);
 
SetCtrlAttribute (panel0, PANEL_TIMER, ATTR_ENABLED, 0);

I also then commented out the CmtWaitForThreadPoolFunctionCompletion function in the Run button callback.  This program works fine, it will run when you click Run and stop whenuntil you click the stop button.  Again, this is changing the flow of the program you had so it may not be a desireable solution but I wanted you to know that it may be a workaround for the time being if necessary.  I will continue to research the problem with the original code and let you know when I find something.

John B.
Applications Engineer
National Instruments
0 Kudos
Message 2 of 5
(3,577 Views)
Hi,
 
Thanks for the reply,
Its seems as if i may have found the solution just by sitting back thinking a bit more...
I removed the timer and added another thread to the program that only plots the data.
This works really well and might be the best solution so far.
 
If anyone can think of something beter, don't hesitate to reply!
 
Thanks
Ruan
0 Kudos
Message 3 of 5
(3,558 Views)
Hi Ruan,

There are a couple of architecture options you can take to get the desired behavior you are wanting.  Before I discuss them, I wanted to mention that the
OPT_TP_PROCESS_EVENTS_WHILE_WAITING flag used in the CmtWaitForThreadPoolFunctionCompletion function is only used for processing system (i.e. button click, mouse move, etc) events and COM events to prevent deadlocks. It doesn't process CVI internal events like a timer tick. Basically, the point is that that flag isn't equivalent to ProcessSystemEvents

Okay, so there are a few alternative approaches you can take to get the behavior you want.  However, I did want to mention that since you are reading and writing data from different threads, you should be using some time of thread management features like locks. I would recommend using our Thread Safe Queue.

1) Do not use the Timer Control and use Thread Safe Queues along with the TSQ callback mechanisms. In this case, you will spawn off a new thread that writes to the TSQ. You then have a TSQ callback setup to fire in the main thread when some event (i.e. there are 3 events availalbe to use) occurs. You will use the CmtInstallTSQCallback function to do this. In this callback, you will plot your data.

2) Do not use the Timer Control and use Asynchronous timers instead. With the async timer, the timer callback will be called in a different thread and from there, we allow you to update the UI. You still would probably want to use some thread managements methods here to manager your data to avoid deadlocks

3) Instead of the CmtWaitForThreadPoolFunctionCompletion, use the following code:

while (!flag)
{
     ProcessSystemEvents();
}     


This code should end based on some flag which is set when your separate thread (which is writing data) ends.  So your separate thread code could be something like:

while (xxxx)
{
    DataPoint = 1;
    ........
}
flag = 1;


This way, you ensure that when your thread ends, it notifies the main UI thread.

Besides those architecture suggestions, I would also recommend that whenever the user clicks the Run button and fires the callback, you should first dim the control to avoid users from clicking and firing this callback again which could result in reentrancy. Do this by saying SetCtrlAttribute (panel, PANEL_COMMANDBUTTON, ATTR_DIMMED, 1); 

Best Regards,
Jonathan N.
National Instruments
0 Kudos
Message 4 of 5
(3,542 Views)

Thanks alot,
i'll try it out and see what works best for me

Thanks
Ruan

0 Kudos
Message 5 of 5
(3,508 Views)