Simpler way to time an action in a loop?

Hello,
One way to time code is to make the following if-statement, shown in the code-snippet:

1
2
3
4
 If(currentTime - previousTime > intervall) 
{
 // do something
}


My problem was that i wanted the previousTime to start after an additional action. Best i describe it at my currently working code:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <time.h>
#include <iostream>
using namespace std;

clock_t previousClock = 0;
clock_t currentMillis = 0;
clock_t previousMillis = 0;

int durration = 5000;										// 5 seconds
int counter = 0;
string input;

void turnOff(string inputString)
{
	while (true)
	{
		if (clock() >= 10000+previousClock)					       // brake after 10 seconds
		{
			previousClock = clock();
			break;
		}

		currentMillis = clock();

		if (inputString == "ON")
		{
			if (counter == 0)
			{
				previousMillis = clock();					// get once everytime "inputString" is set to "ON"
				counter++;
			}

			if (currentMillis - previousMillis > durration)	                       // do after 5 seconds
			{
				inputString = "OFF";
				previousMillis = currentMillis;
				counter = 0;
			}
		}

		cout << inputString << endl;
	}
}

int main()
{
	input = "OFF";
	turnOff(input);
	cout << "******************" << endl;

	input = "ON";
	turnOff(input);
	cout << "******************" << endl;

	input = "OFF";
	turnOff(input);
	cout << "******************" << endl;

	input = "ON";
	turnOff(input);
	cout << "******************" << endl;

	return 0;
}


I have a string called input, which is either "OFF" or "ON". This string is given to the function turnOff as a parameter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
	input = "OFF";
	turnOff(input);
	cout << "******************" << endl;

	input = "ON";
	turnOff(input);
	cout << "******************" << endl;

	input = "OFF";
	turnOff(input);
	cout << "******************" << endl;

	input = "ON";
	turnOff(input);
	cout << "******************" << endl;

	return 0;
}


This function should output this string for 10 seconds. But after the durration (here 5 seconds) the string is "overwriten" to "OFF".
For this i used an additional variable called counter. It helps that the previousTime only gets updatet once every loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (inputString == "ON")
		{
			if (counter == 0)
			{
				previousMillis = clock();			// get once everytime "inputString" is set to "ON"
				counter++;
			}

			if (currentMillis - previousMillis > durration)         // do after 5 second
			{
				inputString = "OFF";
				previousMillis = currentMillis;
				counter = 0;
			}
		}

Without counter, the previousTime is updatet every loop and is then equal to CurrentMillis so the if-statement is always false.
I dont know but is there a better way to solve this problem?
Last edited on
you can rearrange it but the mechanics are the same (you can stuff it into an object, or hide it in a finite state machine, etc, but it will do the same things).

if you want to have a second event within a time window of a first event, you have to track all the bits. you can get the now-time vs the first event time and check that BOTH events are set, but at a minimum you need to know {the starting time of the first event, that the first event happened, and that the second event happened} along with the fixed data (how long the time window is, whatever else) and it has to handle repeated first events followed by a second event (and beyond that, do you allow complexity like E1a, E1b, E2a, E2b pattern that correctly matches first and second events together somehow... If you need to match the complexity you need more info of some sort or an algorithm for it.


Last edited on
This has similarities with Arduino stuff. (cf Arduino 'Debounce' ).
But it's not all that clear what you are trying to do. However here is a simplified rendition of what it might be about and the possibility of extending it.

It turns ON for the duration then turns OFF, and vice versa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <time.h> // OR <chrono> BETTER
#include <iostream>

using namespace std;

clock_t previousClock = 0;
clock_t currentMillis = 0;
clock_t previousMillis = 0;

int duration = 1000000; // <-- CALIBRATE TO SUIT - BETTER TO USE <chrono>
int counter = 0;
string input[]{"ON", "OFF"};
bool state {0};


void show_status()
{
    currentMillis = clock();

    cout << input[state];
    state = !state;
    while( clock() - currentMillis < duration )
    {

    }
    cout << "\t-> " << input[state] << endl;
}

void turn_ON(){ state = 1; show_status();}
void turn_OFF(){ state = 0; show_status();}

int main()
{
    turn_ON();
    turn_OFF();
    turn_ON();
    turn_ON();
    turn_OFF();

    return 0;
}
@againtry
It turns ON for the duration then turns OFF, and vice versa.

I want something to be turned ON, but only for a speficic durration. If its not "ON", the code just "scips" this part and goes to the next event, which might be turned "ON" for some specific time. But for that i need that Variable counter, to not go every loop though the following:
previousMillis = clock();.

@jonnin
you can rearrange it but the mechanics are the same (you can stuff it into an object, or hide it in a finite state machine, etc, but it will do the same things).
Ok, so there is not a completly different approach.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <chrono>
#include <iostream>

using namespace std;

clock_t previousClock = 0;
clock_t currentMillis = 0;
clock_t previousMillis = 0;


int duration = 10000000; // <-- CALIBRATE TO SUIT - BETTER TO USE <chrono>
int counter = 0;
string input[]{"OFF", "ON"};
bool state {0};


void show_status()
{
    currentMillis = clock();
    cout << input[state];
    if(state == 1)
    {
        while( clock() - currentMillis < duration )
        {

        }
        state = !state;
    }
    cout << "\t-> " << input[state] << endl;
}

void turn_ON(){ state = 1; show_status();}
void turn_OFF(){ state = 0; show_status();}

int main()
{
    turn_ON();
    turn_OFF();
    turn_ON();
    turn_ON();
    turn_OFF();

    return 0;
}
Topic archived. No new replies allowed.