I bought an rtc on ebay that doesn't use the standard resistor values, to use it successfully the programming approach needs to be changed from reading all 7 or 8 bytes at a time to only reading 1. If I don't do this, I get garbage every so often as you mentioned. Try this:
// for DS1307 RTC
struct DateType
{
int yr;
uint8_t mo;
uint8_t dy;
uint8_t hr;
uint8_t mn;
uint8_t sc;
};
DateType CustomDate;
boolean RTC_State_ON;
int RTCBaseYear = 2000; // adjust as needed
const uint8_t RTC_YEAR = 6;
const uint8_t RTC_MONTH = 5;
const uint8_t RTC_DAY = 4;
const uint8_t RTC_HOUR = 2;
const uint8_t RTC_MINUTE = 1;
const uint8_t RTC_SECOND = 0;
uint8_t ReadRTCByte(uint8_t adr)
{
uint8_t data;
Wire.beginTransmission(0x68);
Wire.write(adr);
Wire.endTransmission();
Wire.requestFrom(0x68,1);
while (Wire.available()) data=Wire.read();
return data;
}
void WriteRTCByte(uint8_t adr, uint8_t data)
{
Wire.beginTransmission(0x68);
Wire.write(adr);
Wire.write(decToBcd(data));
Wire.endTransmission();
}
uint8_t GetRTCData(uint8_t adr, uint8_t validbits)
{
uint8_t data;
// read using wire library
data = ReadRTCByte(adr);
// adjust the return value depending
// on the number of valid bits
data=data & 0xff >> (8-validbits);
return(bcdToDec(data));
}
// convert normal decimal numbers to binary coded decimal
uint8_t decToBcd(uint8_t val)
{
return ((val/10*16) + (val%10));
}
// convert binary coded decimal to normal decimal numbers
uint8_t bcdToDec(uint8_t val)
{
return ((val/16*10) + (val%16));
}
uint8_t GetSecondsFromRTC()
{
int a;
if (RTC_State_ON == false)
StartRTC();
a = (int)GetRTCData(RTC_SECOND,7);
return(a);
}
void GetDateAndTimeFromRTC()
{
if (RTC_State_ON == false)
StartRTC();
// date
CustomDate.yr = (int) GetRTCData(RTC_YEAR,8) + RTCBaseYear;
CustomDate.mo = GetRTCData(RTC_MONTH,5);
CustomDate.dy = GetRTCData(RTC_DAY,6);
// time
CustomDate.hr = GetRTCData(RTC_HOUR,6);
CustomDate.mn = GetRTCData(RTC_MINUTE,7);
CustomDate.sc = GetRTCData(RTC_SECOND,7);
}
void SetRTCTime(uint8_t h, uint8_t m, uint8_t s)
{
if (RTC_State_ON == false)
StartRTC();
WriteRTCByte(RTC_SECOND,s);
WriteRTCByte(RTC_MINUTE,m);
WriteRTCByte(RTC_HOUR,h);
}
void SetRTCDate(uint8_t mo, uint8_t d, int y)
{
if (RTC_State_ON == false)
StartRTC();
WriteRTCByte(RTC_YEAR,(uint8_t) y-RTCBaseYear);
WriteRTCByte(RTC_MONTH,mo);
WriteRTCByte(RTC_DAY,d);
}
void StartRTC()
{
Wire.begin();
RTC_State_ON = true;
}
Hope that helps.