36 h delay - trouble

Hi

I try to make a timer for a ssr reley, on time ie 36h.
I use an arduino Pro Mini, no wifi/ble

I tried

deleay(3660'601000);

This code did not work,

Any tip to make this timer?

M

Read up on millis() timing and delays.
Then you can control the delay while allowing other things to happen - like a LED to blink as the countdown approaches, or to test a button for any purpose.

1 Like

36h is 36 x 3600 x 1000 ms

to write it so that it does not overflow on a 8 bit processor you need to make sure the correct type is used for the numbers (if they fit they will use int and it's too small)

you could define those constants at the start of your code

constexpr unsigned long oneSecond = 1000ul;            // 1 s in ms
constexpr unsigned long oneMinute = oneSecond * 60;    // 60 seconds
constexpr unsigned long oneHour = oneMinute * 60;      // 60 minutes

because the constants are typed as unsigned long, the multiplication with the integral literal will be conducted also as unsigned long and it won't roll over.

Then in your code if you want to way 36 hours you could do

delay(oneHour*36); //block for 36 hours

or add at the start of your code (for easy modification and reuse)

constexpr unsigned long oneSecond = 1000ul;            // 1 s in ms
constexpr unsigned long oneMinute = oneSecond * 60;    // 60 seconds
constexpr unsigned long oneHour = oneMinute * 60;      // 60 minutes

constexpr unsigned long thirtySixHours = oneHour*36; 

and then you can use

delay(thirtySixHours); //block for 36 hours
2 Likes

This code provides a fast blinking onboard LED (IO-pin 13) as long as the delay is active
and slower blinking if delay-time is over.

unsigned long MyBlinkTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;     // onboard of Arduino Uno / Mega

unsigned long MyDelayTimer = 0;                   // Timer-variables MUST be of type unsigned long

boolean delayIsActive = true;
unsigned long delayActiveInterval = 100; // fast blinking
unsigned long delayIsOverInterval = 500; // slower blinking

unsigned long blinkInterval;

const unsigned long oneSecond = 1000ul;            // 1 s in ms
const unsigned long oneMinute = oneSecond * 60;    // 60 seconds
const unsigned long oneHour = oneMinute * 60;      // 60 minutes

const unsigned long thirtySixHours = oneHour * 36;
unsigned long delayInterval = thirtySixHours;


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();
  MyDelayTimer = millis();
  delayIsActive = true;
  blinkInterval = delayActiveInterval;
}


void loop() {
  BlinkHeartBeatLED(OnBoard_LED, blinkInterval);

  if (delayIsActive == true) {
    if ( TimePeriodIsOver(MyDelayTimer, delayInterval) ) {
      delayIsActive = false;
      // code that shall be executed if delayTime is over
      blinkInterval = delayIsOverInterval;
    }
  }
}


// helper-functions
void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long & startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}



void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

Here is an explanation how non-blocking timing works

What shall happen when the ontime is over?
shall the SSR stay switched off for 10 years or shall something else happen?

1 Like

Don't you think your code is just way too complicated for the OP (who doesn't seem to understand much about coding in C++) and not meeting the original question?

the very short answer for OP would have been to say

use

delay(129600000); // 36 x 3600 x 1000 = 129600000ms for 36h
2 Likes

No because the wanted functionality is really small.
The code does what the OP was asking for.
The code is direct usable.

Anyway I asked for additional functionality.
Still the hurdle to understand the code is somehow less high than than with some other code.

But yes it is more than a simple "delay(129600000);
and need more time and explanation to make it easy to understand for real beginners.

didn't you have a tutorial explaining your TimePeriodIsOver() function? may be you should link it when you use it in some examples

1 Like

Hi,
thanks for really helping me, did not expect to get a working code! @StefanL38. I like the blinking feedback, wife friendly!

To the rest of you, @J-M-L @jim-p @lastchancename:
I agree, the code made me jump over the learning phase this time, I'm not a skilled c++ programmer so to make the code, given here, would take me some time to learn. I am aware of the timing problem, but when I wrote my code I did not remember the situation...

Fyi, this code will be used for my wife's honey production, see https://bybi.no/, voluntarily work in Oslo, Norway.

The timer is for a heating cabinet that makes honey from a sugary state to a floating state, and for the process it needs to run for 36 h, on Thursday she needs the system, and I will deliver it!

Thanks!

M

Here is a slightly extended version which prints the remaining time to the serial monitor


unsigned long MyBlinkTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;     // onboard of Arduino Uno / Mega

unsigned long mySecondsTimer;
unsigned long MyDelayTimer = 0;                   // Timer-variables MUST be of type unsigned long

boolean delayIsActive = true;
unsigned long delayActiveInterval = 100; // fast blinking
unsigned long delayIsOverInterval = 500; // slower blinking

unsigned long blinkInterval;

const unsigned long oneSecond = 1000ul;            // 1 s in ms
const unsigned long oneMinute = oneSecond * 60;    // 60 seconds
const unsigned long oneHour = oneMinute * 60;      // 60 minutes

const unsigned long thirtySixHours = oneHour * 36;
unsigned long delayInterval = thirtySixHours;
unsigned long secondsCounter = delayInterval / 1000;

unsigned long hoursRemaining;
unsigned long MinutesRemaining;
unsigned long SecondsRemaining;


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();
  MyDelayTimer = millis();
  delayIsActive = true;
  blinkInterval = delayActiveInterval;
}


void loop() {
  BlinkHeartBeatLED(OnBoard_LED, blinkInterval);

  if (delayIsActive == true) {
    if ( TimePeriodIsOver(MyDelayTimer, delayInterval) ) {
      delayIsActive = false;
      // code that shall be executed if delayTime is over
      blinkInterval = delayIsOverInterval;
    }

    if (TimePeriodIsOver(mySecondsTimer, 1000) ) {
      printRemainingTime();
    }
  }
}

void printRemainingTime() {
  secondsCounter--;
  Serial.print("Seconds remaining:");
  Serial.println(secondsCounter);

  hoursRemaining = secondsCounter / 3600;
  MinutesRemaining = (secondsCounter % 3600) / 60;
  SecondsRemaining = (secondsCounter % 3600) % 60;
  Serial.print("time remaining: ");
  Serial.print(hoursRemaining);
  Serial.print(":");
  Serial.print(MinutesRemaining);
  Serial.print(":");
  Serial.println(SecondsRemaining);
}

// helper-functions
void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long & startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}



void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}
1 Like

if you need final help with the code let us know. Forum is always very happy to help out those providing help for voluntarily work.

congrats to you & your wife for contributing.

1 Like

That latest addition by StefanL38, of adding the countdown of the remaining time is a great benefit.

However you must remember to keep the Serial Monitor open through out the full timing period.
If you happen to close it, and then re-open it, the timer re-starts at 36 hours.

Good luck with the honey production.

1 Like

Hi

Your helping answers makes me feel lucky, so nice of you all, thanks also from my wife, I shared your comments.

The serial count-down from @StefanL38 is a nice addition, I save it for next project. For this project I make a project box, 230V in, SSR relay + Arduino Pro Mini, 230V out, when plugged in it starts the 36 h countdown and LED flashes quick when in countdown mode. If they will start again, they disconnect 230V and reconnect. No computer needed. Of course I can add a OLED, but that would be overkill for this simple system.

M

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.