DS1307 Turn on things at specific time

Hi people,
I just decided to take some of my time and get more into arduino and electronics.
So I decided to make light timer by myself.I got myself a 5V relay,arduino and DS1307.
My goal is to turn on lights on every day at 00:00 (midnight) and have it on for 12 hours,so till 12AM.
I can afford 1% error (it would be 432 seconds,or 7.2 minutes).
I got DS1307 to work,so it’s not a problem.
Also I destroyed digital pin of arduino with it because relay coil is 66.65 ohms (it was drawing 75.01mA) I know,this time I’ll use 2n7000 to drive it.I would like to ask you guys for help because my programming skills are really bad…So code I’m trying to edit is this

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    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(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}
  1. What problem are you having?

  2. I'd be tempted to ditch the DS1307 and get a DS3231 instead. It's temperature compensated, unlike the 1307, so will maintain accuracy. It uses the same libraries as the 1307 but the downside is that the isRunning function won't work.

I think the simplest way to get the change at midnight is to test for the change of day

GetClock();
  if (today != day)
  {
   today = day;
   doSomething(); 
  }

If your library has am/pm, you could use it similarly at noon, otherwise test for change to 12 hours and also change a flag so that you only do it once. That flag might be set at midnight

I'm not sure how exactly would I turn it on at 00:00 and have it turned on till 12PM.My libray outputs time as 15:30.So I need lights working for 12 hours.

I might not have been clear. I meant change from 11:59 to 12:00, and set flag=1.
You test for hours=12 and flag =0.
You set flag=0 at midnight.

The above means there are only two operations - midnight and noon. It also means you have to wait for one or the other event for anything to happen. You may prefer to have redundant operations, which enable you to have something happen on start-up.

Nikola19992:
I'm not sure how exactly would I turn it on at 00:00 and have it turned on till 12PM.My libray outputs time as 15:30.So I need lights working for 12 hours.

I wrote a library just for this... you have to adapt for your specific RTC library

 if (now.hour() == 0 && now.minute() == 0) {
      digitalWrite (RELAY, HIGH);
}

 if (now.hour() == 12 && now.minute() == 30) { 
      digitalWrite (RELAY, LOW);
}

//12 hours 30 minutes

Yes, something like that. The usefulness of that approach might depend on the time taken by your loop.

Nick_Pyner:
Yes, something like that. The usefulness of that approach might depend on the time taken by your loop.

the problem with this is power interruption between on and off times...

The DailyTimer library solves that problem...

What exactly do you mean by "power interruption between on and off times"?

If, for example, you want a timed lamp to come on at 20:00 and off at 3:00.

If you use the method above, the light will changes state only when the boundaries are crossed.

If you power up your Arduino at say 1:30, the next on event isn't until 20:00, even though you are within the boundaries of the time window.

Using the library, if you powered up the Arduino and were within the boundaries, the light would be powered on. It determines the State that the lamp should be in based on the on and off times...

I understand now,yes I’m aware of that,but I don’t think it’s a big problem.Now I’m writing a code that will automatically calculate fan speed by temperature.But I don’t really understand how should PWM affect my motor speed

how to activate lights based on the day

Arfan09:
how to activate lights based on the day

"based on the day"? As in "It's Tuesday, the lights should be on"? As in "Today is the 17th, the lights should be on"?

What have you tried? Posting here is not trying. Though some people that post here are trying. Very trying.

only based on the day… As in “It’s Tuesday, the lights should be on”

and this program me, please help…

#include <RTClib.h>
#include <Wire.h>

RTC_DS1307 rtc;
char nameDay[7][12] = {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”};
//byte weekday = 0;

#define LIGHTS1_DIGITAL_PIN 6
#define LIGHTS2_DIGITAL_PIN 7

void setup() {
// put your setup code here, to run once:
pinMode(LIGHTS1_DIGITAL_PIN, OUTPUT);
pinMode(LIGHTS2_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(nameDay[weekday-1]);
Serial.print(nameDay[now.dayOfTheWeek()]);
Serial.print(",");
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.day(4) & now.hour()== 16 & now.minute() == 30 )
{
Serial.println (" lights on");
digitalWrite (LIGHTS1_DIGITAL_PIN, HIGH);
}
else if(now.day()==1 & now.hour()== 15 & now.minute() == 55 )
{
Serial.println (" lights off");
digitalWrite (LIGHTS1_DIGITAL_PIN, LOW);
}
}

Post your code between code tags (</>).

Here you can find out how to use the code tags: http://forum.arduino.cc/index.php/topic,148850.0.html

only based on the day... As in "It's Tuesday, the lights should be on"

The DateTime library has a weekday field.

    DateTime now = rtc.now();

   if(now.weekday == 2) // Sunday is 0
   {
      // It's Tuesday. Let's have a beer. Or something like that
   }