Converting Alarm Clock Code from Using DS1307 to Internal RTC

Hi,

I am trying to use Dr. John Liu’s code for an Alarm clock (attached) to apply this to my project.

I am using a screen shield kit from Adafruit that makes use of a different library than the one used in the code. The library that my lcd screen uses is Adafruit_RGBLCDShield, instead of LiquidCrystal.

This is the screen that I am using: RGB LCD Shield Kit w/ 16x2 Character Display - Only 2 pins used! [NEGATIVE DISPLAY] : ID 714 : $24.95 : Adafruit Industries, Unique & fun DIY electronics and kits

I have two problems:

  1. I need to switch the LCD library used

  2. I wish to use the Arduino Uno’s internal RTC

The attached code is making use of a DS1307, and I need to use an internal RTC.

If someone can assist me with editing this code so that it works for my specific project, I would really appreciate it!

**I’m new here! Sorry if I forgot to mention something, or didn’t attach the file properly :slight_smile:

Alarm_Clock_1.ino (5.94 KB)

Which Arduino do you have? I'm not aware of any with internal RTC. There is the time library but you're limited to the accuracy of the resonator that clocks the chip and I think it's only good to plus minus ten minutes a day or so.

The uno does not have a rtc so you need to be clearer in that requirement.

Your code seems small enough to be added to a post

Type

[code]
Paste your code after that
Type [/code]

after the pasted code.

I’m using an Arduino Uno. I think I read somewhere that it has an internal clock but I may be wrong… I need to have the lcd display the current time (hours and minutes).

Thank you for letting me know!

Here is the code:

/*
Phi-1 shield for Arduino
Test program: Alarm clock

Programmed by Dr. John Liu
Revision: 11/19/2010
Commerical use without authorization is prohibited.
Find details of the Phi-1 shield or contact Dr. Liu at http://liudr.wordpress.com
All rights reserved.

List of functions:
* Display real time clock with Year month, date, day of week, hour, minute, and second.
* Four individual alarms (change Max_alarms to get more alarms)
* Alarms are stored on Arduino EEPROM and won't be lost when the power is out.
* Alarms Daily, Weekday, Weekend, Once, Off.
* Adjustable alarms. Press B to choose alarm and adjust the time.
* Adjustable clock and date. Press A to adjust clock and date.
* TODO - Add snooze function.
* TODO - Add special function on the alarm to drive outputs other than the buzzer and LED. You can be creative!

Instructions:

You need to set the clock before you can use it.
1. Uncomment this line "#define setRTC" among the #define lines.
2. Update the time in setup() to the current time.
3. Upload the sketch to arduino to set the time.
4. Then comment the line "#define setRTC" and recompile and upload to arduino.
5. If you don't do step 4, the clock will be reset every time arduino resets.
----------------------------------------
Thanks:

RTC created by matt.joyce@gmail.com

EEPROM Author: hkhijhe

*/
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include "buttons.h"
#include "DS1307_1.h" 
#include "alarm_clock.h"

int hmi_with_update_2(int current, int lower, int upper, byte inc, byte column, byte row, byte space, void (*update_function)(int));

// Defining pins used
//#define setRTC
#define buzzer 16
#define ch1 16
#define ch1_analog 2
#define led 17
#define ch2 17
#define ch2_analog 3
#define btn_u 5
#define btn_d 10
#define btn_l 11
#define btn_r 3
#define btn_b 14
#define btn_a 15
#define alarm_EEPROM_storage 1023-3*Max_alarms // Where the alarm is saved.
// Messages used in program.
PROGMEM prog_char dow_00[]="SUN";
PROGMEM prog_char dow_01[]="MON";
PROGMEM prog_char dow_02[]="TUE";
PROGMEM prog_char dow_03[]="WED";
PROGMEM prog_char dow_04[]="THU";
PROGMEM prog_char dow_05[]="FRI";
PROGMEM prog_char dow_06[]="SAT";
PROGMEM prog_char dow_07[]="M-F";
PROGMEM prog_char dow_08[]="Day of the week";

PROGMEM prog_char alarm_00[]="Off    ";
PROGMEM prog_char alarm_01[]="Daily  ";
PROGMEM prog_char alarm_02[]="Weekday";
PROGMEM prog_char alarm_03[]="Weekend";
PROGMEM prog_char alarm_04[]="Once   ";

PROGMEM prog_char month_00[]="JAN";
PROGMEM prog_char month_01[]="FEB";
PROGMEM prog_char month_02[]="MAR";
PROGMEM prog_char month_03[]="APR";
PROGMEM prog_char month_04[]="MAY";
PROGMEM prog_char month_05[]="JUN";
PROGMEM prog_char month_06[]="JUL";
PROGMEM prog_char month_07[]="AUG";
PROGMEM prog_char month_08[]="SEP";
PROGMEM prog_char month_09[]="OCT";
PROGMEM prog_char month_10[]="NOV";
PROGMEM prog_char month_11[]="DEC";
PROGMEM prog_char month_12[]="Month";

// Defines button objects
buttons btn_1(btn_u, LOW);
buttons btn_2(btn_d, LOW);
buttons btn_3(btn_l, LOW);
buttons btn_4(btn_r, LOW);
buttons btn_5(btn_b, LOW);
buttons btn_6(btn_a, LOW);

int rtc[7];
LiquidCrystal lcd(8, 9, 7, 6, 2, 4); //Phi-1 shield setting
DS1307 RTC=DS1307(); // Create RTC object
alarm_clock clock1(false); // Create an alarm clock

void setup()
{
  lcd.begin(16, 2);
  Wire.begin(); // initialize wire

// Set button pins to input with internal pull-up resistors
  pinMode(btn_u,INPUT);
  digitalWrite(btn_u,HIGH);
  pinMode(btn_d,INPUT);
  digitalWrite(btn_d,HIGH);
  pinMode(btn_l,INPUT);
  digitalWrite(btn_l,HIGH);
  pinMode(btn_r,INPUT);
  digitalWrite(btn_r,HIGH);
  pinMode(btn_b,INPUT);
  digitalWrite(btn_b,HIGH);
  pinMode(btn_a,INPUT);
  digitalWrite(btn_a,HIGH);

// Set the two channels to output to drive the buzzer and LED.
  pinMode(buzzer,OUTPUT);
  digitalWrite(buzzer,LOW);
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);

#ifdef setRTC
// Set/init RTC
  RTC.stop();
  RTC.set(DS1307_SEC,0);
  RTC.set(DS1307_MIN,50);
  RTC.set(DS1307_HR,0);
  RTC.set(DS1307_DOW,3); // value from 1 to 7. User define whether 1 is sun or mon.
  RTC.set(DS1307_DATE,16);
  RTC.set(DS1307_MTH,11);
  RTC.set(DS1307_YR,10);
  RTC.start();

//Set alarms
  EEPROM.write(alarm_EEPROM_storage,6); // Alarm 0 hour
  EEPROM.write(alarm_EEPROM_storage+1,50); // Alarm 0 minute
  EEPROM.write(alarm_EEPROM_storage+2,2); // Alarm 0 frequency M-F

  EEPROM.write(alarm_EEPROM_storage+3,7); // Alarm 1 hour
  EEPROM.write(alarm_EEPROM_storage+4,00); // Alarm 1 minute
  EEPROM.write(alarm_EEPROM_storage+5,2); // Alarm 1 frequency M-F

  EEPROM.write(alarm_EEPROM_storage+6,7); // Alarm 2 hour
  EEPROM.write(alarm_EEPROM_storage+7,10); // Alarm 2 minute
  EEPROM.write(alarm_EEPROM_storage+8,2); // Alarm 2 frequency M-F

  EEPROM.write(alarm_EEPROM_storage+9,9); // Alarm 3 hour
  EEPROM.write(alarm_EEPROM_storage+10,30); // Alarm 3 minute
  EEPROM.write(alarm_EEPROM_storage+11,3); // Alarm 3 frequency Weekend
#else
// Set alarm on the clock from EEPROM.
  clock1.set_alarm(0, EEPROM.read(alarm_EEPROM_storage), EEPROM.read(alarm_EEPROM_storage+1), EEPROM.read(alarm_EEPROM_storage+2));
  clock1.set_alarm(1, EEPROM.read(alarm_EEPROM_storage+3), EEPROM.read(alarm_EEPROM_storage+4), EEPROM.read(alarm_EEPROM_storage+5));
  clock1.set_alarm(2, EEPROM.read(alarm_EEPROM_storage+6), EEPROM.read(alarm_EEPROM_storage+7), EEPROM.read(alarm_EEPROM_storage+8));
  clock1.set_alarm(3, EEPROM.read(alarm_EEPROM_storage+9), EEPROM.read(alarm_EEPROM_storage+10), EEPROM.read(alarm_EEPROM_storage+11));
#endif

}

void loop()
{
  int temp1;
  clock1.run();
  if (!clock1.alarm_is_on)
  {
    temp1=wait_on_escape(250);
    switch (temp1)
    {
      case 1:
      lcd.clear();
      lcd.print("liudr.wordpress");
      lcd.setCursor(0,1);
      lcd.print(".com for details");
      wait_on_escape(5000);
      break;
      
      case 5:
      set_alarm(0);
      break;
      
      case 6:
      set_clock();
      break;
      
      default:
      break;
    }
  }  
}

You did not read that anywhere. If you did you were lied to. There is no internal RTC.

#include "DS1307_1.h"

That's an I2C chip, DS1307, not internal to the Arduino's Atmega328P.

Oh, darn... Are you aware of any other libraries or methods that I could use to obtain the current time without relying on the DS1307?

Eseguin:
Oh, darn... Are you aware of any other libraries or methods that I could use to obtain the current time without relying on the DS1307?

You could use an internet connection and a Network Time Server to get the time.
If your clock has a clear enough view of the sky you could use a GPS module to get the time.
A DS1307 module costs $0.99 on eBay.

Eseguin:
I think I read somewhere that it has an internal clock but I may be wrong...

Of course it has a clock, how else would it time anything?

But, a clock != RTC :wink:

Delta_G:
If you did you were lied to.

So not per se :stuck_out_tongue: It has a clock, only it's not a RTC :smiley:

Eseguin:
Are you aware of any other libraries or methods that I could use to obtain the current time without relying on the DS1307?

Yes, I thought the Time library has a mode to use the internal clock. BUT, it is nowhere accurate then. Multiple minutes per day can happen then.

I'm not sure a 328P has enough resources to get Network Time like that - we did a project with one of these internet modules
http://www.dipmicro.com/store/ENC28J60-MINI-MOD
Ethernet LAN Network Breakout Module ENC28J60 Arduino Compatible - dipmicro electronics (breaks out more pins, so a little larger, but also on sale)
and needed more SRAM than a 328P had to get time from a NTP server.

DS1307 chips & battery backed modules (with some extra EEPROM as well) are not expensive.Chips need 32.768 KHz crystal if wiring up your own, and a couple 4.7K resistors to pull up the SCL, SDA, (and square wave output lines if used).
http://www.dipmicro.com/store/index.php?searchStr=ds1307&act=viewCat&Submit=Search

I've decided to go ahead and order a DS1307. This solves the issue of the Uno not having an internal RTC, but I am left with the trouble of the lcd screen libraries. I am not sure if I can simply include both, or even if they are compatible. (As you can tell, I'm fairly clueless when it comes to libraries) Can I use this code and simply replace a few lines of code in order to use the Adafruit RGB library instead of the LiquidCrystal one?

CrossRoads:
I'm not sure a 328P has enough resources to get Network Time like that - we did a project with one of these internet modules
Ethernet LAN Network Breakout Mini Module ENC28J60 Arduino Compatible - dipmicro electronics
Ethernet LAN Network Breakout Module ENC28J60 Arduino Compatible - dipmicro electronics (breaks out more pins, so a little larger, but also on sale)
and needed more SRAM than a 328P had to get time from a NTP server.

The $2.75 ENC28J60 is an Ethernet interface that has no TCP/IP support. The entire TCP/IP stack has to be implemented in the Arduino library. That does leave very little room on an ATmega328P for anything else.
The common $6 Ethernet Shield uses a WIZnet W5100 chip which includes the TCP/IP stack and requires far fewer resources in the Arduino. It can easily do NTP as shown in File->Examples->Ethernet->UdpNtpClient. The example uses only 34% of FLASH and 33% of SRAM on an Arduino UNO. The Ethernet Shield also includes a handy SD Card socket for file storage.

Thanks John, we'll have to check that out for future projects.

I don't do many internet connected projects, everything is usually embedded into something.
Who's a good supplier for Wiznet5100 modules?

CrossRoads:
I don't do many internet connected projects, everything is usually embedded into something.
Who's a good supplier for Wiznet5100 modules?

I go to eBay and search for "Ethernet Shield". Current prices start around $5.50 including shipping.

Eseguin:
I’ve decided to go ahead and order a DS1307. This solves the issue of the Uno not having an internal RTC, but I am left with the trouble of the lcd screen libraries. I am not sure if I can simply include both, or even if they are compatible. (As you can tell, I’m fairly clueless when it comes to libraries) Can I use this code and simply replace a few lines of code in order to use the Adafruit RGB library instead of the LiquidCrystal one?

The Adafruit library is built on top of the standard LiquidCrystal library so you just need to change the initialization:

#include <Adafruit_RGBLCDShield.h>
#...
#LiquidCrystal lcd(8, 9, 7, 6, 2, 4); //Phi-1 shield setting
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

and all your lcd.print() calls will work

I won't buy electronics off e-bay. If I'm going to design a part in, I want to get it from a reliable, repeatable source.

AS long you don't want to make something commercial but just a DIY thing, eBay is just fine :slight_smile: Yeah, eBay things might change. But as far as home stuff I don't care...

I'm just not going to pay €5,- for a RTC + another €5,- for shipping for a fun DIY project...