Go Down

Topic: DS1307 RTC resetting unexpectedly (Read 4 times) previous topic - next topic

ricm

Jul 15, 2012, 08:53 pm Last Edit: Jul 15, 2012, 09:20 pm by ricm Reason: 1
I have a DS1307 & AT24C32 chip combination on a small RTC board bought via eBay. This is billed as "version 2" and has a slightly smaller crystal than most of the others on sale from China.

I had to add edge connectors - no problem, but because of the battery overlapping the solder pads, the battery had to be removed to solder the connectors. Connections were then made to the Mega 2560, powered by the USB: +5V and Gnd to the same pins on the 2560; SDA and SCL again to the equivalent pins in the "Communication" connectors.

I have tried a number of programs, including ones with specific libraries, but have been unable to get this board to function properly. For the purposes of describing this problem here I have reverted to the simplest possible code, first to set the time and secondly to read the time. This code is from here: http://bildr.org/2011/03/ds1307-arduino/

The code to set the time is here:

Code: [Select]
//Arduino 1.0+ Only
//Arduino 1.0+ Only

#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527

void setup(){
 Wire.begin();
 Serial.begin(9600);
 setDateTime(); //MUST CONFIGURE IN FUNCTION
}

void loop(){
 printDate();
 delay(1000);
}

void setDateTime(){

 byte second =      00; //0-59
 byte minute =      57; //0-59
 byte hour =        18; //0-23
 byte weekDay =     1; //1-7
 byte monthDay =    15; //1-31
 byte month =       7; //1-12
 byte year  =       12; //0-99

 Wire.beginTransmission(DS1307_ADDRESS);
 Wire.write(zero); //stop Oscillator

 Wire.write(decToBcd(second));
 Wire.write(decToBcd(minute));
 Wire.write(decToBcd(hour));
 Wire.write(decToBcd(weekDay));
 Wire.write(decToBcd(monthDay));
 Wire.write(decToBcd(month));
 Wire.write(decToBcd(year));

 Wire.write(zero); //start

 Wire.endTransmission();

}

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
 return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
 return ( (val/16*10) + (val%16) );
}

void printDate(){

 // Reset the register pointer
 Wire.beginTransmission(DS1307_ADDRESS);
 Wire.write(zero);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_ADDRESS, 7);

 int second = bcdToDec(Wire.read());
 int minute = bcdToDec(Wire.read());
 int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
 int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
 int monthDay = bcdToDec(Wire.read());
 int month = bcdToDec(Wire.read());
 int year = bcdToDec(Wire.read());

 //print the date EG   3/1/11 23:59:59
 Serial.print(month);
 Serial.print("/");
 Serial.print(monthDay);
 Serial.print("/");
 Serial.print(year);
 Serial.print(" ");
 Serial.print(hour);
 Serial.print(":");
 Serial.print(minute);
 Serial.print(":");
 Serial.println(second);

}


This code is compiled and downloaded ONCE just 10 seconds before the due time (approximately the time taken to transfer). This is a crude - but for testing purposes, acceptable approximation to real world time.

Without disconnecting or resetting or anything else, the following READ code is compiled and sent to the 2560:

Code: [Select]
//Arduino 1.0+ Only
//Arduino 1.0+ Only

#include "Wire.h"
#define DS1307_ADDRESS 0x68

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

void loop(){
 printDate();
 delay(1000);
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
 return ( (val/16*10) + (val%16) );
}

void printDate(){

 // Reset the register pointer
 Wire.beginTransmission(DS1307_ADDRESS);

 byte zero = 0x00;
 Wire.write(zero);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_ADDRESS, 7);

 int second = bcdToDec(Wire.read());
 int minute = bcdToDec(Wire.read());
 int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
 int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
 int monthDay = bcdToDec(Wire.read());
 int month = bcdToDec(Wire.read());
 int year = bcdToDec(Wire.read());

 //print the date EG   3/1/11 23:59:59
 Serial.print(month);
 Serial.print("/");
 Serial.print(monthDay);
 Serial.print("/");
 Serial.print(year);
 Serial.print(" ");
 Serial.print(hour);
 Serial.print(":");
 Serial.print(minute);
 Serial.print(":");
 Serial.println(second);

}


This should ensure the setting of the RTC time occurs only once and that, from then on, reading the RTC should give a reasonable approximation to real-world time.

The problem that I have is that the clock starts from 7/15/12 18:57:00 and increments every second to 7/15/12 18:57:19 it then resets back to 7/15/12 18:57:00. When the RTC is unplugged from the Arduino or the Arduino is powered down the time always starts from 7/15/12 18:57:00 and resets again at 7/15/12 18:57:19, never getting beyond this time. If I set a different time the same kind of thing happens, resetting after a certain interval, not necessarily 19 seconds, but always resetting at an interval less than 5 minutes.

I have removed the battery to reset the RTC (the read then shows 0/0/0 0:0:80). I have replaced the battery just in case. I have downloaded the read program twice (in another, different example, the author reported that two sends were required to get the RTC to start properly).

I am left with the thought that a) there is some register set somewhere that is causing the RTC to act more as an interval timer than a RTC (but have found no documentation for such a register) or b) the RTC board is duff.

Before I contact the supplier has anyone any further thoughts as to anything I may have missed?

Regards,
Ric

I should add that the board is fitted with R2 and R3 which appear to be the required pull-up resistors for SDA and SCL. If I add additional 4K7 pull-ups the result is the same as without them. In other words: I don't think the pull-ups is the issue here.

Riva

Hi ricm,

I can see no problems with your clock reading code.
Have you tried running the clock without the battery in? It will not maintain the time once power is removed but will it keep counting?
Do you have a link for the eBay item and a schematic of how you have connected to the Mega.

ricm

#2
Jul 16, 2012, 06:34 pm Last Edit: Jul 16, 2012, 06:44 pm by ricm Reason: 1
Hi Riva,

Thanks very much for replying. I have just tried running the clock without a battery in. Results are the same as before with no improvement or deterioration. I am running a different "Read" program from the one posted (attempting to touch all the bases here) and, as before, it resets after the 19th second.

The eBay item is here: http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=170849904275&ssPageName=ADME:X:RTQ:GB:1123

Attached are three schematics. The first shows the board connections, the second shows the connections to the mega 2560 without pull-ups; the third shows the connection to the mega 2560 with 4K7 pull-ups.

I am happy there are no solder bridges and that the joints are good. I'm happy that the connections are correct. Indeed if it were not so I would be unlikely to get ANY data. Period. The battery is obviously OK even to the extent of not dragging down the supply rail when present.

Appreciated your help,

Kind regards, Ric

PaulS

Quote
I am running a different "Read" program from the one posted (attempting to touch all the bases here) and, as before, it resets after the 19th second.

And that code looks like?

If it calls bcdToDec(), too, I'd suspect something in that function is causing issues. Try removing the calls to bcdToDec() and see if that gets you past 19 seconds. If the new code doesn't use bcdToDec(), then never mind.

ricm

The new code is here:

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


It uses a library called RTClib from jeelabs.org. Here is RTClib.h:

Code: [Select]
// Code by JeeLabs http://news.jeelabs.org/code/
// Released to the public domain! Enjoy!

// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
class DateTime {
public:
   DateTime (uint32_t t =0);
   DateTime (uint16_t year, uint8_t month, uint8_t day,
               uint8_t hour =0, uint8_t min =0, uint8_t sec =0);
   DateTime (const char* date, const char* time);
   uint16_t year() const { return 2000 + yOff; }
   uint8_t month() const { return m; }
   uint8_t day() const { return d; }
   uint8_t hour() const { return hh; }
   uint8_t minute() const { return mm; }
   uint8_t second() const { return ss; }
   uint8_t dayOfWeek() const;

   // 32-bit times as seconds since 1/1/2000
   long secondstime() const;
   // 32-bit times as seconds since 1/1/1970
   uint32_t unixtime(void) const;

protected:
   uint8_t yOff, m, d, hh, mm, ss;
};

// RTC based on the DS1307 chip connected via I2C and the Wire library
class RTC_DS1307 {
public:
 static uint8_t begin(void);
   static void adjust(const DateTime& dt);
   uint8_t isrunning(void);
   static DateTime now();
};

// RTC using the internal millis() clock, has to be initialized before use
// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?)
class RTC_Millis {
public:
   static void begin(const DateTime& dt) { adjust(dt); }
   static void adjust(const DateTime& dt);
   static DateTime now();

protected:
   static long offset;
};


...cont/ next post

Go Up