DS1307 as an alarm.

Guys, im trying to build an alarm based on the DS1307 RTC.

My plan is this, to have an alarm that would alarm at specific times as i have inputted them already.

I ordered the module, and im excited to use it, but i wanted to get a jump start from you guys.

My plan to create this project is to read the time from the RTC, such as:

int hour = now.hour()
int minute = now.minute()

correct?

then, run it through an if statement, like say, i wanted it to ring the alarm at say, 0830, the could would be like:

if hour == 8 && minute == 30
{
digitalWrite(alarmPin, HIGH);
delay(1000);
digitalWrite(alarmPin, LOW;
}

correct?

:slight_smile:

Have you taken into account that the test "hour == 8 && minute == 30" is true for whole a minute (= 60 seconds)? So your alarm pin may be high for more than 1 second (or better 60 times high for one second with only a very short interruption).

You've got a point there... Hmmm... Here's my solution:

Since the pin would be 60 times as high as you mentioned, and I wanted a 1 second interruption, ill just make the pin HIGH for 16 mS. So that 60*16 = 960mS, around 1 second. :smiley:

as for the other codes, would that be a valid code sequence? Like for example, I wanted for different times, i just keep adding "if" statements?

Since the pin would be 60 times as high as you mentioned, and I wanted a 1 second interruption, ill just make the pin HIGH for 16 mS. So that 60*16 = 960mS, around 1 second.

You didn't get the point. It's high for one minute, the 60 times comes from the fact that a minute has 60 seconds. If you shorten the pulse to 16ms you just get about 4000 pulses but it's still one minute.

as for the other codes, would that be a valid code sequence? Like for example, I wanted for different times, i just keep adding "if" statements?

I would not do it that way. Think about storing your alarm times in EEPROM? That way you can change the alarm times without uploading new sketches.

Hi!

You can add a counter. That will solve your problem.

if ((bAlarmHours==hours) && (bAlarmMinutes==minutes))
{
  if ((nowMillis - ulAlarmDelay) > 60000)
  {
      digitalWrite(alarmPin, HIGH);
      ulAlarmDelay=nowMillis;
  }
  if ((nowMillis - ulAlarmDelay) > 1000)
  {
     digitalWrite(alarmPin, LOW);
  }
}

nowMillis = millis();
The alarm will not trigger again until 1 minute has passed. You will also get 1 sec HIGH/LOW period.

Either store the alarm settings in EEPROM or use the DS1307 RAM (battery powered).

void set_alarm(byte ah,byte am)
{
  write_byte(1, ah);
  write_byte(2, am);
}
void get_alarm()
{
  bAlarmHours=read_byte(1);
  bAlarmMinutes=read_byte(2);
}
byte read_byte(byte bAdress)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                   // Set the register pointer to (0x08) to read first memory byte
  Wire.endTransmission();                      
  Wire.requestFrom(DS1307_I2C_ADDRESS, 1);     // In this case only read one byte
  byte bRetVal = Wire.read();  
  return bRetVal;
}

void write_byte(byte bAdress,byte bValue)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                             // Set the register pointer to (0xf3) to write the 11th memory byte
  Wire.write(bValue);                             // Write the desired byte value
  Wire.endTransmission(); 
}

Hey olof_n!

Thanks for the reply and help!

I was looking at the code, where you have to store it in either the EEPROM or RAM of the DS1307, considering that I have multiple times that require an alarm, what would be the best way to approach this?

Looking at the code, please do guide me, since I'm still a newbie in programming. i out some comments on each line where I get confused.

void set_alarm(byte ah,byte am)
{
  write_byte(1, ah);         //ah is the hour? 
  write_byte(2, am);        //am is the minute?
}
void get_alarm()
{
  bAlarmHours=read_byte(1);        //So this part reads the data from the EEPROM?
  bAlarmMinutes=read_byte(2);
}

//Is this a new code? like as you said in your statement above, I can either use the EEPROM, or the DS1307 RAM.

byte read_byte(byte bAdress)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                   // Set the register pointer to (0x08) to read first memory byte
  Wire.endTransmission();                      
  Wire.requestFrom(DS1307_I2C_ADDRESS, 1);     // In this case only read one byte
  byte bRetVal = Wire.read();  
  return bRetVal;
}

void write_byte(byte bAdress,byte bValue)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                             // Set the register pointer to (0xf3) to write the 11th memory byte
  Wire.write(bValue);                             // Write the desired byte value
  Wire.endTransmission(); 
}

With regards to writing new values to the EEPROM without uploading new sketches, how is that done?

if I proceeded with the IF else statements, would it still be possible? Like if I add a "second" reading, and add it to the test, such as, "hour == 8 && minute == 30 && second == 01"? And just upload a new sketch every time i wanted to change the alarm times?

If you haven't already seen the Time library and the included TimeAlarms libraries you may benefit by looking at them:
http://playground.arduino.cc/Code/time

Hi!

The code stores the alarm in DS1307 RAM (not EEPROM).
You could use arrays to store multiple alarms.

Here is an example.

byte bAlarmHours[3];  //Declare an array of bytes
byte bAlarmMinutes[3]; //Declare an array of bytes

bAlarmHours[0] = 10; //Set first alarmhour
bAlarmHours[1] = 11; //Set next alarmhour
bAlarmHours[2] = 12;

//Check all alarms
for (byte bNumOfAlarms=0;bNumOfAlarms<=2;bNumOfAlarms++)
{
         if ((bAlarmHours[bNumOfAlarms]==hours) && (bAlarmMinutes[bNumOfAlarms]==minutes))
         ........
}
void set_alarm(byte ah,byte am)
{
  write_byte(1, ah);         //ah is the hour?  Correct
  write_byte(2, am);        //am is the minute? Yes you can change the variable names to something better.
}
void get_alarm()
{
  bAlarmHours=read_byte(1);        //So this part reads the data from the EEPROM?
  bAlarmMinutes=read_byte(2);     //It reads from DS1307 RAM. 
                                               //If you use an array of alarms add an for loop
}

//Is this a new code? like as you said in your statement above, I can either use the EEPROM, or the DS1307 RAM.

//Below is a funtion that read from the DS1307 RAM. bAdress = which byte you want to read.
//Function get_alarm calls read_byte
byte read_byte(byte bAdress)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                   // Set the register pointer to (0x08) to read first memory byte
  Wire.endTransmission();                      
  Wire.requestFrom(DS1307_I2C_ADDRESS, 1);     // In this case only read one byte
  byte bRetVal = Wire.read();  
  return bRetVal;
}

//Writes to RAM. 
//bAdress = The address in memory
//bValue = byte you want to store
//Function set_alarm calls write_byte 
void write_byte(byte bAdress,byte bValue)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);  
  Wire.write(0x08+bAdress);                             // Set the register pointer to (0xf3) to write the 11th memory byte
  Wire.write(bValue);                             // Write the desired byte value
  Wire.endTransmission(); 
}

Hope this make sense. I am from Sweden so my English is not the best.

/Olof

Hi Sir, olof_n,,

How Could i Control this Alarm Value using LCDkeypad????