Hello,
I am doing a project with ethernet shield (5100) and DS1307 RTC,
I had 2 problems, the first one was the the arduino would just stop responding every few couple of hours, apparently it has gotten alot better after connecting it to an external power source. although it still freeze after 2 days~ (last time I checked)
the second one is that after about 1.5 days the RTC has started to give garbage. instead of the time it responded with 450/521/2030
or something similar.
I cant find the problem.. did anyone had the same or similar problems?
Why does the Ethernet freeze (I use the Arduino "Official" Ethernet Library) and for the rtc a library called "DS1307RTC" I can post it here if it is necessary...
How come the ethernet freezes after 2 days, and how can I prevent it?
I have this part of the code that syncs the RTC with arduino. that is the only part of the code that handles the RTC (Except for writing it)
does it look ok?
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");
I'm looking at the library right now, but it is not easy to understand.
You could have a ram or stack overflow, or the Time library could have problems with rollover.
You check timeStatus() for timeSet, but can you check which value it is ? Is it "timeNotSet" or "timeNeedsSync".
If it is "timeNeedsSync" you might just ignore that value and try once more.
You might have a rollover problem in you own code.
If you use millis() for example.
Can you measure somehow how long it takes to freeze ? Is it the same every time ?
I am having some freezing problems with my arduino uno+ethernet+ds1037. I believe the problem lies within the ds1037 as it sometimes give me garbage which is probably the source for the freezing.
I just updated the code so when it converts the time to decimal it will never give garbage, so in the worst case scenario it will return 0.
I wonder if this fix will work..
/*
* DS1307RTC.h - library for DS1307 RTC
Copyright (c) Michael Margolis 2009
This library is intended to be uses with Arduino Time.h library functions
The library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 Dec 2009 - Initial release
5 Sep 2011 updated for Arduino 1.0
*/
#include <Wire.h>
#include "DS1307RTC.h"
#define DS1307_CTRL_ID 0x68
DS1307RTC::DS1307RTC()
{
Wire.begin();
}
// PUBLIC FUNCTIONS
time_t DS1307RTC::get() // Aquire data from buffer and convert to time_t
{
tmElements_t tm;
read(tm);
return(makeTime(tm));
}
void DS1307RTC::set(time_t t)
{
tmElements_t tm;
breakTime(t, tm);
tm.Second |= 0x80; // stop the clock
write(tm);
tm.Second &= 0x7f; // start the clock
write(tm);
}
// Aquire data from the RTC chip in BCD format
void DS1307RTC::read( tmElements_t &tm)
{
Wire.beginTransmission(DS1307_CTRL_ID);
#if ARDUINO >= 100
Wire.write((uint8_t)0x00);
#else
Wire.send(0x00);
#endif
Wire.endTransmission();
// request the 7 data fields (secs, min, hr, dow, date, mth, yr)
Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields);
#if ARDUINO >= 100
tm.Second = bcd2dec(Wire.read() & 0x7f);
tm.Minute = bcd2dec(Wire.read() );
tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock
tm.Wday = bcd2dec(Wire.read() );
tm.Day = bcd2dec(Wire.read() );
tm.Month = bcd2dec(Wire.read() );
tm.Year = y2kYearToTm((bcd2dec(Wire.read())));
#else
tm.Second = bcd2dec(Wire.receive() & 0x7f);
tm.Minute = bcd2dec(Wire.receive() );
tm.Hour = bcd2dec(Wire.receive() & 0x3f); // mask assumes 24hr clock
tm.Wday = bcd2dec(Wire.receive() );
tm.Day = bcd2dec(Wire.receive() );
tm.Month = bcd2dec(Wire.receive() );
tm.Year = y2kYearToTm((bcd2dec(Wire.receive())));
#endif
}
void DS1307RTC::write(tmElements_t &tm)
{
Wire.beginTransmission(DS1307_CTRL_ID);
#if ARDUINO >= 100
Wire.write((uint8_t)0x00); // reset register pointer
Wire.write(dec2bcd(tm.Second)) ;
Wire.write(dec2bcd(tm.Minute));
Wire.write(dec2bcd(tm.Hour)); // sets 24 hour format
Wire.write(dec2bcd(tm.Wday));
Wire.write(dec2bcd(tm.Day));
Wire.write(dec2bcd(tm.Month));
Wire.write(dec2bcd(tmYearToY2k(tm.Year)));
#else
Wire.send(0x00); // reset register pointer
Wire.send(dec2bcd(tm.Second)) ;
Wire.send(dec2bcd(tm.Minute));
Wire.send(dec2bcd(tm.Hour)); // sets 24 hour format
Wire.send(dec2bcd(tm.Wday));
Wire.send(dec2bcd(tm.Day));
Wire.send(dec2bcd(tm.Month));
Wire.send(dec2bcd(tmYearToY2k(tm.Year)));
#endif
Wire.endTransmission();
}
// PRIVATE FUNCTIONS
// Convert Decimal to Binary Coded Decimal (BCD)
uint8_t DS1307RTC::dec2bcd(uint8_t num)
{
return ((num/10 * 16) + (num % 10));
}
// Convert Binary Coded Decimal (BCD) to Decimal
uint8_t DS1307RTC::bcd2dec(uint8_t num)
{
if((((num/16 * 10) + (num % 16))>=0 && ((num/16 * 10) + (num % 16))<=60) || (((num/16 * 10) + (num % 16))>=2010 && ((num/16 * 10) + (num % 16))<=2030))
return ((num/16 * 10) + (num % 16));
else
return(0);
}
DS1307RTC RTC = DS1307RTC(); // create an instance for the user
The DS1307 I think you meant, is an I²C device. The I²C bus operates around the principals of the devices being open-drain (or open collector for ancient TTL devices).
As a result the bus requires pull-up resistors to make it work properly.
Add 10K resistors between SCL and +5V, and SDA and +5V.