DS1302 notworking properly

Hey guys. I am new here, so sorry if my question looks stupid but I really need some help. I am trying to use DS1302 RTC to make a clock (part of my project is to have real time clock). And the problem is that the time is absolutely wrong.

// Timur Maksiomv 2014
//
// A quick demo of how to use DS1302-library to make a quick
// clock using a DS1302 and a 16x2 LCD.
//
// I assume you know how to connect the DS1302 and LCD.
// DS1302:  CE pin    -> Arduino Digital 45
//          I/O pin   -> Arduino Digital 43
//          SCLK pin  -> Arduino Digital 41
//          GND pin   -> Arduino Digital 39
//          VCC pin   -> Arduino Digital 37
//
// LCD:     DB7       -> Arduino Digital 7
//          DB6       -> Arduino Digital 6 
//          DB5       -> Arduino Digital 5
//          DB4       -> Arduino Digital 4
//          E         -> Arduino Digital 9
//          RS        -> Arduino Digital 8

#include <LiquidCrystal.h>
#include <DS1302RTC.h>
#include <Time.h>

// Init the DS1302
// Set pins:  CE, IO,CLK
DS1302RTC RTC(45, 43, 41);

// Optional connection for RTC module
#define DS1302_GND_PIN 39
#define DS1302_VCC_PIN 37

// Init the LCD
//   initialize the library with the numbers of the interface pins
//            lcd(RS,  E, d4, d5, d6, d7)
LiquidCrystal lcd(10,  8, 33, 31, 29, 27);

void setup()
{
  // Setup LCD to 16x2 characters
  lcd.begin(16, 2);

  // Activate RTC module
  digitalWrite(DS1302_GND_PIN, LOW);
  pinMode(DS1302_GND_PIN, OUTPUT);

  digitalWrite(DS1302_VCC_PIN, HIGH);
  pinMode(DS1302_VCC_PIN, OUTPUT);

  lcd.print("RTC activated");

  delay(500);

  // Check clock oscillation  
  lcd.clear();
  if (RTC.haltRTC())
    lcd.print("Clock stopped!");
  else
    lcd.print("Clock working.");

  // Check write-protection
  lcd.setCursor(0,1);
  if (RTC.writeEN())
    lcd.print("Write allowed.");
  else
    lcd.print("Write protected.");

  delay ( 2000 );

  // Setup Time library  
  lcd.clear();
  lcd.print("RTC Sync");
  setSyncProvider(RTC.get); // the function to get the time from the RTC
  if(timeStatus() == timeSet)
    lcd.print(" Ok!");
  else
    lcd.print(" FAIL!");

  delay ( 2000 );

  lcd.clear();
}

void loop()
{

  // Display time centered on the upper line
  lcd.setCursor(3, 0);
  print2digits(hour());
  lcd.print("  ");
  print2digits(minute());
  lcd.print("  ");
  print2digits(second());

  // Display abbreviated Day-of-Week in the lower left corner
  lcd.setCursor(0, 1);
  lcd.print(dayShortStr(weekday()));

  // Display date in the lower right corner
  lcd.setCursor(5, 1);
  lcd.print(" ");
  print2digits(day());
  lcd.print("/");
  print2digits(month());
  lcd.print("/");
  lcd.print(year());

  // Warning!
  if(timeStatus() != timeSet) {
    lcd.setCursor(0, 1);
    lcd.print(F("RTC ERROR: SYNC!"));
  }

  delay ( 1000 ); // Wait approx 1 sec
}

void print2digits(int number) {
  // Output leading zero
  if (number >= 0 && number < 10) {
    lcd.write('0');
  }
  lcd.print(number);
}

Can someone help me with solving the problem, so that DS1302 would sync time with my PC?
Now it shows 18/09/2013 23:34. It runs for 5 minutes (until 23:39) and then resets back to 23:34.

Which time library are you using ?

I assume you use this DS1302 library : http://playground.arduino.cc/Main/DS1302RTC

The DS1307 and DS1302 are known to have many problems. The good modules from Sparkfun and Adafruit do work, but cheap modules from Ebay do often not work very well.

When you need an RTC, remember to use the DS3231. That chip doesn't have all those troubles.

I may be being blind, but I cannot see anywhere in that code where the time is actually set for the RTC, nor can I see anwhere in the loop where the time is obtained from the RTC in which case it is not surprising that the figures you display bear no resemblance to the actual time.

Now it shows 18/09/2013 23:34. It runs for 5 minutes (until 23:39) and then resets back to 23:34.

For some reason, the RTC is not running. It is set to 18/09/2013 23:34 and is not moving from there.

setSyncProvider(RTC.get); // the function to get the time from the RTC

The time library arduino internal clock is getting the time from the RTC and it is what is being displayed. The default resync period is 5 minutes. The system checks the RTC every 5 minutes and gets the same halted value each time.

The code appears to be checking for the setting of the oscillator enabled bit, so that is probably not the cause.

Are you using the bare chip? Is it a module with a battery?

cattledog:
Are you using the bare chip? Is it a module with a battery?

I am using module with battery (This is the picture of it).

I use this Time library
And this DS1302 library

Can someone fix the code I am using? Or tell me how to fix it. I am just a newbie in programming so sorry about stupid questions.

Thanks for the photo and the links.
That is the newest Time library.

You have to set the time into the DS1302.

I think you have to run RTC.set or a setTime something.
At the moment I can only find the example with the DS1302RTC library called "SetSerial", but that uses yet another library. Perhaps there is something simpler than that.

The code and connections are for an Arduino Mega. Is that what you are using?

A first thing to try is to connect Vcc and Ground to pins labeled 5v and gnd instead of powering it off 37 and 39.

This code has a setting routine

/*----------------------------------------------------------------------*
* Display the date and time from a DS1302 RTC every second.            *
*                                                                      *
* Set the date and time by entering the following on the Arduino       *
* serial monitor:                                                      *
*    year,month,day,hour,minute,second,                                *
*                                                                      *
* Where                                                                *
*    year can be two or four digits,                                   *
*    month is 1-12,                                                    *
*    day is 1-31,                                                      *
*    hour is 0-23, and                                                 *
*    minute and second are 0-59.                                       *
*                                                                      *
* Entering the final comma delimiter (after "second") will avoid a     *
* one-second timeout and will allow the RTC to be set more accurately. *
*                                                                      *
* No validity checking is done, invalid values or incomplete syntax    *
* in the input will result in an incorrect RTC setting.                *
*                                                                      *
* Jack Christensen 08Aug2013                                           *
*                                                                      *
* Adopted for DS1302RTC library by Timur Maksimov 2014                 *
*                                                                      *
* This work is licensed under the Creative Commons Attribution-        *
* ShareAlike 3.0 Unported License. To view a copy of this license,     *
* visit http://creativecommons.org/licenses/by-sa/3.0/ or send a       *
* letter to Creative Commons, 171 Second Street, Suite 300,            *
* San Francisco, California, 94105, USA.                               *
*----------------------------------------------------------------------*/ 

#include <DS1302RTC.h>
#include <Streaming.h>        //http://arduiniana.org/libraries/streaming/
#include <Time.h>             //http://playground.arduino.cc/Code/Time

// Set pins:  CE, IO,CLK
DS1302RTC RTC(27, 29, 31);

// Optional connection for RTC module
#define DS1302_GND_PIN 33
#define DS1302_VCC_PIN 35

void setup(void)
{
 Serial.begin(115200);
   
 // Activate RTC module
 digitalWrite(DS1302_GND_PIN, LOW);
 pinMode(DS1302_GND_PIN, OUTPUT);

 digitalWrite(DS1302_VCC_PIN, HIGH);
 pinMode(DS1302_VCC_PIN, OUTPUT);
 
 Serial << F("RTC module activated");
 Serial << endl;
 delay(500);
 
 if (RTC.haltRTC()) {
   Serial << F("The DS1302 is stopped.  Please set time");
   Serial << F("to initialize the time and begin running.");
   Serial << endl;
 }
 if (!RTC.writeEN()) {
   Serial << F("The DS1302 is write protected. This normal.");
   Serial << endl;
 }
 
 delay(5000);
   
 //setSyncProvider() causes the Time library to synchronize with the
 //external RTC by calling RTC.get() every five minutes by default.
 setSyncProvider(RTC.get);

 Serial << F("RTC Sync");
 if (timeStatus() == timeSet)
   Serial << F(" Ok!");
 else
   Serial << F(" FAIL!");
 Serial << endl;
}

void loop(void)
{
   static time_t tLast;
   time_t t;
   tmElements_t tm;

   //check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
   if (Serial.available() >= 12) {
       //note that the tmElements_t Year member is an offset from 1970,
       //but the RTC wants the last two digits of the calendar year.
       //use the convenience macros from Time.h to do the conversions.
       int y = Serial.parseInt();
       if (y >= 100 && y < 1000)
           Serial << F("Error: Year must be two digits or four digits!") << endl;
       else {
           if (y >= 1000)
               tm.Year = CalendarYrToTm(y);
           else    //(y < 100)
               tm.Year = y2kYearToTm(y);
           tm.Month = Serial.parseInt();
           tm.Day = Serial.parseInt();
           tm.Hour = Serial.parseInt();
           tm.Minute = Serial.parseInt();
           tm.Second = Serial.parseInt();
           t = makeTime(tm);
	    //use the time_t value to ensure correct weekday is set
           if(RTC.set(t) == 0) { // Success
             setTime(t);
             Serial << F("RTC set to: ");
             printDateTime(t);
             Serial << endl;
	    }
	    else
	      Serial << F("RTC set failed!") << endl;
           //dump any extraneous input
           while (Serial.available() > 0) Serial.read();
       }
   }
   
   t = now();
   if (t != tLast) {
       tLast = t;
       printDateTime(t);
       Serial << endl;
   }
}

//print date and time to Serial
void printDateTime(time_t t)
{
   printDate(t);
   Serial << ' ';
   printTime(t);
}

//print time to Serial
void printTime(time_t t)
{
   printI00(hour(t), ':');
   printI00(minute(t), ':');
   printI00(second(t), ' ');
}

//print date to Serial
void printDate(time_t t)
{
   printI00(day(t), 0);
   Serial << monthShortStr(month(t)) << _DEC(year(t));
}

//Print an integer in "00" format (with leading zero),
//followed by a delimiter character to Serial.
//Input value assumed to be between 0 and 99.
void printI00(int val, char delim)
{
   if (val < 10) Serial << '0';
   Serial << _DEC(val);
   if (delim > 0) Serial << delim;
   return;
}

I was able to fix my code with only few additional lines. First of all I had to start clock (for some reason it was not running), and then add these lines to set time.

  //setTime(0,43,0,16,12,2014);
  //time_t t = now();
  //RTC.set(t);

Now I have one more question. How to sync time with the time of my PC? And is this even possible? If not, then thank you guys for help :slight_smile:

Take a look at this SetTime example from the DS1307RTC library. It uses the AVR compiler macros DATE and TIME to get a time which is when the computer compiled the sketch. It then sets this time in the RTC.

I have looked at the libraries, and I can not see why with a simple change of the #include to the DS1302 library it would not work. I don’t think you need Wire.h with the DS1302 library. I have no experience with the mega, but you seem to be handling that part of the situation fine.

//#include <Wire.h>
#include <Time.h>

//#include <DS1307RTC.h>

#include <DS1302RTC.h>

const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

tmElements_t tm;

void setup() {
  bool parse=false;
  bool config=false;

  // get the date and time the compiler was run
  if (getDate(__DATE__) && getTime(__TIME__)) {
    parse = true;
    // and configure the RTC with this info
    if (RTC.write(tm)) {
      config = true;
    }
  }

  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  delay(200);
  if (parse && config) {
    Serial.print("DS1307 configured Time=");
    Serial.print(__TIME__);
    Serial.print(", Date=");
    Serial.println(__DATE__);
  } else if (parse) {
    Serial.println("DS1307 Communication Error :-{");
    Serial.println("Please check your circuitry");
  } else {
    Serial.print("Could not parse info from the compiler, Time=\"");
    Serial.print(__TIME__);
    Serial.print("\", Date=\"");
    Serial.print(__DATE__);
    Serial.println("\"");
  }
}

void loop() {
}

bool getTime(const char *str)
{
  int Hour, Min, Sec;

  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
  tm.Hour = Hour;
  tm.Minute = Min;
  tm.Second = Sec;
  return true;
}

bool getDate(const char *str)
{
  char Month[12];
  int Day, Year;
  uint8_t monthIndex;

  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
    if (strcmp(Month, monthName[monthIndex]) == 0) break;
  }
  if (monthIndex >= 12) return false;
  tm.Day = Day;
  tm.Month = monthIndex + 1;
  tm.Year = CalendarYrToTm(Year);
  return true;
}

Well done.

When you buy a RTC chip, and connect it with a battery, it is not running. As far as I know, every RTC chip has to be started.

Your Arduino RTC has no time zone and no daylight-saving-flag, so you can use the current time of the computer and send it to the Arduino via the serial port. It is possible to send a message from the command line in Windows and linux, and you have to read the Serial message on the Arduino and set the time.

While I was writing this, cattledog replied. You don’t have to use <Wire.h> of course, that is for the DS1307 (an I2C chip). Using the compiler date and time (DATE and TIME) is very handy. But do that just once, directly after upload the sketch. When you want to set the time every now and then, you need to use a command via the serial port.

Peter_n

What I dont understand is why the clock halt flag was not picked up by either the op's original sketch with the lcd

// Check clock oscillation  
  lcd.clear();
  if (RTC.haltRTC())
    lcd.print("Clock stopped!");
  else
    lcd.print("Clock working.");

or in any of the later posted sketches with serial output testing the same CH bit 7 in the seconds register.