Page 1 of 1

Timing

Posted: 05 March 2007, 8:52 AM
by hacktorious
How much time should I generally allow for code overhead? For example, the following code in a BS2 would run for 4.6 seconds. Thus, turning the servo for 4.6sec.
One time through the loop = 1.7 ms + 20 ms + 1.3 ms = 23.0 ms.

FOR counter = 1 TO 200
PULSOUT 13, 850
PAUSE 20
NEXT

Parallax recommends 1.3ms code overhead for this loop.

The same code written in Zbasic is as follows:

For counter = 1 TO 200
Call PulseOut(A.2,0.0017,1)
Call PulseOut(0,0.020,0)
Next counter

The problem is that the ZX-24a executes commands much faster than the BS2 and I am not certain how to determine code overhead. Thanks.

Re: Timing

Posted: 05 March 2007, 9:17 AM
by dkinzer
hacktorious wrote:How much time should I generally allow for code overhead?
There is no published data on the execution time for various instructions and combinations thereof.
hacktorious wrote:The problem is that the ZX-24a executes commands much faster than the BS2 and I am not certain how to determine code overhead.
There are several ways to measure the execution time of code. The first method requires an oscilloscope, logic analyzer or frequency counter. The general idea is to create a loop like that shown below. When run, this code will generate a square wave on pin C.0 whose period is twice the execution time of the loop. Once you know the execution time of this test loop, you can add to the loop any instructions that you would like to time. Again, the period of the signal on C.0 will be twice the time to required to execute the loop and the difference will be attributable to the added instructions.

Code: Select all

Call PutPin(C.0, 0)
Do
  Register.PortC = Register.PortC Xor 1
Loop
If you don't have frequency measuring equipment, you can use the ZX real time clock to measure the time. Consider the following code:

Code: Select all

Dim t0 as Single, t1 as Single
t0 = Timer()
For counter = 1 TO 200
   Call PulseOut(A.2,0.0017,1)
   Call PulseOut(0,0.020,0)
Next counter
t1 = Timer()
Debug.Print "Elapsed time: "; Fmt((t1 - t0) * 1000.0, 3); "mS"
Depending on the actual elapsed time you may want to adjust the scaling to display the time in seconds or microseconds.

This method will not be accurate if the execution time being measured is not substantially larger than the time required to execute Timer() twice. For those cases, you could measure that "overhead" time first and then subtract it from the execution time during the test run.

A third alternative is to use a stopwatch or sweep second hand to measure execution time. Because human response time is relatively slow, you will typically have to execute the test code hundreds or thousands of times in a loop and then divide the measured time by the iteration count.

Posted: 05 March 2007, 9:41 AM
by GTBecker
BXTiming.zip, on the BX-24 Yahoo group, is useful, too.

Posted: 05 March 2007, 10:00 AM
by hacktorious
OK, great. I like the sound of the solution with the Timer(). I have noticed many commands have a resolution time. I am new to this stuff and not sure what that means. What exactly is a resolution time and how will it affect my code?

Posted: 05 March 2007, 10:14 AM
by dkinzer
hacktorious wrote:What exactly is a resolution time and how will it affect my code?
The resolution associated with any measured or specified quantity indicates how precisely the value is quantified. If a 1mS resolution is specified then you know that 1mS is the most precisision you can get - don't expect to measure or specify 1.5mS for example if a 1mS resolution is indicated.

In the descriptions of ZBasic System Library routines, the resolution is most often associated with use of a Single value. For example, with the PulseOut() routine, you may specify the pulse duration using a Single value and the resolution is specified as 1.085uS. It will do no good to try to specify the pulse width as 1e-9 (1nS) for example because the resolution is limited to 1.085uS. Moreover, if you specify the pulse duration as 2.5e-6 (2.5uS) you're going to get a pulse of approximately 2.17uS, the nearest integral multiple of 1.085uS.