arduino + ds1307 rtc + relay

I have this code for my arduino to turn a light on for a period of time. when I use only hour is working ok, but when i try to use hour and minute is not working. Any help will be nice!

#include <RTClib.h>
#include <Wire.h>
RTC_DS1307 rtc;
#define LIGHTS1_DIGITAL_PIN 5
void setup() {
  // put your setup code here, to run once:
   pinMode(LIGHTS1_DIGITAL_PIN, OUTPUT);
Serial.begin(9600);
Wire.begin();
   rtc.begin();
   if (! rtc.isrunning())
  {
    Serial.println("RTC is NOT running!");
}
}

void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = rtc.now();
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(")");
  Serial.println();

  Serial.println( );
  delay(1000);

  if((now.hour()>= 9 & now.minute() == 30 ) && (now.hour() <= 18 & now.minute() == 40 ))
{
  Serial.println (" lights on");
  digitalWrite (LIGHTS1_DIGITAL_PIN, HIGH);
}
else
{
  Serial.println ("lights off");
  digitalWrite (LIGHTS1_DIGITAL_PIN, LOW);
}

}

Hi,
Try doing it in this way.

if (now.hour()>= 9 && now.hour() <= 18 && now.minute() >= 30 && now.minute() <= 40 )

Seems you've mixed up bitwise AND (&) and boolean AND (&&).

lthary:
but when i try to use hour and minute is not working.

No, it's working just fine. It is doing exactly what you coded it to do. Now if that doesn't match with your expectations or what you wanted it to do then maybe you need to tell what it is that you want and how that compares with what actually happens. But I can assure you that it is working just fine.

I use similar functionality in my sketch. Here's where I code daily feed times using hours and minutes.

    boolean pumpAstate = false;
    if (now.hour() == 6 && now.minute() >= 0 && now.minute() < 5) pumpAstate = true;    //6:00 am - 5 mins
    if (now.hour() == 8 && now.minute() >= 30 && now.minute() < 35) pumpAstate = true;  //8:30 am - 5 mins
    if (now.hour() == 11 && now.minute() >= 0 && now.minute() < 5) pumpAstate = true;  //11:00 am - 5 mins
    if (now.hour() == 13 && now.minute() >= 30 && now.minute() < 35) pumpAstate = true;  //1:30 pm - 5 mins
    if (now.hour() == 16 && now.minute() >= 0 && now.minute() < 10) pumpAstate = true;  //4:00 pm - 10 mins
    if (pumpAstate == true)
    {
      digitalWrite(pumpA, TURN_ON);
      terminal.print("\t");
      terminal.println(F("Feeding PlantA"));  //  Text printed to terminal monitor
      terminal.print("\t");
      terminal.println();
    }
    else
    {
      digitalWrite(pumpA, TURN_OFF);
    }

just change "terminal" to "Serial".

OK! sorry for my mess, coding not one of my skill :slight_smile: , i want too turn the lights on at 9:30 and off at 20:30. and if it happens to lose power the program check the clock and turn lights on /off depends of the time, now this is what i want, what exactly happens is the Serial m is printing lights off and the relay is LOW :frowning: , this if I use minutes, if i use only hours everything works as plan!

if (now.hour()>= 9  &&  now.hour() <= 18  &&    now.minute() >= 30   && now.minute() <= 40 )

Well then this won't work then will it. What if it was 10:25? The minutes side would fail so the whole thing would be false.

Instead of trying to cram it all in one line, try making two if statements out of it. That might help you express what you want a little easier.

What might be even easier would be to forget the concept of hours and minutes here and just express those times as minutes since midnight. Then you only need to compare that you are between two numbers. That would be a lot easier.

You don't need to digitalWrite (LIGHTS1_DIGITAL_PIN, HIGH) at every loop for 8 hours or 5 minutes either.

You can do

 if (now.hour() == 6 && now.minute() == 0) {
     //pump on
      digitalWrite (LIGHTS1_DIGITAL_PIN, HIGH);
}

 if (now.hour() == 6 && now.minute() == 5) {
     //pump off
      digitalWrite (LIGHTS1_DIGITAL_PIN, LOW);
}

Or you can use the Time.h & TimeAlarm.h library

but what happens in case of a power failure? the lights will be off until next cycle?

lthary:
but what happens in case of a power failure? the lights will be off until next cycle?

Do a simple check in setup to switch light on or off depending on time. Or store state in eeprom (when the light state changes, else you reach the max 100,000 write cycles in no time), read it at startup and act accordingly.

Separate the logic for determining if the lights should be on or off into to parts. The lights should be on if it is after the start time. The lights should be off if it after the end time.

bool lightsOn = false;
if(now.hour() >= 6 && now.minute() >= 30)
   lightsOn = true;
if(now.hour() >= 18 && now.minute() >= 40)
   lightsOn = false;

if(lightsOn)
   lightsNeedToBeOn();
else
   lightsNeedToBeOff();

There is no need to try to use a single if statement when using two makes more sense.

thank's guys for all your help! using bool make all the difference :slight_smile: .It was so simple but so complicate for me, this coding stuff is not for a old guy! :wink: