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

Sleep, Time delay, Zen Timer?..in need of time accuracy to 1 ms

Status
Not open for further replies.

marvg007

Programmer
Jan 1, 2001
6
US
Hi, first off, to know why I need precise accuracy in this function, down to the exact millisecond is because I am trying to produce a frequency through my parallel port. Sending frequencies through the port would allow me to make multiple channels in which a robot can communicate with the computer(different frequencies through same pin can mean different commands). I timed the call and return of the _outp()(function to write to the port in VSC++6.0) to be around 1/200,000th of a second. I only need my program to be exact to the 1/1000th of a second so that isn't much of a time consumer. On the other hand, the Sleep(ms) function is a MAJOR time consumer. I can only achieve at most 100Hz doing this:

while(1){

_outp(0x00378, 0x01); //Switch pin 0 to High
Sleep(1);
_outp(0x00378, 0x00); //Switch pin 0 to Low
Sleep(1);
}
The Supposed result should be that it pauses for 1 ms between switching from on to off, meaning that it does a cycle(on off) in 2 ms. This theoretically mean that it would give a frequency of 1000/2 per second or 500Hz.But it gives me 100Hz, 100 cycles a second at most!

and no, I don't think the while loop has anything to do with it since I batch process it, doing it 10 times before repeating a while.(I even experimented with no while, doing it 100 times)

I tried making my own delay function using clock() but the calls to clock() take Significantly longer than the calls to Sleep(). I'm thinking Sleep might be coded in assembly.

I need help finding an assembly written function to be used with C++ or such that might be able to help me make near precise frequencies. I know Micheal Abrash's Zen Timer does some pretty accurate calculations. Can someone show me a way to do this? Thanks!
 
Here's a few things to try:

1. Multimedia timers are pretty good, but I'm not sure if they're this good. Anyway, you can read about them at


2. You might be able to use the QueryPerformanceFrequency and QueryPerformanceCounter functions. See


3. You might want to play some games with increasing the priority of your process. See the documentation for "SetPriorityClass" at


Please note, however, that as the documentation warns you can get into trouble by making your priority too high. And even with a high priority I'm not sure that there's any guarantee that your process won't get preempted and lose control for more than a millisecond in the middle of the operation.
 
Look here:
while(1)
{

_outp(0x00378, 0x01);
//calling a function=lose time on
//calling, executing and returning

Sleep(1);
//lose time on calling
//waiting one millisecond
//lose time on returning

_outp(0x00378, 0x00);
//lose time on
//calling, executing and returning

Sleep(1);
//lose time on calling
//waiting one millisecond
//lose time on returning

}
this is the first problem.
The second:
Sleep(1) sleep not precisely one millisecond. This function is for tens of milliseconds. By the way, Sleep(0) sleep more then one millisesond.
 
Thanks Keith, I'm going to try the Multimedia Timer built into windows..but I'm not sure even it can handle < 10 ms delays. I'll give it a try!

John,Yep, I know the function calls take up quite some time. The _outp function though, takes only 1/200,000 of a second(call and return), I timed it by making it Occillate through the port and measured the resulting Frequency output(number of times it goes off and on in a second). That's why I'm asking for a better sleep function..sleep just doesn't work exactly as it should..
 
One thing I would consider, if you are at all familiar with threads, is put the frequence generator code in a seperate thread, set to time critical priority. Something like this.

Code:
AfxBeginThread(FreqThreadProc, NULL, THREAD_PRIORITY_TIME_CRITICAL);

I have used the QueryPerformanceFrequency and QueryPerformanceCounter functions to determine how long some of my code was running, and I was able to get 1ms resolution.
 

> Sleep(1) sleep not precisely one millisecond. This function is for tens of milliseconds. By
> the way, Sleep(0) sleep more then one millisesond.

Take a look at timeBeginPeriod()
In my tests it lets Sleep(1) be much more precise.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top