Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problems with a millisecond timing routine

0 views
Skip to first unread message

Steve Kenshulo

unread,
Jan 21, 1994, 12:15:52 AM1/21/94
to
I was wondering if someone could take a look at this for me. I connected
some stepper motors to the printer port of a PC, and then wrote this
routine to time the number of milliseconds between pulses (sent to
the stepper motors.) It works most of the time, but sometimes returns
incorrect values. It seems to run better (fewer errors) within the
Turbo C++ IDE (Intergrated Development Environment) than it does from
DOS.

What do you guys think? Below is the source code for the real_ms routine
along with a little program to test it. If it would help anyone, I
could upload the executable to a FTP site.

-----------------------CUT HERE----------------CUT HERE-------------------
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <dos.h>
#include <stdlib.h> /* needed only for rand function */
main()
/*This program is intended to test the real_ms() function,
and nothing more. It is not intended to be usefull. */
{
int a,b,c=0,d=0,e=0,f=0;
while (d<25000)
{
realtime_ms();
/*printf("\nHello!!"); */
b=rand() % 30;
delay(b);
a=realtime_ms();
printf("\nThat took %i millisconds\n",a);
if (a<=b-3)
{
c=c+1;
e=a; /*realtime returned value */
f=b; /*rand value */
}
printf("total errors = %i, total tries %i, rand value = %i\n",c,d,b);
printf("error was %i for realtime value, and %i for rand value\n",e,f);
printf("\n%f\n",CLK_TCK);
d=d+1;
}
}


realtime_ms(void)
/* function deffinition to return the number of milliseconds
since the last time it was called
It has some bugs, and returns a wrong value about 2% of the time.
Written by Steve Kenshalo, sken...@csufresno.edu
*/
{
int unsigned b,lsb,msb,word,c,a;
static int ticker,clocker; /* static preserves value between function calls */
_disable(); /* prevent interrupts between timer calls */
outp(0x43,06); /* 00000110 latch currrent timer value */
lsb=inp(0x40); /* read lsb */
msb=inp(0x40); /* read MSB */
c=clock(); /* NOTE: this function may enable interrupts */
_enable();

a=c-clocker;
if (word>ticker) /* detect wraparound */
--a; /* one of the ticks in a is unneeded */
clocker=c; /*save for next call */

word=(msb*256)+lsb; /* combine msb and lsb into word */
/*word=word*.000838395; /* convert word (ticks) into milliseconds */
b=(0.000838395*(ticker - word))+(a*0.05494505495);

ticker = word; /* save word for next call */
return b;
}

Dick Kressman

unread,
Jan 21, 1994, 5:50:23 AM1/21/94
to
^^^^

> --a; /* one of the ticks in a is unneeded */
> clocker=c; /*save for next call */
>
> word=(msb*256)+lsb; /* combine msb and lsb into word */
> /*word=word*.000838395; /* convert word (ticks) into milliseconds */
> b=(0.000838395*(ticker - word))+(a*0.05494505495);
>
> ticker = word; /* save word for next call */
> return b;
> }

--

You reference variable "word" before any assignment - a sure route
to tears!

Secondly, I haven't looked at the algorithm in detail, but I'm very
suspicious of that floating point stuff - I would expect it to
produce rounding errors at best. Better do it all in (long?) integer
arithmetic (and faster!).

Finally, it wouldn't surprise me if the clock() function (or
the time-of-day service called by clock()) had differential
errors due to rounding - I don't think it's really intended for this
level of precision. Also, clock() is typed as clock_t in MSC - isn't
that actually a long? (You assign it to an unsigned int, i.e., short
in MSC - I can't speak for Turbo. I might expect this to result in
wrap-around every 65536/18.2 seconds, i.e., about once per hour).

Hope that gives some food for thought.

Dick.

-----------------------------------------------------
As an economy measure, the light at the end of the
tunnel will be switched off while the recession lasts.
-----------------------------------------------------

Carle

unread,
Jan 26, 1994, 9:46:00 PM1/26/94
to
In article <CJyry...@zimmer.CSUFresno.EDU>, sken...@mondrian.CSUFresno.EDU (Steve Kenshulo) writes...

If I remember correctly, the timer resets to zero every time it gets
to the count required to trigger the interrupt. On that basis you
would need to forget the previous value and just offset the
regular time value.

/*------------------------+---------------------------------------
| Carle C. Henson | Opinions expressed are my own and may
| Hughes Network Systems | not be shared by anyone else on the
| hen...@lando.hns.com | planet, even if I am right. The
| Voice (301) 428-5917 | possible exception being Rush Limbaugh
| Fax (301) 428-1868 | who is always right.
+-------------------------+-------------------------------------*/

0 new messages