Alarms dont work with DS1307

Hi Guys,
I am presently automating my central heating system. Part of this plan requires a time clock based on the Arduino Mega 2560 with a DS1307 shield together with thermostats to control the furnace. I am using the Arduino IDE 1.0.5.
The attached program is based on the Time and TimeAlarms examples and requires an input from the Serial Monitor to set the RTC and display on the LCD. This part of the trial program works fine but the section associated with the alarm fails to function.
Please help.

To test the program

Set Time to 13 Jan2014 7.58am T1389599884
ALARMS

Alarm.alarmRepeat(8,00,0, KMorning1AlarmOn); // 8:00am every day
Alarm.alarmRepeat(8,02,0, KMorning1AlarmOff); // 8:00am every day
digitalClockDisplay();
Alarm.delay(200);

FUNCTIONS

void KMorning1AlarmOn()
{
digitalWrite(led, HIGH); // turn LED ON
lcd.print("morning alarm on"); // Print a message to the LCD.
// mySerial.println("Alarm: - turn lights on");
}

void KMorning1AlarmOff()
{
digitalWrite(led, LOW); // turn LED OFF
lcd.print("morning alarm off"); // Print a message to the LCD.
// mySerial.println("Alarm: - turn lights off");
}

/*15/1/14
 * TimeRTCSet sketch
 * example code illustrating Time library with real-time clock.
 * LED switches On/Off
 * RTC is set in response to serial port time message
 * A Processing example sketch to set the time is included in the download
 * Set Time to 13 Jan2014 7.58am     T1389599884
 */

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <TimeAlarms.h>
//#include <SoftwareSerial.h>
#include <LiquidCrystal.h> // include the library code

int led = 13;     //LED pin
//SoftwareSerial mySerial(10, 3); // RX, TX 

//constants for the number of rows and columns in the LCD
const int numRows = 2;
const int numCols = 16;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(30, 31, 32, 33, 34, 35);




void setup() 

{
   pinMode(30, OUTPUT);
    pinMode(31, OUTPUT);
    pinMode(32, OUTPUT);
    pinMode(33, OUTPUT);
    pinMode(34, OUTPUT);
    pinMode(35, OUTPUT);
    
  lcd.begin(numCols, numRows);
  
  pinMode(led, OUTPUT); 
 digitalWrite(led, LOW);     //Turn off LED
 
  lcd.print("RTC CLOCK");  // Print a message to the LCD.
  
 // set the data rate for the SoftwareSerial port
 delay(1000);
// mySerial.begin(9600);
//mySerial.println("Hello world, RTC");


 Alarm.alarmRepeat(8,00,0, KMorning1AlarmOn);  // 8:00am every day
 Alarm.alarmRepeat(8,02,0, KMorning1AlarmOff);  // 8:00am every day
    digitalClockDisplay();
   Alarm.delay(200);
}

void digitalClockDisplay(){
  // digital clock display of the time on LCD
    lcd.setCursor(0, 1);
  lcd.print(hour());
  printDigits(minute());
  printDigits(second());
  lcd.print(" ");
  lcd.print(day());
  lcd.print(" ");
  lcd.print(month());
  lcd.print(" ");
  lcd.print(year());
  lcd.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints 
  // preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}

/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed
                           // by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

time_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  // time message consists of a header and ten ascii digits
  while(Serial.available() >=  TIME_MSG_LEN ){  
    char c = Serial.read() ;
    Serial.print(c);
    if( c == TIME_HEADER ) {
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){
        c = Serial.read();
        if( c >= '0' && c <= '9'){
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
        }
      }
      return pctime;
    }
  }
  return 0;
}
//  pinMode(led, OUTPUT); 
//digitalWrite(led,LOW);
 // delay(1000);     
void KMorning1AlarmOn()
{
  digitalWrite(led, HIGH);   // turn  LED ON
  lcd.print("morning alarm on");  // Print a message to the LCD.
 //  mySerial.println("Alarm: - turn lights on");
}


void KMorning1AlarmOff()
{  
  digitalWrite(led, LOW);   // turn LED OFF
  lcd.print("morning alarm off");  // Print a message to the LCD.
 //   mySerial.println("Alarm: - turn lights off");
}








void loop()
{
  if(Serial.available())
  {
     time_t  t = processSyncMessage();
     if(t >0)
     {
        RTC.set(t);   // set the RTC and the system time to the received value
        setTime(t);
     }
  }
   digitalClockDisplay();
   Alarm.delay(200);
  }

Your Arduino is doing practically nothing. Why not have it determine if it is 8:00AM or 8:02, and perform the required actions? The Alarm class is not really necessary.

Your sync function appears to be relying on getting time from the PC, rather tan the DS1307. Why?

Paul's right...there's no need to keep reading the PC once you have initialized the RTC. Most DS1307 modules I've seen have a battery on board that can run the clock for years when power is removed. Since you have the Arduino powered by something (e..g, a wall wart?), there's no need to have a USB connection to the PC once you've initialized the DS1307 registers. ..hence, no need to bother the PC again. Your code should have some read() and write() calls to the RTC object to set (you only need to do this once) and read the clock. The contents of the registers is documented in the spec sheet and tells you that the values are returned as BCD numbers in the nibbles. Note that the DS1307 maintains an internal pointer to the registers that is automatically incremented each time a read() is done. While it will "wrap around", the register pointer is normally reset prior to each read of the register set.

Are you sure the problem is Alarms with DS1307? I have a sketch that works flawlessly with those two libraries, but the Alarms fail when I add the I2C LCD library.

Both the I2C LCD library and the parallel LCD library have the delay() and delayMicroseconds() functions in the .cpp file. If you note the readme file associated with the Alarms library it warns that all delay() commands must be replaced by Alarm.delay().

So I made a modified I2C LCD library, replacing all delay() and delayMicroseconds() statements with the nearest Alarm.delay() pause that I could get (1 msec minimum). Unfortunately that has still not solved the problem for me. I do think this might be where your problem is, not with the RTC. You might try commenting out the lcd calls in your sketch to see if the Alarms work then.

So I made a modified I2C LCD library, replacing all delay() and delayMicroseconds() statements with the nearest Alarm.delay() pause that I could get (1 msec minimum). Unfortunately that has still not solved the problem for me.

The delayMicroseconds() values are probably critical. Making them longer, but using Alarm.delay() instead, is probably not a good idea. I'd out them back, and simply do as advised - replace delay() with Alarm.delay().

Actually, I'd forget about the Alarm class altogether. You've got a clock. Look at it, periodically, and see if it is time to call the appropriate alarm function. That's all Alarm.delay() is doing.

Hi,
Many thanks for your prompt and helpful replies.
As far as my query is concerned I am really only interested in the TimesAlarm library and why the Alarms are not working. The reason for this is that in the final product I have many alarms to deal with and that library is my choice to do so.
Anyway I do not like mysteries as to why it does not work!!!!!
I would be grateful if someone could identify whats wrong with my program or perhaps provide me with a link to a program that carries out the same function as my original program, either would be very helpful.
I have commented out the LCD library but unfortunately it did not solve the problem. Maybe I will have to take up the suggestion of reading the clock and then generating the alarm that way.
I look forward to any further help
Again,thank you, and if I solve the problem I will be delighted to share it with you.
Regards

So, how about addressing this:

Your sync function appears to be relying on getting time from the PC, rather than the DS1307. Why?

Unless the Alarm class knows what time it is, you can't really expect the Alarm to fire on time.

Write one sketch that sets the time on the clock.
Write another sketch that does nothing more than read the time from the clock.
Then, write a third sketch (or extend the 2nd one) that introduces the Time library, and which uses setSyncProvider() to cause the time from the RTC to be fetched.
Only then should you think about adding Alarms.

Hi PaulS,
That sounds like a good plan.
Will try that and let you know how I get on.
Regards

One thing I ran into using an Uno. With LiquidCrystal, Alarm, and another couple of libraries, I ran out of SRAM. My sketch would run briefly and then hang up in the Uno, but ran great when I put it into a Mega. Since program space was not a problem in either controller, my conclusion is that there was a shortage of SRAM.