Go Down

Topic: RealTimeClock does not allow a date year > 2012! (Read 342 times) previous topic - next topic

Davste

Hi, I'm trying to update the time on my RTC chip using the DS1307 library: http://libds1307.googlecode.com/files/DS1307.zip

When I try setting the time to anything from 2000 to 2012, it works. When I use a date greater than 2012, it just resets it back to 2000. Any idea why this might be?

Script:
Code: [Select]
#include <Wire.h>
#include <DS1307.h>

int rtc[7];

void setup()
{

  Serial.begin(115200);
 
  RTC.stop();
  RTC.set(DS1307_SEC,0);
  RTC.set(DS1307_MIN,0);
  RTC.set(DS1307_HR,0);
  RTC.set(DS1307_DOW,0);
  RTC.set(DS1307_DATE,0);
  RTC.set(DS1307_MTH,0);
  RTC.set(DS1307_YR,12); // << Changing this to 2000 to 2012 works, 2013 onwards does not.
  RTC.start();
 
}

void loop()
{
  RTC.get(rtc,true);

  for(int i=0; i<7; i++)
  {
    Serial.print(rtc[i]);
    Serial.print(" ");
  }
  Serial.println();

  delay(1000);

}


Output (12 as year):
Quote
0 0 0 0 0 0 2012
1 0 0 0 0 0 2012
2 0 0 0 0 0 2012
3 0 0 0 0 0 2012
4 0 0 0 0 0 2012


Output (13 as year):
Quote
0 0 0 0 0 0 2000
1 0 0 0 0 0 2000
2 0 0 0 0 0 2000
3 0 0 0 0 0 2000
4 0 0 0 0 0 2000



I'm using an Arduino RTC DS1307 AT24C32 (from here: http://www.ebay.co.uk/itm/170794819927).
I have wired it according to the diagram, but since I have an Arduino Mega 2560, pins 4 and 5 are now 20 (SDA) and 21 (SCL).

Thanks!

johncc

#1
Feb 05, 2013, 12:46 am Last Edit: Feb 05, 2013, 12:48 am by johncc Reason: 1
Hmm there does seem to be a bug with the set(int, int) method:
Code: [Select]
 case DS1307_MTH:
   if(v<13 && v>-1)
   {
rtc_bcd[DS1307_MTH]=((v / 10)<<4) + (v % 10);
   }
   break;
 case DS1307_YR:
   if(v<13 && v>-1)
   {
rtc_bcd[DS1307_YR]=((v / 10)<<4) + (v % 10);
   }
   break;
 } // end switch


Looks like they may have just (inadvisably) copied that conditional from the set-month case.  You could change that line in your DS1307.cpp file to something like
Code: [Select]
if (v<100 && v>-1)    // n.b. this will break in year 2100

That seems to be a different RTC library than what came with my Time library (1.0.2)

Cheers,
John

Nick_Pyner

Here is what I use. I added the dispaly but you can do without it.

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 <PCD8544.h>
static PCD8544 lcd;
#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527

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

void loop(){
      lcd.clear();
  printDate();
 
  delay(1000);
}

void setDateTime(){

  byte second =      0; //0-59
  byte minute =       36; //0-59
  byte hour =        0; //0-23
  byte weekDay =     5; //1-7
  byte monthDay =    4; //1-31
  byte month =       1; //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);
}
/*
  lcd.print(monthDay);
  lcd.print("/");
  lcd.print(month);
  lcd.print("/");
  lcd.print(year);
 
  lcd.setCursor(0,1);
  lcd.print(hour);
  lcd.print(":");
  lcd.print(minute);
  lcd.print(":");
    if(second <10)
  {
    lcd.print("0");
  }
  lcd.print(second);
}*/

Davste

Thanks everyone! I've used Nick's code without the LCD and it worked well :)

Go Up