Go Down

Topic: Can't get ds1307 to set time (Read 22622 times) previous topic - next topic

Bizzare

So I'm new to arduino and programming, I tried to get a DS1307 working on my arduino for turning on relays based on the current time ,and for data logging purposes.  But I can't get the RTC to set the correct time.  It's a Tiny RTC DS1307 from ebay, I have it installed on an arduiono mega2560.  The vcc on the rtc is connected to 5v, gnd to gnd, sda to pin 20 (sda pin on mega), and sdl to pin 21 (sdl pin on mega).  When I run the TimeRTC example from the Time library:
Code: [Select]
/*
* TimeRTC.pde
* example code illustrating Time library with Real Time Clock.
*
*/

#include <Time.h> 
#include <Wire.h> 
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");     
}

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

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

The serial port shows:
RTC has set the system time
17:18:09 17 4 2037
17:18:10 17 4 2037
17:18:11 17 4 2037
17:18:12 17 4 2037
17:18:13 17 4 2037
17:18:14 17 4 2037
17:18:15 17 4 2037
17:18:16 17 4 2037
17:18:17 17 4 2037
17:18:18 17 4 2037


Which is all fine and dandy except it's not 5:18PM April 17, 2037.  If I try to set the time over the serial port with a unix stamp, like T1377641703 for 5:15PM 8/27/2013, nothing happens and the arduino continues printing out times from 24 years in the future.

If I try running the DS1307 example from RTClib:
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);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  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);
}

it prints out this:
RTC is NOT running!
2165/165/165 165:165:85
since midnight 1/1/1970 = 2028820689s = 23481d
now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
since midnight 1/1/1970 = 2028820689s = 23481d
now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
since midnight 1/1/1970 = 2028820689s = 23481d
now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
since midnight 1/1/1970 = 2028820689s = 23481d
now + 7d + 30s: 2034/4/23 17:18:39

I've looked around on the web trying to find out how to fix such a basic problem, but haven't found a solution.  What am I overlooking?  Maybe my RTC is broke?

nickgammon

Is the backup battery installed?
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Bizzare

#2
Aug 28, 2013, 12:52 am Last Edit: Aug 28, 2013, 01:35 am by Bizzare Reason: 1

Is the backup battery installed?


Yes the battery is installed.

nickgammon

Can you run the I2C scanner on this page and copy and paste what it returns please?

http://www.gammon.com.au/i2c
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Nick_Pyner

Here is one that works, and that is all it does. Preset the time, run it, use the reset to set it. The time is set when the reset button is released.


Code: [Select]
//Arduino 1.0+ Only
//Arduino 1.0+ Only
// pre-set the time in the void then use reset button to set it!

#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
printDate();
Serial.println("loopstart");
}

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

void setDateTime(){

  byte second =      30; //0-59
  byte minute =      24; //0-59
  byte hour =        0; //0-23
  byte weekDay =     5; //1-7
  byte monthDay =    19; //1-31
  byte month =       4; //1-12
  byte year  =       13; //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);
}

Bizzare


Can you run the I2C scanner on this page and copy and paste what it returns please?

http://www.gammon.com.au/i2c



So running that scanner gave this response:

I2C scanner. Scanning ...
Found address: 80 (0x50)
Done.
Found 1 device(s).

Which I assume means the device is connected and working correctly?
And I forgot to add that the RTC is the only thing connected to the arduino currently.


Here is one that works, and that is all it does. Preset the time, run it, use the reset to set it. The time is set when the reset button is released.


Code: [Select]
//Arduino 1.0+ Only
//Arduino 1.0+ Only
// pre-set the time in the void then use reset button to set it!

#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
printDate();
Serial.println("loopstart");
}

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

void setDateTime(){

  byte second =      30; //0-59
  byte minute =      24; //0-59
  byte hour =        0; //0-23
  byte weekDay =     5; //1-7
  byte monthDay =    19; //1-31
  byte month =       4; //1-12
  byte year  =       13; //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);
}



When I ran this sketch I got this on the serial monitor:
165/165/165     45:165:165
loopstart
165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165
....

Pushing the reset button on the arduino didn't set the time.

Thanks for ya'lls help so far!

JChristensen


So running that scanner gave this response:

I2C scanner. Scanning ...
Found address: 80 (0x50)
Done.
Found 1 device(s).

Which I assume means the device is connected and working correctly?
And I forgot to add that the RTC is the only thing connected to the arduino currently.


There's a problem. The address should be 0x68.

Can you give us a link to the RTC module?

And maybe a schematic or photo of the wiring?

Nick_Pyner



And I forgot to add that the RTC is the only thing connected to the arduino currently.

When I ran this sketch I got this on the serial monitor:
165/165/165     45:165:165



I recognise that you only have the RTC connected. Nonetheless, I think that sort of output hints at inadequate power. Are you running off USB or a wallwart?

nickgammon

Code: [Select]

165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165
165/165/165     45:165:165


This is basically saying you are not communicating with the RTC. I2C reads 0xFF if there is nothing available and the RTC library does not check if anything is available:

Code: [Select]

DateTime RTC_DS1307::now() {
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send((byte) 0);
  Wire.endTransmission();
 
  Wire.requestFrom(DS1307_ADDRESS, 7);
  uint8_t ss = bcd2bin(Wire.receive() & 0x7F);
  uint8_t mm = bcd2bin(Wire.receive());
  uint8_t hh = bcd2bin(Wire.receive());
  Wire.receive();
  uint8_t d = bcd2bin(Wire.receive());
  uint8_t m = bcd2bin(Wire.receive());
  uint16_t y = bcd2bin(Wire.receive()) + 2000;
 
  return DateTime (y, m, d, hh, mm, ss);
}


Since 0xFF is 255, and bcd2bin does this:

Code: [Select]
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }


If you substitute 255 you get:

Code: [Select]
255 - (6 * floor (255 / 16)) = 165


So, it isn't talking to it. This is confirmed by the fact that the I2C scanner did not return the correct address.

Are you sure it's a DS1307?
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Bizzare



So running that scanner gave this response:

I2C scanner. Scanning ...
Found address: 80 (0x50)
Done.
Found 1 device(s).

Which I assume means the device is connected and working correctly?
And I forgot to add that the RTC is the only thing connected to the arduino currently.


There's a problem. The address should be 0x68.

Can you give us a link to the RTC module?

And maybe a schematic or photo of the wiring?


Link to RTC I'm using:  http://www.ebay.com/itm/SainSmart-Arduino-I2C-RTC-DS1307-AT24C32-Real-Time-Clock-Module-For-AVR-ARM-PIC-/270934150322?pt=LH_DefaultDomain_0&hash=item3f14ef0cb2

Whipped this out on fritz, first time using so if I did it wrong please tell me  :smiley-roll-blue:





And I forgot to add that the RTC is the only thing connected to the arduino currently.

When I ran this sketch I got this on the serial monitor:
165/165/165     45:165:165



I recognise that you only have the RTC connected. Nonetheless, I think that sort of output hints at inadequate power. Are you running off USB or a wallwart?


The arduino is running off a USB from my PC.



So, it isn't talking to it. This is confirmed by the fact that the I2C scanner did not return the correct address.

Are you sure it's a DS1307?


I don't know how to tell by looking at it if it's a DS1307 or not, but that's what it was sold as.

Nick_Pyner



The arduino is running off a USB from my PC.

I don't know how to tell by looking at it if it's a DS1307 or not, but that's what it was sold as.


It's a DS1307. I have four of those. You might try putting a meter between 5v and ground at the module

Nick_Pyner

Pins 20 and 21 are the standard pins for SDA SCL on a Mega, as clearly marked, and the connection illustrated in Reply #9 is 100% kosher.

Bizzare


From the ebay picture, it looks like the same board as this one from DFRobot:
http://www.dfrobot.com/index.php?route=product/product&product_id=879

Perhaps you could try their example software.
Otherwise, I would guess you have either a bad connection or a defective board.


That didn't work either, get this on monitor:
85 85 45 7 45 45 2165
85 85 45 7 45 45 2165
85 85 45 7 45 45 2165
85 85 45 7 45 45 2165
....

I'm thinking my board is defective.  I'm gonna order a new one and see if that works.  Thanks for you help guys.

nickgammon

Try pull-up resistors.

http://www.gammon.com.au/i2c
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

dannable

Just out of curiosity, what happens if you change the 0x68 in your program with 0x50?

I'm sure I've come across this on the forums before - try doing a search for 0x50.
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

Go Up