Solved

Loop each Second

Posted on 2004-03-26
28
384 Views
Last Modified: 2010-04-15
Hi

I'm trying to write a piece of code that will loop every second over a defined time range. I know how to get the time in seconds since 1/1/70 from the help pages but I dont know how to get it to loop every second for say, 5 seconds. If I can get it to print the time every second over 5 seconds I can incorporate it into my main code which will allow a user to ramp the power dissipated in a light bulb over a defined range in a defined time.

Any ideas???

here is the code for displaying the time in seconds since 1/1/70;

#include <time.h>
#include <stdio.h>

void main()
{
time_t ltime;

time( &ltime );
printf( "Time in seconds since UTC 1/1/70:\t%ld\n", ltime );
}


Thanks.
0
Comment
Question by:giania
  • 9
  • 7
  • 4
  • +3
28 Comments
 
LVL 45

Assisted Solution

by:Kdo
Kdo earned 195 total points
ID: 10690102
Hi giania,

sleep (1) should delay you for a second.  Just put that in your loop.


Kent
0
 
LVL 17

Expert Comment

by:mokule
ID: 10691080
IMHO
sleep(1000)
BTW what OS are You using
0
 
LVL 45

Expert Comment

by:Kdo
ID: 10691110
Hi mokule,

sleep() does vary between implementations.  On linux systems the parameter is the integral number of seconds to sleep.  Some windows systems have a nearly identical function called Sleep() (with a capital 'S').  As I recall, the parameter to this function is microseconds.


Kent
0
 
LVL 4

Assisted Solution

by:xassets
xassets earned 75 total points
ID: 10691168
Sleep is milliseconds in windows.

If you're using windows...

If you're not bothered about CPU usage then you can saturate the CPU with a do loop which calls out to a function every one second. Just inspect the SystemTime:

      SYSTEMTIME stime;
      GetSystemTime(&stime);

and call it every time stime.wSecond changes. You could call sleep every 10ms or so for the first 0.97 seconds if you want to be cpu friendly !

0
 
LVL 17

Expert Comment

by:mokule
ID: 10691270
In Windows more precise is

QueryPerformanceCounter
0
 
LVL 4

Expert Comment

by:xassets
ID: 10691480
Agreed much. Query Performance counter is very accurate, whereas my proposition would have been maybe 1% to 5% out
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10692702
Shouldnt the sleep() or delay() amount be slightly less than 1000 msec.Thats because the
rest of the code in the loop will also take some amount of time to execute.
0
 
LVL 2

Expert Comment

by:Avik77
ID: 10693950
I feel if there are no iterative or complex conditional logic within the loop then amount of time for the rest of the code is negligible compared to the delay() or sleep(). Anyway I am just assuming his code within the loop to be consisting only of sequential logic and calling no functions or interrupt call from within.

Avik.
0
 

Author Comment

by:giania
ID: 10694233
Thanks all for your replys.

As ankuratvb says, the rest of the code may take 0.5 seconds to readjust the power in the bulb therefore if i use the sleep command it will pause for 1.5 seconds which is no good. in fact there is no way i can time and adjust the sleep value as it takes different amounts of time to readjust the power at different values.

The code does call other functions and provides the data to a DAC and then to an analogue circuit which controls the power in the bulb it then measures the data value from an ADC and compares then readjusts, and it can take a 'long' time (0.5sec).

So what i need to do is, pause the code until the UTC time changes from, say, 10000000 seconds to 10000001 seconds and then resume. I have some code that prints the value constantly but it does not wait until the time changes.

Alde
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 60 total points
ID: 10694254
Hi,

This can be achieved as follows:

1. Store the time at the beginning of the loop.
2. Execute the other Statements in the loop.
3. Now Keep polling the time till it reaches the next second i.e. keep checking the time
till the clock ticks over to the next second.

This will give u an accurate pause of 1 second.
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10694260
Step 3 means keep checking the time in a loop and the loop will terminate when the
time ticks over to the next second
0
 

Author Comment

by:giania
ID: 10694271
Sorry, it is Windows im using, the program only works under the DOS based versions since i have to output/input through the parallel port, ports 379h and 378h using _inp and _outp, everything else in the code works.
0
 

Author Comment

by:giania
ID: 10694281
Thanks ankuratvb, how do i do that. I'm an electronic engineer not a programmer and ,thus, only know the basic functions
0
 

Author Comment

by:giania
ID: 10694296
P.S i've upped the points
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 17

Assisted Solution

by:mokule
mokule earned 20 total points
ID: 10694495
May be You can try like this

{
  _LARGE_INTEGER freq, tb,te;
  if(QueryPerformanceFrequency(&freq))
    {
    QueryPerformanceCounter(&tb);
  /*
   time consuming operations
  */
    do
      QueryPerformanceCounter(&te);
    while ((te -tb)/freq < 1); /* test for 1 sec */
    }
  else
    /* Sorry QueryPerformanceCounter not supported*/
    ;
}
0
 
LVL 45

Expert Comment

by:Kdo
ID: 10694676
Hi All,

You can do the same with the clock() function

#include <time.h>

void WaitOneSecond ()
{
  clock_t  BaseTime;

  BaseTime = clock ();
  while (clock () - BaseTime < CLK_TCK);

  return;
}

Kent
0
 
LVL 4

Expert Comment

by:xassets
ID: 10694809
I think clock() suffers from the same inaccuracies as GetSystemTime() ??

From the question this sounds like a scientific project so you'd want it to be accurate ?
0
 

Author Comment

by:giania
ID: 10695181
Thanks xassets that's exactly what it is. Here is what i have so far;

#include <time.h>
#include <stdio.h>
void main()
{
      time_t start_time;
      time_t end_time;
      time(&start_time);
      start_time += 5;
      time(&end_time);
      while (start_time >= end_time)
    {       
            printf("Time in seconds since UTC 1/1/70:\t%ld\n",end_time);
            time(&end_time);
    }
}
However, i don't know how i can control the loop. This program prints the value of the UTC in seconds constantly over five seconds but i need it to pause until the second value increments then print. I am just saying print because once i get it to do that it will be no problem to adopt it for my purpose.

I do need accuracy. i have tried the _sleep function and the one from kido (thanks) but yes that does suffer in the same way the sleep function suffers.

0
 
LVL 4

Expert Comment

by:xassets
ID: 10695234
OK well QueryPerformanceCounter will be available on a 32bit windows compiler like msvc so the bit of code that mokule put up should be a good starting point. I think you need to convert the large ints into doubles though, but thats something you need to debug through.

Logically:

dblsecond = gettime()
dbllastsecond = lsecond

while (dblsecond < targettime)
{
    dblsecond = gettime()
    if (dblsecond >= 5 + dbllastsecond )  // measure every 5 seconds
    {
        measurelightbulb();
    }
}

So I would say you need to get it compiling with QueryPerformanceCounter wrapped in a function (gettime()) which returns a double representing the number of elapsed seconds. Then write the above login (in C!) and that should be it.

Please share points fairly
0
 
LVL 4

Expert Comment

by:xassets
ID: 10695241
oops I missed out resetting dbllastsecond whenever you measure,

inside the if do

dbllastsecond = gettime();
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10695259
I was also thinking along the clock() function as Kent pointed out but according to
people above,it suffers from some inaccuracies.Basically,u need to follow the procedure
as per my previous post and just find a function accurate enough for ur purpose.

I'll try to find one out.
0
 
LVL 4

Expert Comment

by:xassets
ID: 10695288
Whats wrong with QueryPerformanceCounter ? I know you're running it in dos but thats still available on any windows command prompt session ??? or is this win 3.1?
0
 
LVL 45

Accepted Solution

by:
Kdo earned 195 total points
ID: 10695320
Hi giania,

Modifying your program just a bit.....

#include <time.h>
#include <stdio.h>
void main()
{
     time_t start_time;
     time_t end_time;
     time(&start_time);
     start_time += 5;
     time(&end_time);
     printf("Time in seconds since UTC 1/1/70:\t%ld\n",end_time);
     while (start_time >= end_time)
         time(&end_time);
     printf("Time in seconds since UTC 1/1/70:\t%ld\n",end_time);
}

This will give you a 5-second delay, but this method is even more inaccurate than the one I'd posted.  In my version, the value of CLK_TCK is your granularity.  In the version here, the granularity is almost one second, the average accuracy is 1/2 second, and the error between two random times could be nearly two seconds.  

Select any starting time.  You won't know any closer than one second because time() returns the current second.  If the time is 12.01.10.000, you've hit the time exactly on the microsecond.  If the time is 12.01.10.999 you're on the last tick of the microsecond.  Continually calling time() and waiting for the second to click off means that you'll wait anywhere from 1 call to 1 second.

Your program could calculate the number of time() calls that can be executed in one second and use this as your timer, but this has its own inaccuracies as other tasks in the system could be sharing the CPU which means you'll delay more than one second.


Kent

0
 

Author Comment

by:giania
ID: 10695532
modifyed your program a little and yes i see what you mean;

#include <time.h>
#include <stdio.h>
void main()
{
int i, time_one, delay;
                 time_t start_time;
       printf("\nPlease enter the delay in seconds:> ");
       scanf("%d", &delay);
       time(&start_time);
       time_one=start_time+1;
       for(i=0;i<delay;i++)
       {
            printf("Time in seconds since UTC 1/1/70:\t%ld\n",time_one);
            do
             {
                  time(&start_time);
             }while (start_time != time_one);
             time_one+=1;
         time(&start_time);
       }
}
0
 

Author Comment

by:giania
ID: 10695533
modifyed your program a little and yes i see what you mean;

#include <time.h>
#include <stdio.h>
void main()
{
int i, time_one, delay;
                 time_t start_time;
       printf("\nPlease enter the delay in seconds:> ");
       scanf("%d", &delay);
       time(&start_time);
       time_one=start_time+1;
       for(i=0;i<delay;i++)
       {
            printf("Time in seconds since UTC 1/1/70:\t%ld\n",time_one);
            do
             {
                  time(&start_time);
             }while (start_time != time_one);
             time_one+=1;
         time(&start_time);
       }
}
0
 

Author Comment

by:giania
ID: 10695579
oops i pressed tab on my keyboard and it went up twice and i wasn't even finished yet.

Yeah so modifyed your program and i see that  doing it this way there is the error margin. If it gets the time at 6.95 seconds it only recognises it as 6 seconds and then prints again at the 7 second mark which is only a delay of 0.05 seconds.

Does anyone know if i can extract the millisecond data without modifying too much was has been done already?

xassets yeah, see in my house i use win2k and the circuit/program is tested on win95. I overcome all the limitations by disabling the _outp and _inp when i am at home and just put in false values for the get_serial_data() function. Its ok i know how to modify it back to the required source. So i need to write this program that it works on both the operating systems. I know it's not the best way but it is the way it has to be done. I had partitioned my HDD so i could have 95/98 on my home system but bought new HDD and never bothered reinstalling it. The queryfunction does not work on my home PC.

Aslo Xassets your point about the points in duly noted and i will share accordingly, once i get this resolved. I have also increased them slightly.
0
 
LVL 4

Assisted Solution

by:xassets
xassets earned 75 total points
ID: 10695596
OK, QueryPerformanceCounter does work on Win95.
0
 

Author Comment

by:giania
ID: 10695692
Thanks all i've done it. What i have done is put in another small delay, i.e. if the start time is 6.75 seconds it will delay till 7 seconds then it will start ramping the power, it will be ok as long as it indicates when it is ramping from. This way it waits until (hopefully) 7.000 seconds before it executes. here is the code;

#include <time.h>
#include <stdio.h>
void main()
{
      int i, time_one, delay;

    time_t start_time;
      printf("\nPlease enter the delay in seconds:> ");
      scanf("%d", &delay);
      time(&start_time);
      time_one=start_time+1;
      do
      {
            time(&start_time);
      }while (start_time != time_one);

      printf("\nNOW RAMPING POWER....\n\n");
      time_one+=1;
      for(i=0;i<=delay;i++)
      {      
            printf("The power is ? at %d seconds\n",i);
            while (start_time != time_one)
            {
                  time(&start_time);
            }
            time_one+=1;
            time(&start_time);
      }
}

Thanks again all. I have distributed the points in terms of comments and contribution to this piece of code.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now