Using Millis() Function to turn on/off relay for x amount of hours and min

I am trying to using millis() function to turn on/off relay after a certain amount of hours/mins to automate my hydro system.

Currently, it is not switching the relay at the correct time. Attached is the code, any suggestion on how to modify the code or a new method would be much appreciated.

Thanks for the help

Hydro.ino (1.92 KB)

What is it doing wrong? If I change the delays to a few seconds for testing, it seems to turn the light and pump on and off appropriately.

It works for small increments, but when I try and delay it for hours it will turn on/off in 25 mins (or way before its suppose to turn on/off)

Welcome to the forum.

Posting your code inline with code tags will get many more eyes on it than when it is posted as an attachment.

t works for small increments, but when I try and delay it for hours it will turn on/off in 25 mins (or way before its suppose to turn on/off)

This is a symptom of overflowing some time variable.

First, the previousMillis variables should be typed as unsigned longs since they are being assigned the values of millis().

Second, see this note about U,L, and UL formatters for the constants

Try adding a specifier to all your time constants. They are better typed as unsigned longs rather than longs.

int Pump = 2;
int Light = 4;
int Fan = 7;

int PumpState = LOW; 
unsigned long previousMillis1 = 0;
const long PumpStart = 1980000; // for x sec 1980000
const long PumpStop = 300000; // on pump for x seconds  300000

int LightState = LOW;
unsigned long previousMillis2 = 0;
const long LightStart = 36000000; // on for x secs 36000000
const long LightStop = 2160000; // stop for x secs 21600000

int FanState = LOW;
unsigned long previousMillis3 = 0;
const long FanStart = 2000;
const long FanStop = 2000;

void setup() {
  
pinMode(Pump, OUTPUT);
pinMode(Light, OUTPUT);
pinMode(Fan,OUTPUT);

Serial.begin(9600);

}

void loop() {

unsigned long currentMillis = millis();
Serial.println("millis");
Serial.print(currentMillis);

if ((PumpState == HIGH) && (currentMillis - previousMillis1 >= PumpStart)){
  
  PumpState = LOW;
  previousMillis1 = currentMillis;
  
  Serial.println("current");
  Serial.print(currentMillis);
  Serial.print("previous");
  Serial.print(previousMillis1);
  digitalWrite(Pump, PumpState);
}
else if ((PumpState == LOW) && (currentMillis - previousMillis1 >= PumpStop)){
  
  PumpState = HIGH;
  previousMillis1 = currentMillis;
  
  Serial.println("current");
  Serial.print(currentMillis);
  Serial.print("previous");
  Serial.print(previousMillis1);
  digitalWrite(Pump, PumpState);    
  }
  
  if ((LightState == HIGH) && (currentMillis - previousMillis2 >= LightStart)){
  
  LightState = LOW;
  previousMillis2 = currentMillis;
  
  Serial.println("current");
  Serial.print(currentMillis);
  Serial.print("previous");
  Serial.print(previousMillis2);
  digitalWrite(Light, LightState);
}
else if ((LightState == LOW) && (currentMillis - previousMillis2 >= LightStop)){
  
  LightState = HIGH;
  previousMillis2 = currentMillis;
  
  Serial.println("current");
  Serial.print(currentMillis);
  Serial.print("previous");
  Serial.print(previousMillis2);
  digitalWrite(Light, LightState);    
  }
 digitalWrite(Fan, HIGH); 
  
}

Can you post the example with the hours delays in it?

wildbill:
Can you post the example with the hours delays in it?

unsigned long presentmillis = 0;
while(millis() - presentmillis != 86400000)   //wait for 24 hrs = 24x60x60x1000 ms //you can wait for 49 days
{
  ;    //you can do some other job during this waiting period
}
presentmillis = millis();  //update present time variable

while(millis() - presentmillis != 86400000) Could be a long wait.

Thank you all for the insight on both forum and the references for correcting the code. I will read over your reference and make the changes to the code and see if that solves the solution.. sounds like it will. I will keep the thread posted.

Thanks for all the help!

I would recommend you to use the DS3231 Real Time Clock which is very accurate. It works with an independent battery and has the option to create two alarms.

Which I recommend is to get the arduino into an sleep mode (you will save battery), with a previously set up alarm on the RTC. When the alarm fires the arduino will wake up and you could do your staff.

There are a lot of tutorials about waking up an arduino with an RTC Alarm. I recommend you this one: https://www.instructables.com/id/Arduino-Sleep-and-Wakeup-Test-With-DS3231-RTC/

Regards,