DS1307 Real Time Clock issues.

I've managed to get the Sparkfun DS1037 RTC working over I2C, it reads in the time fine, keeps the time fine, etc. The only issue I'm having is that I can't seem to get the right time set. Searching through the forums I came across this code:

#include <Wire.h>

void setup(){

 Wire.begin();
 Serial.begin(9600);

 Wire.beginTransmission(0x68);
 Wire.send(0);
 Wire.send(0x00);         
 Wire.send(0x10);         
 Wire.send(0x80 | 0x02);   
 Wire.endTransmission();
}

Now it works fine, if you want the time to be 2:10am. When I try edit the Wire.send(0x80 | 0x02); part I keep setting the wrong time. Could someone point me in the right direction of how to figure out the proper hex values to set the time. Thanks.

Okay, so I've managed to get the proper time and day of the week set using the following code:

  Wire.beginTransmission(0x68);
  Wire.send(0);
  Wire.send(0x00);         // seconds        
  Wire.send(0x54);         // minutes
  Wire.send(0x80 | 0x09);  // hours (24hr)
  Wire.send(0x06);         // day
  Wire.send(0x29);         // date
  Wire.send(0x12);         // month
  Wire.send(0x07);         // year
  Wire.endTransmission();

Though the date returned is 47 and the month returned is 18. Any help with what the correct values should be to set those properly?

IMHO, the Arduino makes I2C interfacing doggoned darned difficult... That said, someone else wrote a working demo for the DS1307 that I have expanded on (though a few hairs went gray in the process). Perhaps this will help.

BTW... bit 7 of the hours register does NOT control the 12/24 hour aspect of the clock; it is bit 6, and when bit 6 is zero the clock is in 24-hour mode. You should download the DS1307 data sheet as you're working with the part; it shows how to use the square wave output as well as the extra (battery backed) RAM of the DS1307.

// DS1307 demo
// -- by Jon McPhalen (www.jonmcphalen.com) -- based on work by others
// -- 29 DEC 2007

// SDA pin is Analog4
// SCL pin is Analog5

#include <Wire.h>

#define DS1307 0xD0 >> 1 // shift required by Wire.h (silly...)

// DS1307 clock registers

#define R_SECS 0
#define R_MINS 1
#define R_HRS 2
#define R_WKDAY 3
#define R_DATE 4
#define R_MONTH 5
#define R_YEAR 6
#define R_SQW 7

byte second = 0x00; // default to 01 JAN 2007, midnight
byte minute = 0x00;
byte hour = 0x00;
byte wkDay = 0x02;
byte day = 0x01;
byte month = 0x01;
byte year = 0x07;
byte ctrl = 0x00;

void setup()
{
Wire.begin();
Serial.begin(9600);

second = 0x45; // demo time
minute = 0x59;
hour = 0x23;
wkDay = 0x07;
day = 0x29;
month = 0x12;
year = 0x07;
ctrl = 0x00; // disable SQW output
setClock();
}

void loop()
{
getClock();

printHex2(hour);
Serial.print(":");
printHex2(minute);
Serial.print(":");
printHex2(second);

Serial.print(" ");
printDayName(bcd2Dec(wkDay));
Serial.print(" ");

printHex2(day);
Serial.print(" ");
printMonthName(bcd2Dec(month));
Serial.print(" 20");
printHex2(year);
Serial.println();

//no need to rush
delay(1000);
}

void setClock()
{
Wire.beginTransmission(DS1307);
Wire.send(R_SECS);
Wire.send(second);
Wire.send(minute);
Wire.send(hour);
Wire.send(wkDay);
Wire.send(day);
Wire.send(month);
Wire.send(year);
Wire.send(ctrl);
Wire.endTransmission();
}

void getClock()
{
Wire.beginTransmission(DS1307);
Wire.send(R_SECS);
Wire.endTransmission();
Wire.requestFrom(DS1307, 8);
second = Wire.receive();
minute = Wire.receive();
hour = Wire.receive();
wkDay = Wire.receive();
day = Wire.receive();
month = Wire.receive();
year = Wire.receive();
ctrl = Wire.receive();
}

byte bcd2Dec(byte bcdVal)
{
return bcdVal / 16 * 10 + bcdVal % 16;
}

void printHex2(byte hexVal)
{
if (hexVal < 0x10)
Serial.print("0");
Serial.print(hexVal, HEX);
}

void printDec2(byte decVal)
{
if (decVal < 10)
Serial.print("0");
Serial.print(decVal, DEC);
}

void printDayName(byte d)
{
switch (d) {
case 1:
Serial.print("SUN");
break;
case 2:
Serial.print("MON");
break;
case 3:
Serial.print("TUE");
break;
case 4:
Serial.print("WED");
break;
case 5:
Serial.print("THU");
break;
case 6:
Serial.print("FRI");
break;
case 7:
Serial.print("SAT");
break;
default:
Serial.print("???");
}
}

void printMonthName(byte m)
{
switch (m) {
case 1:
Serial.print("JAN");
break;
case 2:
Serial.print("FEB");
break;
case 3:
Serial.print("MAR");
break;
case 4:
Serial.print("APR");
break;
case 5:
Serial.print("MAY");
break;
case 6:
Serial.print("JUN");
break;
case 7:
Serial.print("JUL");
break;
case 8:
Serial.print("AUG");
break;
case 9:
Serial.print("SEP");
break;
case 10:
Serial.print("OCT");
break;
case 11:
Serial.print("NOV");
break;
case 12:
Serial.print("DEC");
break;
default:
Serial.print("???");
}
}

Does anyone know how to interface Jon's code to a 4Bit 16x4 lcd???

Ive been trying for hours now and i just can get the sketch correct!!!

Any help would be great!!!!

VR

Okay, so I've managed to get the proper time and day of the week set using the following code:

Code:

Wire.beginTransmission(0x68);
Wire.send(0);
Wire.send(0x00); // seconds
Wire.send(0x54); // minutes
Wire.send(0x80 | 0x09); // hours (24hr)
Wire.send(0x06); // day
Wire.send(0x29); // date
Wire.send(0x12); // month
Wire.send(0x07); // year
Wire.endTransmission();

Though the date returned is 47 and the month returned is 18. Any help with what the correct values should be to set those properly?

Looks rather as though you are sending hex (hexadecimal, base 16) numbers (thats what the 0x means) and reading back decimal (base 10) numbers!

29 in hex means 2 times 16 (32) plus 9, ie 41 in decimal numbers.
Similarly 12 in hex means 1 times 16 (16) plus 2, giving 18 decimal.

A little 'bit' of practice with binary and hex will make converting 'bits' in control registers much easier.

A relevant (poor) joke:
"There are 10 types of people in the world. Those who understand binary arithmetic, and those who don't."

Here is what I use that I found somewhere in the play ground. You run the program twice, first with the RTC.set portion uncommented to set all the initial time/date variables, and then comment out that section and reload the program.

/*Reads the value from a Real Time Clock (RTC) DS1307 and displays it in the serial monitor
 *
 *Created by D. Sjunnesson 1scale1.com d.sjunnesson (at) 1scale1.com
 *
 *Created with combined information from 
 *http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1180908809
 *http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1191209057
 *
 *
 *Big credit to  mattt (please contact me for a more correct name...) from the Arduino forum 
 *which has written the main part of the library which I have modified
 *
 */

#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h> // written by  mattt on the Arduino forum and modified by D. Sjunnesson

void setup()
{
  Serial.begin(57600);
/*                              // update time/date constants and uncomment block to set new time & date
  RTC.stop();
  RTC.set(DS1307_SEC,1);        //set the seconds
  RTC.set(DS1307_MIN,50);       //set the minutes
  RTC.set(DS1307_HR,0);        //set the hours   note 24 hour clock
  RTC.set(DS1307_DOW,5);        //set the day of the week
  RTC.set(DS1307_DATE,14);      //set the date
  RTC.set(DS1307_MTH,8);        //set the month
  RTC.set(DS1307_YR,9);         //set the year   
  RTC.start();   */
}

void loop()
{

  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year 
  Serial.println();

  delay(1000);

}

Lefty

I have a RTC library for the DS1337 and some application examples
at Loading...
The library works for my NB1A board (Arduino compatible board + RTC + DAC). Should only require minor modifications for the DS1307.

I use the TWI (I2C) library from Atmel. I made some minor modifications and
added some doxygen comments.

To set the date and time --

rtc.set_date(2009, 10, 14);
rtc.set_time(9, 4, 15);

To print out the time to the serial port --

  char timestr[22];
  rtc.read_regs();
  rtc.localtime(timestr);
  Serial.print(timestr);
  Serial.print("\n");

The only thing I need to add is the epoch time conversion.

(* jcl *)


www: http://www.wiblocks.com
twitter: http://twitter.com/wiblocks
blog: http://luciani.org

As an extra note, I usually skip over the weekday setting and using this standard calc to set it automatically.

int _a,_y,_m,_d;
_a=(14-_month)/12;
_y=_year-_a;
_m=_month+12*_a-2;
_d=(_day+_y+_y/4-_y/100+_y/400+(31*_m/12))%7;
_d++;

The _month,_day,_year are the RTC settings used then the _d is the weekday from 1-7 with 1 being Sunday. The last ++ puts it in the 1-7 range because the 1307 starts at 1 instead of 0.