A working sketch for DS1302 real time module?

greets

I've found a sketch online at GitHub - msparks/arduino-ds1302: Arduino library for the DS1302 Real Time Clock chip based on the DS1302 library, but unfortunatelly it does not work, I'm only getting "Sunday 2000-01-01 00:00:40" as the output of Serial.print.

direct links to:

the example sketch:

/*
Example sketch for interfacing with the DS1302 timekeeping chip.

Copyright (c) 2009, Matt Sparks
All rights reserved.

http://quadpoint.org/projects/arduino-ds1302
*/
#include <stdio.h>
#include <string.h>
#include <DS1302.h>

/* Set the appropriate digital I/O pin connections */
uint8_t CE_PIN   = 4;
uint8_t IO_PIN   = 5;
uint8_t SCLK_PIN = 6;

/* Create buffers */
char buf[50];
char day[10];

/* Create a DS1302 object */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);


void print_time()
{
  /* Get the current time and date from the chip */
  Time t = rtc.time();

  /* Name the day of the week */
  memset(day, 0, sizeof(day));  /* clear day buffer */
  switch (t.day) {
    case 1:
      strcpy(day, "Sunday");
      break;
    case 2:
      strcpy(day, "Monday");
      break;
    case 3:
      strcpy(day, "Tuesday");
      break;
    case 4:
      strcpy(day, "Wednesday");
      break;
    case 5:
      strcpy(day, "Thursday");
      break;
    case 6:
      strcpy(day, "Friday");
      break;
    case 7:
      strcpy(day, "Saturday");
      break;
  }

  /* Format the time and date and insert into the temporary buffer */
  snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
           day,
           t.yr, t.mon, t.date,
           t.hr, t.min, t.sec);

  /* Print the formatted string to serial so we can see the time */
  Serial.println(buf);
}


void setup()
{
  Serial.begin(9600);

  /* Initialize a new chip by turning off write protection and clearing the
     clock halt flag. These methods needn't always be called. See the DS1302
     datasheet for details. */
  rtc.write_protect(false);
  rtc.halt(false);

  /* Make a new time object to set the date and time */
  /*   Tuesday, May 19, 2009 at 21:16:37.            */
  Time t(2014, 2, 26, 16, 27, 37, 3);

  /* Set the time and date on the chip */
  rtc.time(t);
}


/* Loop and print the time every second */
void loop()
{
  print_time();
  delay(2000);
}

Has anyone gotten this sketch to work, or perhaps you could post a simple example of a read and write sketch?

thanks!

btw, the sketch at Arduino Playground - DS1302 prints the correct (set in code) date but it prints an error date every few Serial.prints.

e.g. its serial output:

DS1302 Real Time Clock
Version 2, March 2013
Time = 10:08:00, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 08:04:02, Date(day of month) = 10, Month = 2, Day(day of week) = 1, Year = 2009
Time = 10:08:04, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:06, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:08, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:10, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:12, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:15, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 08:08:17, Date(day of month) = 10, Month = 2, Day(day of week) = 1, Year = 2009
Time = 10:08:19, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 08:08:21, Date(day of month) = 10, Month = 2, Day(day of week) = 1, Year = 2009
Time = 10:08:23, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:25, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:27, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:29, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:31, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 08:04:33, Date(day of month) = 10, Month = 2, Day(day of week) = 1, Year = 2009
Time = 08:08:35, Date(day of month) = 10, Month = 2, Day(day of week) = 1, Year = 2009
Time = 10:08:37, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:39, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:41, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:43, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:45, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013
Time = 10:08:47, Date(day of month) = 15, Month = 4, Day(day of week) = 2, Year = 2013

I wanted to try to bit bang a write command to the DS1302 so I looked at the data sheet http://datasheets.maximintegrated.com/en/ds/DS1302.pdf , but I don't understand bits 1 - 5 (A0 - A5) of the command byte, how can you choose a register address with just 5 bits? For example is I want to write to the Year register I have to choose 0x8C, but how can I represent 0x8C with just 5 bits, am I missing something here?

This is the 'standard' clock chip read. Most I've come across all use the same address (0x68), all that changes is functionality - memory, alarms, etc.

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}

The library I use is by JeeLabs - http://news.jeelabs.org/code/

RTG.adjust() is such a pain, if it drives you crazy you may want to explore using Infrared to set the time correctly:
MIM 5383H4 Infrared Module with ATtiny85 (UNO set time/date menu sample) - Exhibition / Gallery - Arduino Forum and a reprint w/ better picture
http://www.hackster.io/rayburne/infrared-dedicated-decoder

Ray

the "RTClib.h" is for the ds1307 chip.

Yesterday I was able to write data to the YEAR register but when reading it back it did not come out correctly all the time. If the binary value written ended with a 1 the read value would come out correct, but if I would write a binary value ending with a 0, then when I was reading it back the code (arduino shiftIn) would discard the last zero, so e.g. decimal 14 is 0000 1110, but the read operation would send back only 111.

Perhaps it has something to do with the fact that DS1302 codes values in BCD and I'm missing something, or maybe my DS1302 module is faulty, I might have to get another one to make a comparison.

You should try another one.

Those printouts with faulty dates now and then is not normal. It should print the dates always right, even if you let it run for days.

Do you use a breadboard ? Perhaps there is a bad connection.
Do you use weak USB power ? Perhaps you can try a power supply to the DC jack.
Do you use an RTC module from Ebay ? They are known to cause nothing but trouble.

Do you use a breadboard ? Perhaps there is a bad connection.

Yes, but I checked all the connections.

Do you use weak USB power ? Perhaps you can try a power supply to the DC jack.

I use the 5V pin on the Uno.

Do you use an RTC module from Ebay ? They are known to cause nothing but trouble.

Well, I've gotten a lot of stuff from eBay and it worked fine. Besides this module is pretty simple, so it's either a fault in the manufacturing or something else, but I don't think it's a circuit design fault.

I'll just have to get another one and see.

Here is an example sketch. https://github.com/mikaelpatel/Cosa/blob/master/examples/Drivers/CosaDS1302/CosaDS1302.ino
It uses the Cosa DS1302 device driver and time class. It also demonstrates how to use the RAM on the device.
Interface: https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/Driver/DS1302.hh
Documentation: http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/de/d0d/classDS1302.html

Cheers!