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 Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Precise Timer

Status
Not open for further replies.

clarkbr

Technical User
Apr 5, 2001
3
US
In short, does anyone know how to use VB to measure times of less then .01 seconds?

In detail, I am trying to time an event that takes .001 - .009 seconds. The best resolution that I seem to be able to get is .01 seconds. I have reviewed the archives and found thread222-6546 . This was helpful in that it created a timer that doesn't reset itself but every 47 days, but it didn't help my problem. To test for accuracy I created a form with four text boxes, one command button and the following code:

Code:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetTickCount& Lib "kernel32" ()
Private Sub Command1_Click()
    Text2 = GetTickCount
    Sleep Text4
    Text1 = GetTickCount
    Text3 = Text1 - Text2
End Sub
By inputting different values into Text4 I could see how accurate GetTickCount is and the actual values returned. It seems that it is accurate to .01 seconds and it always round up.

Does anyone know how to use VB to measure times of less then .01 seconds?
 
AFAIK the timer is NEVER expected to be acurate. MS. has numerour disclaimers (FINGER POINTING ==> INTEL?) stating that the "Clock" does not keep accurate time (this has been attested to often and loudly by MULTITUDES of users and programmers alike). MS. states - in more than one place that the "clock" has a "LOW priority" and may not (substitute USUALLY IS NOT) updated on a regular basis. Wheather your resoloution issue is a display function or not, expecting a Windows operating system to (reliably) do anything on a interval of less than 10 milliseconds is "asking for IT".

There may be other 'clocks' you can install as addons, but unless Uncle Bill gets a higher resoloution "Clock" there isn't any hope.


MichaelRed
redmsp@erols.com

There is never time to do it right but there is always time to do it over
 
I have further researched this problem and come across the API QueryPerformanceCounter that seems to more accurately store time. I have written the following program to test for accuracy. You need a form with a text box (Text1) and a command button (Command1). In Text1 one enters the number of loops to do. On my machine it does about 82000 per second. The min and max time are the fastest it can process the loop and the longest it takes. I consistently get .0001 seconds as a min and .006 as a max. I have to set Text1 = 100,000 to capture the .006s event. Using 10,000,000 I get the same answer. This would seem to tell me that I can expect about 1 millisecond accuracy from my machine. Is this correct? Am I missing something?

Most of this code comes from Just wanted to give credit where credit is due.
Code:
Private Declare Function QueryPerformanceFrequency Lib "kernel32.dll" (lpFrequency As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32.dll" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type LARGE_INTEGER
        LowPart As Long
        HighPart As Long
End Type
Dim difTime(1 To 10000000) As Single
Dim CTime As Currency, Tnow As Currency, Tlater As Currency


' This function converts the data in a LARGE_INTEGER structure into
' the form of VB's 64-bit Currency data type.  For more information about how this works,
' go to [URL unfurl="true"]http://www.vbapi.com/articles/64bit/index.html.[/URL]
Private Function LI2Curr(li As LARGE_INTEGER) As Currency
        Dim temp As Currency
        CopyMemory temp, li, 8
        LI2Curr = temp * 10000
End Function

Private Function Atimer() As Currency
        Dim freq As Currency  ' high-performance timer frequency
        Dim count1 As Currency  ' timer reading before calculation
        Dim buffer1 As LARGE_INTEGER  ' data input buffer for...
        Dim retval As Long  ' generic return value
        
        ' Get the frequency of the high-performance timer and, in the process,
        ' determine if it actually exists or not.
        retval = QueryPerformanceFrequency(buffer1)
        If retval = 0 Then
                Debug.Print "This computer does not have a high-performance timer."
                Exit Function
        End If
        
        freq = LI2Curr(buffer1)
        retval = QueryPerformanceCounter(buffer1)
        count1 = LI2Curr(buffer1)
        Atimer = count1 / freq
End Function

Private Sub Calc_MaxMin()
    Dim I As Long, Max As Single, Min As Single, MaxI As Long, MinI As Long
    Max = 0
    Min = 100
    For I = 1 To Me.Text1
        If difTime(I) > Max And difTime(I) < 1 Then
            Max = difTime(I)
            MaxI = I
        End If
        If difTime(I) < Min And difTime(I) > 0 Then
            Min = difTime(I)
            MinI = I
        End If
    Next I
    Debug.Print &quot;Process Time = &quot;; Atimer - Tnow; &quot;seconds&quot;; &quot; Max time =&quot;; Max; &quot;Min Time =&quot;; Min
End Sub
Private Sub Fill_difTime()
    Dim I As Long, LastTime As Currency, CurrentTime As Currency
    For I = 1 To Me.Text1
        CurrentTime = Atimer
        difTime(I) = CurrentTime - LastTime
        LastTime = CurrentTime
    Next
End Sub

Private Sub Command1_Click()
    Tnow = Atimer
    Fill_difTime
    Calc_MaxMin
End Sub
 
Process Time = 23.6291 seconds Max time = 0.4543 Min Time = 0.0001
Process Time = 12.585 seconds Max time = 0.0098 Min Time = 0.0001
Process Time = 12.5455 seconds Max time = 0.0022 Min Time = 0.0001
Process Time = 12.5209 seconds Max time = 0.0025 Min Time = 0.0001
Process Time = 12.5134 seconds Max time = 0.0023 Min Time = 0.0001
Process Time = 12.5266 seconds Max time = 0.0073 Min Time = 0.0001
Process Time = 12.5284 seconds Max time = 0.0022 Min Time = 0.0001
Process Time = 12.5328 seconds Max time = 0.0028 Min Time = 0.0001
Process Time = 12.5013 seconds Max time = 0.0022 Min Time = 0.0001
Process Time = 12.5155 seconds Max time = 0.0021 Min Time = 0.0001
Process Time = 12.4988 seconds Max time = 0.0027 Min Time = 0.0001
Process Time = 12.5086 seconds Max time = 0.0022 Min Time = 0.0001
Process Time = 12.5123 seconds Max time = 0.0025 Min Time = 0.0001
Process Time = 12.5262 seconds Max time = 0.0149 Min Time = 0.0001


My Results with 1,000,000 iterations. With the 100,000 iterations, the Max was USUALLY 0.001X, but was as high a s 0.006X. A tenative guess is that the time to fill the array is the dominant function (in terms of execution time), but that you really cannot rely on this timer much (if any)more than the plain old vb timer - at least in terms of CONSISTIENCY.


MichaelRed
redmsp@erols.com

There is never time to do it right but there is always time to do it over
 
from what I can gather, I believe that the clock that the computer uses for it's time and timing controls runs at 18Mhz, therefore it's accurracy is limited to 56milliseconds. However - I don't know if you can use the clock cycle of the main CPU to do timings.

Hope this is of some use.

Whatever you doing it sounds difficult.

I use for and next loops for timing - giving me very precise control over the mark-space ratios I use for steper motor control.

Matt

anymore problems - contact me from (webmaster)
 
Many thanks to those of you that looked at this problem. It seems that to get consistent timing precise to the millisecond or less will require an external module. From the tests that I have run it seems that I can get about 99% reliability from the computer to millisecond accuracy so that may be good enough. The absolute time of the event is not all that critical. It is just that some events are happening very close to one another and I need to be able to filter them out. I think I can create some logic that will do this for me within the confines of the system. I am still open for comments if anyone has any ideas, but I am going to stop here and assume this is the limit of the system. Thanks.

Brian Clark
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top