Go Down

### Topic: DS1307 as an alarm. (Read 1 time)previous topic - next topic

#### Gin319

##### Feb 06, 2013, 02:42 pm
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:

Code: [Select]
`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:

Code: [Select]
`if hour == 8 && minute == 30{digitalWrite(alarmPin, HIGH);delay(1000);digitalWrite(alarmPin, LOW;}`

correct?

--Gin319

#### pylon

#1
##### Feb 06, 2013, 02:50 pm
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).

#### Gin319

#2
##### Feb 06, 2013, 03:21 pm
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.

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?
--Gin319

#### pylon

#3
##### Feb 06, 2013, 05:29 pm
Quote
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.

Quote
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.

#### olof_n

#4
##### Feb 06, 2013, 06:58 pmLast Edit: Feb 06, 2013, 07:04 pm by olof_n Reason: 1
Hi!

Code: [Select]
`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).

Code: [Select]
`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(); }`

#### Gin319

#5
##### Feb 06, 2013, 11:34 pm
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.

Code: [Select]
`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?
--Gin319

#### LarryD

#6
##### Feb 07, 2013, 12:20 am
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
The way you have it in your schematic isn't the same as how you have it wired up!

#### olof_n

#7
##### Feb 07, 2013, 08:31 am
Hi!

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

Here is an example.

Code: [Select]
`byte bAlarmHours[3];  //Declare an array of bytesbyte bAlarmMinutes[3]; //Declare an array of bytesbAlarmHours[0] = 10; //Set first alarmhourbAlarmHours[1] = 11; //Set next alarmhourbAlarmHours[2] = 12;//Check all alarmsfor (byte bNumOfAlarms=0;bNumOfAlarms<=2;bNumOfAlarms++){         if ((bAlarmHours[bNumOfAlarms]==hours) && (bAlarmMinutes[bNumOfAlarms]==minutes))         ........}`

Code: [Select]
`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_bytebyte 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

Go Up

Please enter a valid email to subscribe