Count how many times an IF statement has been run per hour

Hi,

I need to count how many times an IF statement is being run per hour.
At the end of the hour, the counter need to be reset to 0 (zero).

It is far above my knowledge within programming.

Can anybody assist me in resolving this, please?

EDIT:
Sorry, my bad. I run an ESP32 Wroom-32.
The count +1 is the easy one (as mentioned in a post below) but calculating when the hour has passed...

Code:

  if (amountDelay.justFinished()) { 
    scale.power_up();
    float weight0 = scale.get_units(10);
    ThingSpeak.setField(2, weight0);
      if (weight0 > THRESHOLD_AMOUNT) {
        sendSMTP();
      }
    scale.power_down();  
    amountDelay.repeat();
	if (client.connect(thingspeakServer,80)) {  
	  int x = ThingSpeak.writeFields(myChannelNumber, apiKey);
  }
  client.stop();
  }

Every time you execute the IF statement, increment a counter by 1.

When the hour has expired, reset the counter to 0. The question is how do you detect the hour has passed and that depends on the hardware you have, which has not been mentioned.

Please post the code with the if statement in that you wish to count

Sorry guys, of course I should have posted both the hardware and code IF statement. I've edited the original post. Thx for your patience with me...

It looks like you don't have a real time clock.

So the easiest wat to count an hour is to use the millis() counter to get (very) close an hour. 1 hour is 60 minute or 3600 (60*60) seconds or 3600000 milliseconds. You can save the millis() time value for the 'start' of the hour and then when the difference of current millis() to start is the required count, reset the counter. This is the same technique as any of the 'blink without delay' examples quoted with a very long time constant.

thestigh:
Sorry guys, of course I should have posted both all the hardware and code IF statement.

marco_c:
Every time you execute the IF statement, increment a counter by 1.

When the hour has expired, reset the counter to 0. The question is how do you detect the hour has passed and that depends on the hardware you have, which has not been mentioned.

Hi @marco_c,

Thank you. mills() are really new to me, only done a single test in a different IF statement. So question 1) would then me - will such a mills() calculation impact the mills() routine used in a different IF statement? Question 2) would be - could you kindly assist me to show how the code would be? You would be amazed to see what I've achieved the last weeks by reading and reading, but this time-thing just really puzzles me.

Any help would be highly appreciated.

Dont know if it was mentioned, but use unsigned long variables lest you get a mess!

const uint32_t millisPerHour = 3600000UL;

void loop()
{
  static uint32 hourTimer = millis();

  if (millis() - hourTimer >= millisPerHour)
  {
    hourTimer = millis();
    counter= 0;
  }

  // do the rest
}

No, it does not interfere with any other use of millis() as you are only using the timer to remember the starting 'time' for each time period into different variables.

Ahhh @marco_c, I so look forward to insert the code and test ;D Thank you!

marco_c:

const uint32_t millisPerHour = 3600000UL;

void loop()
{
 static uint32 hourTimer = millis();

if (millis() - hourTimer >= millisPerHour)
 {
   hourTimer = millis();
   counter= 0;
 }

// do the rest
}

@marco_c, I get a compile error:

C:\Users\Stigh\Documents\Arduino\Server\ESPproject\ESPproject.ino: In function 'void loop()':
ESPproject:599:16: error: 'uint32' does not name a type
         static uint32 hourTimer = millis();
                ^

This is the first IF statement I tried to put it in;

void loop() {
     if (delayMotionRunning && ((millis() - delayMotionStart) > (timeMotionSeconds*1000))) {
    
        static uint32 hourTimer = millis();
        if (millis() - hourTimer >= millisPerHour) {
          hourTimer = millis();
          motionCounter = 0;
        }
        motionCounter = motionCounter + 1;
    
        digitalWrite(onMotor, LOW);
        delayMotionRunning = false;
        ThingSpeak.setField(3, motionCounter);
        }
      if (client.connect(thingspeakServer,80)) {  
        int x = ThingSpeak.writeFields(myChannelNumber, apiKey);
        }
        client.stop(); 

    }
// new IF statements

This is also after doing the declaration;

const uint32_t millisPerHour = 3600000UL;

... which I assume I insert above void setup(), correct ?

static uint32 hourTimer = millis();
const uint32_t millisPerHour = 3600000UL;

spot the difference?

Uint32 is 32 bits of unsigned integer. T means typedef. What typedef means exactly i dont know.

My typo but you have been corrected already.

thestigh:
Thank you. mills() are really new to me, only done a single test in a different IF statement. So question 1) would then me - will such a mills() calculation impact the mills() routine used in a different IF statement? Question 2) would be - could you kindly assist me to show how the code would be? You would be amazed to see what I've achieved the last weeks by reading and reading, but this time-thing just really puzzles me.

millis() gives the number of milliseconds that have elapsed since the time the board was last reset. That's it, that's all it does. When that number reaches about 49 days, it rolls over - like the odometer of a car. Calling it multiple times in different places does nothing.

The way you use it is that when a thing happens, you store the value of millis() in a static variable. static variables are ones defined outside a function (or declared as static, but let's not go there). At a later time, you subtract that value from the current millis(), and this gives you elapsed milliseconds. It's important to do it that way, because that takes care of rollover.

A final tweak is to note that the constant 'number of milliseconds in an hour' exceeds the size of an 2-byte int. So it's important to tell the compiler that your calculations are to be done using long arithmetic. To do this, put an 'L' at the end of the number.

So:

const long ONE_HOUR = 60L * 60L * 1000L;
long startHour;
int counter;

void setup() {
  startHour = millis();
}

void loop() {
  if(millis()-startHour >= ONE_HOUR) {
    char buf[80];
    sprintf(buf, "Starting a new hour, counter is %d.", counter);
    Serial.println(buf);
    counter = 0;
    startHour = millis();
  }

  // other code. Maybe we increment the counter! Maybe not.
}

does the esp32 have internet connection? if yes - it should be very simple to get the time via NTP.
Just in case you want to have "the last hour" synchronized to the clock...

You guys are amazing! Thanks a lot.
The example from @marco_c with the spotted typo has been implemented and works.

I don't know if there are any practical differences between @marco_c's code example and the latest from @PaulMurrayCbr ...?

noiasca:
does the esp32 have internet connection? if yes - it should be very simple to get the time via NTP.
Just in case you want to have "the last hour" synchronized to the clock...

In some of the cases, it will not have WiFi access so I cannot build it where makes Internet access mandatory. But a good tip for next project :slight_smile: Thx :slight_smile:

thestigh:
I don't know if there are any practical differences between @marco_c's code example and the latest from @PaulMurrayCbr ...?

(scroll, scroll, scroll ...) Naah - it's all the same stuff.

marco_c:

const uint32_t millisPerHour = 3600000UL;

void loop()
{
 static uint32 hourTimer = millis();

if (millis() - hourTimer >= millisPerHour)
 {
   hourTimer = millis();
   counter= 0;
 }

// do the rest
}




No, it does not interfere with any other use of millis() as you are only using the timer to remember the starting 'time' for each time period into different variables.

To make this more complicated, is it possible that it uses the whole hour as 0 / start ? Meaning, it starts the countdown at like 2:00:00 and resets at 2:59:59 so the max value of my counting is at 2:59:59 ?