• C

Loop each Second

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.
gianiaAsked:
Who is Participating?
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
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
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
Hi giania,

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


Kent
0
 
mokuleCommented:
IMHO
sleep(1000)
BTW what OS are You using
0
Identify and Prevent Potential Cyber-threats

Become the white hat who helps safeguard our interconnected world. Transform your career future by earning your MS in Cybersecurity. WGU’s MSCSIA degree program was designed in collaboration with national intelligence organizations and IT industry leaders.

 
Kent OlsenData Warehouse Architect / DBACommented:
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
 
xassetsConnect With a Mentor Commented:
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
 
mokuleCommented:
In Windows more precise is

QueryPerformanceCounter
0
 
xassetsCommented:
Agreed much. Query Performance counter is very accurate, whereas my proposition would have been maybe 1% to 5% out
0
 
ankuratvbCommented:
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
 
Avik DasguptaCommented:
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
 
gianiaAuthor Commented:
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
 
ankuratvbConnect With a Mentor Commented:
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
 
ankuratvbCommented:
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
 
gianiaAuthor Commented:
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
 
gianiaAuthor Commented:
Thanks ankuratvb, how do i do that. I'm an electronic engineer not a programmer and ,thus, only know the basic functions
0
 
gianiaAuthor Commented:
P.S i've upped the points
0
 
mokuleConnect With a Mentor Commented:
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
 
Kent OlsenData Warehouse Architect / DBACommented:
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
 
xassetsCommented:
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
 
gianiaAuthor Commented:
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
 
xassetsCommented:
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
 
xassetsCommented:
oops I missed out resetting dbllastsecond whenever you measure,

inside the if do

dbllastsecond = gettime();
0
 
ankuratvbCommented:
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
 
xassetsCommented:
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
 
gianiaAuthor Commented:
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
 
gianiaAuthor Commented:
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
 
gianiaAuthor Commented:
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
 
xassetsConnect With a Mentor Commented:
OK, QueryPerformanceCounter does work on Win95.
0
 
gianiaAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.