Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Long term periodic serial port communications in VB6 consumes CPU time

Status
Not open for further replies.

Mictel

Technical User
Feb 5, 2008
4
0
0
US
Can VB6 poll the serial port say every hour without sucking up 40 to 50% of the CPU time looping continuously waiting for a 60 minute timer interval to occur? For example, is there a way for a VB6 routine to run in "sleep mode" more efficiently until it is time to do a short data transfer via serial port, and go back to sleep until the next one?

Also having a problem that the PC power management sleeps or hibernates while VB6 is running (looping) waiting to poll the serial port once per hour. Can VB6 prevent PC power management or hibernation while a routine is running? The routine (which communicats via serial port and writes data to a file) works just fine (other than the CPU usage above) if polling is done every 5 minutes.

Thanks,
Mike
 
Although the Timer function is preferable, you can put forms in an ActiveX DLL project.
 
>there is no form to drop it on

There is no reason why you cannot have a form that is never made visible onto which you can place the timer control. And the timer event would simply call the relevant routine in your module.

Other alternatives, in increasing order of complexity might be:

Use Sleep API in combination with DoEvents to drop the CPU load whilst slightly reducing applaicatin responsiveness

Or, in a module, you can write a callback function and use the SetTimer API

Or you can use the above concept to write a formless timer object which can be used in a class (if you don't want to write one yourself you might find an example of such a thing in this forum, e.g. my example in thread222-1246190)

Or you can use the API to write your own much more lightweight version of DoEvents (again, something we've illustrated in this forum - you probably need to search on MsgWaitForMultipleObjects)

 
I had a similar issue where the CPU went to 100% when waiting for data from the com port. I finally found a solution:

Add a new module called pause.bas
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

In the mail program, I used this loop to get data from the com port:
Do
Dummy = DoEvents()
Pause.Sleep 300
Loop Until frmMain.MSComm1.InBufferCount >= 2 Or CL = "Y" 'Min OF CR/LF or escape

Dan
 
I would use the simple approach of interrogating the Time() to see if it had reached the next hour. It would then not matter if the computer had been switched off during the samples.

Have a 10 second standard Timer Control
Dim MinuteFlag as Boolean 'used to ensure sample happens only once an hour

Sub Timer1_OnTimer()
If Minute(Time)=0 then
If MinuteFlag=false then
MinuteFlag=true
'******* here is where you interrogate the comms port
End IF
End If
If Minute(Time)=1 then MinuteFlag=false 'Reset flag for next hour
End Sub

This takes less than 1% CPU usage.
 
Regarding preventing sleep, if the computer is used by others wit the same application, you can have a routine that detects if no keys or mice have been used for a time less than the sleep setting then, if the computer hasn't been used, send a TAB key command to the screen every minute with the same timer above to keep the computer awake. This also defeats screen savers.

There is probably a more exotic way of doing this with APIs
 
I haven't seen anything in this thread yet that justifies the use of DoEvents or Sleep calls at all, let alone any form of timer besides the intrinsic Timer control.

As strongm already said, if the program must run without displaying a Form you simply Load the Form without Showing it. In the simple case of a program with just a Form you set its Visible property to False. That doesn't even appear to apply here based on comments in the code snippets above referring to command buttons.

While in trivial cases (as described in the docs) it is possible to use the MSComm control in a polling fashion, this isn't really how it was meant to be used. Doing this "fights the paradigm" in VB, which results in all of these issues that are being hashed out here. You'd run up against pretty much the same issues in C++ however.

Rewrite the program as a state machine making use of the OnComm event and CommEvent property along with the RThreshold and SThreshold properties if truly needed. There is way too much "straight line" code here to work properly. VB wasn't designed to be used this way.

Power control is an administrative function that is not meant to be under application discretion. The SysInfo control will provide your program with some information about power management and raise events to inform you about pending changes. There are API calls that can be made to define and activate power schemes and interrogate power policies but they generally require administrator rights. Power scheme change attempts may be overridden via group policy. If you want a different power scheme you should set it via the normal system administration tools.
 
As the original questioner said the OnComm wont be of much use because I guess the serial device is presumably sending out stuff all the time and he only wants to sample it every hour and ignore in between.
Therefore polling is quite OK in this case.
Remember that once you open the port you will start receiving data immediately in the Comms buffer and only when the Input statement is reached will you read it.
This means that if the port is opened halfway through a string packet, you get only the last part of it.
You also need to be able to recognise the start and end of the transmission packet and separate it if you want to activate anything except just visually look at the received data on the screen.
Also with quick computers you can get many firings of the Sub OnCom during one packet so data has to be accumulated.
I accumulate the data in a buffer and use the Instr statement to detect a unique start or end character that most serial systems deem to have (often a Chr(13) at the end of a packet - then close the port)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top