How to "Wait" in Millisecond intervals

Example scripts and tips (replaces Old Scripts & Tips archive)

Moderators: Dorian (MJT support), JRL, Phil Pendlebury

Post Reply
User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

How to "Wait" in Millisecond intervals

Post by JRL » Wed Jun 17, 2020 7:33 pm

The Macro Scheduler Wait> function can be told to pause for a time interval as small as 0.001 seconds (one millisecond) However, the Wait> function can't actually pause for a time interval smaller than about 16 milliseconds. In other words you can type into your script "Wait>0.001", but the time the script pauses will not be 1 millisecond it will actually be 16 milliseconds, or more accurately 1/64th of a second which is 15.625 milliseconds.

If you truely need to wait for a time interval in milliseconds, you can instead use the Windows API "Sleep" function. "LibFunc>Kernel32,Sleep,Sres,1" will cause a Macro Scheduler script to pause for 1 millisecond.

The following script is a proof of this statement. The script will initially run 100 cycles of a Wait> function that starts at 1 millisecond then will increment upward at 1 millisecond intervals. The timed results of each 100 cycle loop will display in a message box. You will see that every 1 millisecond increment will run 100 Wait> cycles in about 1600 milliseconds until you reach a 16 millisecond pause at which point each loop of 100 Wait> cycles will take about 3200 milliseconds. When you reach 32 milliseconds per pause the 100 cycles loop time will take about 4500 milliseconds. Etc.

When you close the message box the script will move on to perform the same process but will use Windows API Sleep rather than Wait. As you watch the Sleep function pause time increment you will also see that the 100 cycle loop time increments as well. This indicates that the Windows API Sleep function actually pauses the script in millisecond increments.

Code: Select all

Message>Waiting...
Let>vWTime=0.000
Let>vContinue=1

While>vContinue=1
  Let>vWTime=%vWTime%+0.001
  GoSub>TimeOut
  IfWindowOpen>Macro Scheduler Message
  Else
    Let>vContinue=0
  EndIf
EndWhile

SRT>TimeOut
  Timer>vStartTime
  Let>kk=0
  Repeat>kk
    Add>kk,1
    Wait>vWTime
  Until>kk=100
  Timer>vEndTime
  Let>vTime=%vEndTime%-%vStartTime%
  SetControlText>Macro Scheduler Message,TMemo,1,Wait Time = %vWTime% seconds%crlf%100 cycles took %vTime% miliseconds
END>TimeOut


Message>Waiting...
Let>vWTime=0
Let>vContinue=1

While>vContinue=1
  Let>vWTime=%vWTime%+1
  GoSub>APITimeOut
  IfWindowOpen>Macro Scheduler Message
  Else
    Let>vContinue=0
  EndIf
EndWhile

SRT>APITimeOut
  Timer>vStartTime
  Let>kk=0
  Repeat>kk
    Add>kk,1
    LibFunc>Kernel32,Sleep,Sres,vWTime
  Until>kk=100
  Timer>vEndTime
  Let>vTime=%vEndTime%-%vStartTime%
  SetControlText>Macro Scheduler Message,TMemo,1,Sleep Time = %vWTime% milliseconds%crlf%100 cycles took %vTime% miliseconds
END>APITimeOut

User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Re: How to "Wait" in Millisecond intervals

Post by JRL » Thu Jun 02, 2022 5:28 pm

Posted this info 2 years ago and its had, at this moment, 7580 views. Today I discovered a mistake. 7575 of those viewers think I'm an idiot. (I'm guessing 5 viewers got here by mistake and didn't read it.) If you run the posted code there's a chance you'll see what I said you'd see. There's also a chance both loops will display the exact same information. The concept is still correct but while working on Puzzler #13 yesterday, I found and read this page about multimedia timing on Windows computers. There is also a link to this page about the timeBeginPeriod API function that can be used to control a computers timer. As used below it assures that the sleep API function resolves time to milliseconds rather than to 1/64 of a second (15.625 milliseconds) which is Windows normal timing. As I've been experimenting with Puzzler #13 I've discovered that some computers finest time resolution is 1/64 of a second but others for reasons I've yet to discover can actually resolve one millisecond.

The script below is the script above with four lines added:
LibFunc>Winmm,timeBeginPeriod,vResB,1 and LibFunc>Winmm,timeEndPeriod,vResE,1
were each added to the two subroutines to allow the timers to resolve one millisecond timing if they are capable. The result is still the same as reported above but now, perhaps, more computers will run the script and display the results properly.

Note: If you use timeBeginPeriod in a script you are "required" to also use timeEndPeriod. I don't know for certain the consequences if you fail to use timeEndPeriod but I'm afraid to exclude it and find out. I think it may set your computer to continuously time at one millisecond intervals. This apparently leads to high CPU usage.

Code: Select all

Message>Waiting...
Let>vWTime=0.000
Let>vContinue=1
While>vContinue=1
  Let>vWTime=%vWTime%+0.001
  GoSub>TimeOut
  IfWindowOpen>Macro Scheduler Message
  Else
    Let>vContinue=0
  EndIf
EndWhile

SRT>TimeOut
  Timer>vStartTime
  Let>kk=0
  Repeat>kk
    Add>kk,1
    LibFunc>Winmm,timeBeginPeriod,vResB,1
      Wait>vWTime
    LibFunc>Winmm,timeEndPeriod,vResE,1
  Until>kk=100
  Timer>vEndTime
  Let>vTime=%vEndTime%-%vStartTime%
  SetControlText>Macro Scheduler Message,TMemo,1,Wait Time = %vWTime% seconds%crlf%100 cycles took %vTime% miliseconds
END>TimeOut

Message>Waiting...
Let>vWTime=0
Let>vContinue=1
While>vContinue=1
  Let>vWTime=%vWTime%+1
  GoSub>APITimeOut
  IfWindowOpen>Macro Scheduler Message
  Else
    Let>vContinue=0
  EndIf
EndWhile

SRT>APITimeOut
  Timer>vStartTime
  Let>kk=0
  Repeat>kk
    Add>kk,1
    LibFunc>Winmm,timeBeginPeriod,vResB,1
      LibFunc>Kernel32,Sleep,Sres,vWTime
    LibFunc>Winmm,timeEndPeriod,vResE,1
  Until>kk=100
  Timer>vEndTime
  Let>vTime=%vEndTime%-%vStartTime%
  SetControlText>Macro Scheduler Message,TMemo,1,Sleep Time = %vWTime% milliseconds%crlf%100 cycles took %vTime% miliseconds
END>APITimeOut

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts