Go Down

Topic: RealTimeClock does not allow a date year > 2012! (Read 353 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy