LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Using InstallComCallback

Hi guys,
 
I was wondering if someone can help me out. I am making a uir which reads a modbus register map via RS232. Currently i use installComCallback in my main loop n set for RXCHAR. so everytime there is something at the port it calls the ComCallback.....in this function i read the comport and check for other necessary steps. It wrks fine bt it seems a little slow.....
 
I used a portmap to see what is sent n received on the serial port....well my program first sends a read request to reading the register maps....and then i get a response.....below is what i get on the port map....
 
3:51:29 PM Main_dbg.exe IRP_MJ_WRITE Serial1 SUCCESS Length 8: 03 03 00 24 00 04 05 E0  
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_WAIT_ON_MASK Serial1 SUCCESS  
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS  
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_WAIT_ON_MASK Serial1 SUCCESS
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS 
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_WAIT_ON_MASK Serial1 SUCCESS 
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS    
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS 
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_WAIT_ON_MASK Serial1 SUCCESS 
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_GET_COMMSTATUS Serial1 SUCCESS
3:51:29 PM Main_dbg.exe IRP_MJ_READ Serial1 SUCCESS Length 13: 03 03 08 36 B0 FF 00 00 00 FF 00 F9 65 
3:51:29 PM Main_dbg.exe IOCTL_SERIAL_SET_TIMEOUTS Serial1 SUCCESS RI:-1 RM:0 RC:0 WM:0 WC:1 
3:51:29 PM Main_dbg.exe IRP_MJ_WRITE Serial1 SUCCESS Length 8: 03 03 00 44 00 04 05 FE   ////next read request sent...i get a response after the same no of steps above......

See between the write and the read there is so much delay n waits....do u think its because of my code or jus the way the functions are designed! My aim is to hv the reading really fast...i use 115200 baudrate....and from the data i receive i update the uir....
 
If anything is unclear or need more info....let me know...
 
thanks
 
k1_ke 
 
 

Message Edited by k1_ke on 04-04-2006 04:01 PM

0 Kudos
Message 1 of 11
(7,246 Views)
Hi k1_ke,

Have you tried disabling the output queue?  If you open your port with OpenComConfig and pass a negative value for the output queue length, your program will write data directly to the port instead of using an intermediary output queue.  This tends to improve the performance of write operations.  It's worth a shot, if speed is important.

Mert A.
National Instruments
0 Kudos
Message 2 of 11
(7,243 Views)

Hi Mert A.

Thank you for your reply. I tried what you told me....but still in the portmap i get the same messeges before i receive the response. When using comcallback, would all the characters be waiting in the input buffer and read them one after the other, i roughly send 8bytes and receive between 8-13btyes...do u think the waits and get comm status is because it still waiting to get all the characters....

Also i jus want to make myself clear, when i step through it...i have a breakpoint when i read the port...from the time i send a request....n comes to the breakpoint....i have already got a few wait and get comstatus commands....

Do u think its something in my code thats triggering the extra lines??

looking forward to hear from you.

Thanks

k1_ke

0 Kudos
Message 3 of 11
(7,231 Views)
The messages you are seeing are really nothing to be too concerned with.  The wait messages come from a separate thread that waits on the events you register for (with InstallComCallback).  When the thread is signaled that an event has occurred, it wakes and posts the message so that your callback can be called the next time you process events with ProcessSystemEvents (or RunUserInterface). 

There are a couple things I can suggest.  You say you call InstallComCallback in your "main loop".  I just want to make sure you are not repeatedly calling InstallComCallback unnecessarily in a loop.  This would repeatedly uninstall and reinstall your handler, and very well could cause the messages you are seeing at the port.

Also, since you are concerned with processing your messages as fast as possible, you should be sure that after a write operation, your program is either calling ProcessSystemEvents in a loop, or more likely, sitting in a RunUserInterface call.  If you doing other work after a write before returning to an event processing state, you can delay your callback.

If you are already aware of these points, you could post a bit of your code that shows how you install your callback and what you do in that callback.  I'd be happy to take a look at it to see if anything is amiss.

Mert A.
National Instruments
Message 4 of 11
(7,231 Views)

hi Mert A

Thanks alot for the reply. No i only call installcomcallback once in the start in main loop.....i also do not open n close the comport.....well i hv a timer callback which sends a command to the serial and then receive data using comcallback and then update the uir using Convert2Buffval()........i dont use processsystemevent() but after a send request is made.....it should wait until the data is received....even if the timer tick occured...i check if the respective flags where set...if yes send another request otherwise wait.....attached a the pieces of code....for comcallback n timer....

hope it helps...

thanks

k1_ke

 

0 Kudos
Message 5 of 11
(7,189 Views)
Hi k1_ke,

I don't really see anything obviously wrong with what you are doing, though I am a little confused.  Your com callback is registered to be called every time one or more characters arrive at the port.  It looks like you're making some assumptions about the number of bytes that have been read (e.g. Buffer[1], Buffer[2]) and setting response_flag based on some message termination character being received.  I would consider dropping the timer callback in which you send the requests.  You can register your com callback for the LWRS_RXFLAG event instead of LWRS_RXCHAR, if you know all responses will be terminated by a certain character.  Then ComCallback will only be called when a full response has been received.  You can then use ComRdTerm to read in the response (minus the termination char), then write your next request to the port.

I did not see in the code you posted where you are calling ProcessSystemEvent or RunUserInterface, but the only explanation I have for the multiple wait messages at the port is that multiple RXCHAR events are being queued before you allow them to be processed.  This could be the case if your timer callback writes the request to the port, then does some more work (meanwhile the response is already arriving) before returning and allowing other callbacks to be called.

I hope this is some help to you.  Good luck.

Mert A.
National Instruments
0 Kudos
Message 6 of 11
(7,184 Views)

Hi,

Thank you for your reply. Well i hv those checks cos i dont knw the termination byte, jus that the 2nd byte tells me hw many bytes i should receive....so later i check if the bytes received are the same thats all......i will look into the speed stuff later....for now i am happy with the perfomance

Currently i am stuck in another problem.....See i hv multiple panels.....i hv a timer in the main panel....which updates the parameters.....i use installcomback and everytime a char is recd comcallback is triggered....Now in my other panel i hv to use this too but the parameters are different for installcomcallback so what i do is when loading the new panel....i do the following....

InstallComCallback (comport, 0, 0, 0, 0, 0); //disable sync callback function

SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_INTERVAL, (double)0.005); //enables main timer

InstallComCallback (comport, LWRS_RECEIVE, 32, 0, VideoComCallback, NULL);

Well in this new panel i recd alot of bytes...and sometimes i cna hv less than 32 btyes in the que in the end....so then i use the same timer which is in the main panel....hv a flag so timer know what code to execute.....i change the timer interval to 5ms as thats longer than what it would take to receive 32bytes at 115200baud.......in the new videocomcallback i hv reset timer() everytime it is called adn enable timer everytime it exits....thus if it wrks fine....the timer gets reset before it counts 5ms.....bt if i look at the port map i receive bytes ramdonly...sometimes 32 sometimes 48......its weird.....and i hv checked...when in this new panel everythign else is stopped.....even the updatign in the main panel stops cos in the timer hv a flag....if idle i use the portmap to see there is nothign sent or received.

do u think what i done with installcomcallback is causing the problem??? also in the timer callback i now hv ProcessSystemEvents cos otherwise doesnt let me click on anything on the main uir....

Looking forward for a reply.

Thanks

k1_ke

0 Kudos
Message 7 of 11
(7,120 Views)

I was able to figure out my problem.

Thanks anyways for trying!

k1_ke

0 Kudos
Message 8 of 11
(7,109 Views)
Hello k1_ke,

So is your problem that you are sometimes receiving more bytes (48) than you expect (32)?  InstallComCallback will not affect the number of bytes that you receive from the connected device.  It looks like you are uninstalling and reinstalling your com callback properly.  I can't guess what the extra transferred bytes mean, or why they are being transferred.

It seems that your program architecture is getting a bit complicated by the multiple callback schemes (ie the timer callback(s) and the com callbacks).  You mentioned that the timer callback in your main panel is used to "update the parameters."  If you mean that it is used to set some internal global variables or data structures based on the current values of controls, you would be better off adding simple control callbacks that update the variables when the control's value actually changes.  Using a timer callback is effectively a polling scheme, which is typically something you should avoid.  It can also introduce other complexities, like properly disabling/enabling, adjusting intervals, and using global flags to execute one code path or another.

You could probably do without the timer callback in your video panel as well, since it seems like you are just using it to handle the case where the com callback hasn't been called as soon as you would expect.  What do you do then in your timer callback?  You should consider using the RXCHAR event again (if you do not know how many bytes you should get; 48 or 32) and doing all of your processing/handling in that callback.  However you determine that you have received all the data you need, you can do it in your com callback.

In some cases, timer callbacks are really the best choice, but more often than not, event-based callbacks are really the way to go.  If you simplify your program structure, it may make it much easier to understand what is happening when you have problems.

I hope this helps some.

Mert A.
National Instruments
0 Kudos
Message 9 of 11
(7,104 Views)
I'm glad you found the solution!  Good luck.

Mert A.
National Instruments
0 Kudos
Message 10 of 11
(7,103 Views)