Help with if statement pls!

Hi!

I've attached my code below - I'm trying to get the LED's to light up at a certain time, but the if statement isn't working - any idea where I'm going wrong?
Thanks!

#include "RTClib.h" //including the RTC Library for the time 
RTC_DS1307 rtc;

//Define the pins for the thermostat, lights and coffee machine 
int thermostatPin = 10; //purple LED
int kitchenlightPin = 9; //blue LED
int hallwaylightPin = 8; //yellow LED
int coffeemachinePin = 7; // pink LED 


void setup() {
  // Set-up for the RTC:
  Serial.begin(115200); 
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  //Set-up pins for thermostat, lights and coffee machine 
    pinMode(thermostatPin, OUTPUT);
    pinMode(kitchenlightPin, OUTPUT);
    pinMode(hallwaylightPin, OUTPUT);
    pinMode(coffeemachinePin, OUTPUT);
  }
}
void loop() { 

  // Print the time 
  DateTime now = rtc.now();
Serial.print(now.hour(), DEC);{
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.println();
  delay(3000); //time prints every 0.5 minutes
}
//set the alarm

if 
(now.hour(), DEC ==8 && now.minute(), DEC == 48) { //change these values to your time to watch the system work
    digitalWrite(thermostatPin, HIGH);

    digitalWrite(kitchenlightPin, HIGH);
    digitalWrite(hallwaylightPin, HIGH);
    digitalWrite(coffeemachinePin, HIGH);
}
   //Turn off the system after an hour 
   delay(6000); //change this value to 60000 to see system turn off after 1 minute 
   digitalWrite(thermostatPin, LOW);
   digitalWrite(kitchenlightPin, LOW);
   digitalWrite(hallwaylightPin, LOW);
   digitalWrite(coffeemachinePin, LOW);
  
}
  if (now.hour(), DEC == 8 && now.minute(), DEC == 48)  //change these values to your time to watch the system work

That syntax is wrong. Perhaps you meant

if (now.hour() == 8 && now.minute() == 48)
1 Like

Even after you make the correction suggested by @UKHeliBob your code will still not work.

When the time is not 08:48, the code will wait for 1 hour/1 minute and then turn off the thermostat and lights, even though they are already off. It won't print the time every 0.5 minutes as you are expecting.

I suggest you calculate the "minutes past midnight" and make all your checks against that.

int timeNow = now.hour() *60 + now.minute();
static int prevTime;
const int alarmTime = 8 * 60 + 48;
...
if (timeNow >= alarmTime && prevTime < alarmTime) {
  digitalWrite(...
  ...
}
prevTime = timeNow;

Avoid using delay() completely.

Have a think about that idea and ask any questions you have.

1 Like

Thanks for your help, really appreciated.
I need to be able to show the system working on a smaller timeframe - to prove it works. So taking in mind what you said, I have this. The LEDs turn on perfectly - just need to mess around to make sure it's turning off how I want.

//set the alarm
if (now.hour() ==9 && now.minute() ==40) { //change these values to your time to watch the system work
    digitalWrite(thermostatPin, HIGH);
    digitalWrite(kitchenlightPin, HIGH);
    digitalWrite(hallwaylightPin, HIGH);
    digitalWrite(coffeemachinePin, HIGH);
}
int alarmOff = now.minute() + 2;

   //Turn off the system after an amount of time  
if (alarmOff = now.minute()){
   digitalWrite(thermostatPin, LOW);
   digitalWrite(kitchenlightPin, LOW);
   digitalWrite(hallwaylightPin, LOW);
   digitalWrite(coffeemachinePin, LOW);
 
}
}

Be careful ... you probably mean == rather than =.

1 Like

yup - just spotted it!

That's not going to work (even if you replace the = with == ). For example right now it is 10:43. So alarmOff would get set to 45. Then you test to see if 43 == 45. Ok, there's a very small chance that between those two code lines, the minutes will have changed to 44. But no chance of it being 45.

This is going to be interesting when now.minute() equals 59

On the same topic, unless you can be surely checking the time more than once a minute, it is safer to use logic that sees if one time has reached or gone past another, rather than just test for exact equality.

And the idea of using a single calculated number for time makes things easier.

Minutes since midnight has been suggested by @PaulRB.

Seconds since 1 January 1970 is popular, oddly, and allows for times that go across days or weeks or months. But will overflow a 32 bit integer in 2038. I'll be dead, so I do not care.

    if (60 * hh + mm >= 645) {
      Serial.println(" it is 10:45!");
    }

Of course that will print any time it is executed that is or has passed 10:45. So account for that, however.

   const int onTime = 60 * 18 + 30;  // 6:30 PM
   const int offTime = 60 * 22;      // 10:00 PM

   int minutesSince = 60 * hh + mm;
   if (minutesSince >= onTime and minutesSince < offTime)
     digitslWrite(porchLight, HIGH);
   else
     digitslWrite(porchLight, HIGH);

Turn in the porch light between 6:30 PM and 10 PM.

This also has an advantage in that it is a bit better at surviving a power outrage that may have also caused you to miss exactly comparisons.

If "minutes since midnight" encounters a range that crosses a day transition (midnight), usually that can be handled w/o too much trouble

a7

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