1

I want to execute 2 different output at a certain time in seconds, one after another. And change the swap time using keyEvent. Here's the idea.

[Every 10 seconds]
1 2 3 4 5 6 7 8 9 (10) 11 12 13 14 15 16 17 18 19 (20)  (→ second-from timer lib.)
Display Output 1 = 1-10 second
Display Output 2 = 11-20 second, (then Output 1 again, etc)

[Every 5 seconds]
1 2 3 4 (5) 6 7 8 9 (10) 11 12 13 14 (15) 16 17 18 19 (20)(→ second-from timer lib.)
Display Output 1 = 1-5 second
Display Output 2 = 6-10 second
Display Output 1 = 11-15 second, (then Output 2 again, etc)

I've been looking for question, like Timed C Program Loop and How to use seconds (time) in C program as a counter? and I only find those with timer and clock_t. I don't plan to use timer and clock since I already use a utilTimer library to return amount of seconds in realtime. Here's the my keyEvent code :

if (key == '1' ) {
    delay=10;
}
if (key == '2' ) {
    delay=5;
}
if (key == '3' ) {
    delay=3;
}
if (key == '4' ) {
    delay=1;
}

How do I implement the time loop ? As of now for the looping I'm using mod, but using mod the output is only executed once when the value meets mod. Also it's difficult to set the maximum value of the loop since I'm running realtime. So I'm still a little bit confused and haven't achieved my goal.

for (int count = 0; true; count++) {
    if (count % delay == 0) {
        //push output 1 every defined delay - in seconds
    }
    else {
        //push another output
    }
}

Any advice ?

[EDIT]

I'm running a simple C program on Mac. Basically what I want to do is I want to push an output in this case a string output and an image, so after several seconds the string and image will change, repeatedly. And I want to be able to control the changing frequency using key.

raisa_
  • 594
  • 2
  • 10
  • 28
  • Your question don't make any sense, what do you really want and why are you talking about not use `clock_t` or `timer` (???), also what is your "utilTimer" ? Please read [ask]. Try to include a [mcve] with an exemple of your use of "ulitTimer" – Stargateur Oct 14 '18 at 02:48
  • Telling us about what you are trying to accomplish *overall* would be really helpful to us in our desire to help you. Are you running linux? When running an ordinary linux, timing things via loops will never be accurate. Your process will be suspended by the scheduler at unpredictable times. – Leonard Oct 14 '18 at 04:10
  • You simply need to get time at subsecond accuracy, and use that instead of count. Also better have eg. 10ms sleep in your loop to avoid hogging all CPU. – hyde Oct 14 '18 at 06:04
  • Also have variable for the time you need to do something. Then when that time becomes *less than* current time do that something and increase the variable by interval. Don't use mod like that, it's needlessly complex. – hyde Oct 14 '18 at 06:07
  • @Leonard I understand, I've tried my best to make my question as clear as possible. I've updated my question. Thanks – raisa_ Oct 14 '18 at 13:19

2 Answers2

1

You need to keep track of the last time you changed the image and string. Then you subtract the last time from the current time, and if the difference is more than the delay, you output a new image and string, then update the last time variable to the current time.

If you use unsigned values for the timers, you will not have trouble with rollover (which would be overflow for signed integers, and cause undefined behavior).

unsigned now;        // from your timer
unsigned last_event; // the last time you sent stuff out
unsigned delay;      // the time between output events

while (1)
{
    if ((now - last_event) >= delay)
    {
        // send out your string and image
        last_event = now;
    }
    else
    {
        // keep waiting, and do whatever else you want
        // update now as appropriate from timer
    }
}

My use of a while (1) above is intended to convey the idea that the code inside the while loop is executed frequently. This needn't, and probably wouldn't be a while loop in practice. It would probably be

  • A piece of a "superloop" in an embedded application
  • Inside an RTOS task
  • Inside a big OS thread
  • In a game program's "frame" call
  • Etc.
Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • Thank you, also for explanation ! Unfortunately I'm having issue with infinite loop from the while(1) causing my program not responding. But this is the answer that I need. Thanks again. – raisa_ Oct 14 '18 at 16:20
  • Also I have another question, let's say for 5 seconds time loop. What if I don't hit any key for a long time ? the last_event will stay the same, and finally my "now" value will always be more than last_event, so output never change. Would you please take a look at this https://i.imgur.com/otwmBwH.jpg – raisa_ Oct 14 '18 at 17:54
  • Since `last_event` is set every time the delay expires, there will be an event every `delay` seconds forever (as long as `now` continues to increment). In your whiteboard picture, you need to set `last_event` at time 10. – Doug Currie Oct 14 '18 at 19:01
  • I understand. Thank you. About the infinite while loop, even after I put sleep function on the second condition (else) and scanf() in the first condition (if) as a blocking mechanism, I'm still having infinite loop and my program isn't responding (just black screen). Any advice ? – raisa_ Oct 15 '18 at 01:24
  • See my updated answer that elaborates the purpose of `while (1)`, which would not normally be used in practice. – Doug Currie Oct 15 '18 at 13:58
  • I understand this is not the best approach for my program as well. Thank you. – raisa_ Oct 16 '18 at 03:56
0

If I understand the question right, you can use sleep in a for loop. Its in unistd.h library.

#include unistd.h
for (int count = 0; true; count++) {
    sleep(1000); //sleep for 1 second
    if (count % 10 == 0) {
    //every 10 seconds
    }
    if (count % 5 == 0) {
    //every 5 seconds
    }
}
jahneff
  • 73
  • 1
  • 5
  • Hi, thanks. I tried using sleep as you suggested. Unfortunately, it takes too long, it's lagging and most of the time causing my program not responding. I notice the sleep time is actually longer than I had defined. Also, sleep function will 'sleep' my program temporarily, my counting timer will be stopped too when sleep is happening. I need this in realtime. So, the counter needs to count normally in realtime and the output swap every specific time. Any other advice ? – raisa_ Oct 14 '18 at 01:54
  • Consider to use function getrusage(). It measures user cpu time and system cpu time – manoliar Oct 15 '18 at 11:05