VB:Tutorials:WINAPI:High Resolution Timing

From GPWiki
Jump to: navigation, search

So, you're interested in having your functions act at specific time intervals, eh? Naturally you would turn to the Timer Control included with VB. Unfortunately, the timer control has a resolution of ~55ms. 55ms seems like a very short time to us, but to the computer, 55ms is an agonizingly long time. Don't torture your computer! Use accurate and high-resolution timing methods!

Private Declare Function GetTickCount Lib "kernel32" () As Long

I love this function. When I first stumbled upon it, I was amazed. Why didn't Microsoft use this simple API call when they made their VB Timer Control? I guess it's one for the X-Files, Mulder...

Those with DOS experience might remember the simple DOS timer ticked at 18.158Hz, which equates to 55.07ms per cycle. I suspect 55ms was chosen as an established timer resolution that couldn't be set so precise that it might claim significant resources on low-end machines. ~ ViX44, 05-SEP-2004

Anyways, what this function does is return the length of time that the system has been running in milliseconds. Since computers are frequently left on for days at a time, be sure that you use the Long data type as opposed to Integer when dealing with this control, or you will run into problems.

Determining when exactly an interval of time has passed is now a simple matter. All we have to do is store the current TickCount in a variable, and wait until the desired time length has elapsed:

TempTime = GetTickCount()

Do While DesiredTime < GetTickCount() - TempTime

'Do some things

Loop

Here we have a temporary variable called TempTime in which we store the tick count. We then loop through the statements we want to execute until the difference between the current time and the temporarily stored time is greater than the value of DesiredTime. We should therefore set DesiredTime to the number of milliseconds for which we would like to execute the loop.

The above example shows how we can execute some code for a specific length of time. What follows is an example showing how to execute some code every time an interval elapses:

ExitFunction = False TempTime = GetTickCount()

Do While not(ExitFunction)

   If DesiredTime < GetTickCount() - TempTime then
       'Reset the temporary variable
       TempTime = GetTickCount()
       'Do some things
   End If

Loop

This function will execute the code each time the interval specified by DesiredTime elapses. (In order to exit the loop, include some code to simply set the ExitFunction Boolean to True.) In this fashion we can, for example, ensure that our graphics drawing routines do not exceed a specified frame rate, or we can nullify the speed differences between systems in order to make your program run consistently on all platforms.

Finally, the GetTickCount() function can also be used to benchmark your code. By this I mean you can use it to determine the time it takes to execute a specific chunk of code, thereby enabling you to tweak it for optimal speed (or slow it down, if that's what you're after). I have written a stopwatch like program to demonstrate how you would start, stop, and accumulate time through the use of the glorious GetTickCount API call.

Even if this method is accurate for time based applications, windows never allows your application to run at perfect intervals. Because there are n number of processes running in the background and when any one of the process get priority, your application loses accuracy. But don't worry! There is a method 'Multithreading' which can give high accuracy, specifically when you are writing time based applications for Robotics & Automation systems. Refer Microsoft documentation for knowing how to use multithreading in Visual Basic applications.

Click here to download now.