DS1307 Real Time Clock

I got my samples from Maxim today. I used the sketch from: http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock The problem here was that it didn't say how to connect to the Arduino, so all I got was 0:0:0 0/0/0. I finally figured it out though. In case anyone else is trying one of these out, analog pin 4 connects to SDA (pin 5 on the DS1307) and analog pin 5 connects to SCL (pin 6 on the DS1307). Other libraries/sketches may use different pins, but for the one linked above, this is the correct connection. I was really scratching my head for a while. Works great now. Can't wait to integrate into a project.

Other libraries/sketches may use different pins,

The don't because they can't, well not without emulating the chip's I2C hardware in software.

So I’ve been using the clock and it works great. I have a new question, though. I want to use the onboard RAM on the DS1307. Attached is my sketch, which is a modified sketch from RTC1307 - Real Time Clock - Combustory .

I’ve tried sending just one byte to memory and then retrieving that byte from memory, but I only get 255. When I do a memory dump, it gives me 255 for the first 32 and 0 for the rest. Is there a glaring mistake that someone can point out to me?

/*
 * RTC Control v.01
 * by <http://www.combustory.com> John Vaughters
 * Credit to:
 * Maurice Ribble - http://www.glacialwanderer.com/hobbyrobotics for RTC DS1307 code
 *
 * With this code you can set the date/time, retreive the date/time and use the extra memory of an RTC DS1307 chip.  
 * The program also sets all the extra memory space to 0xff.
 * Serial Communication method with the Arduino that utilizes a leading CHAR for each command described below. 
 *
 * Commands:
 * T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) - T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) - T Sets the date of the RTC DS1307 Chip. 
 * Example to set the time for 02-Feb-09 @ 19:57:11 for the 3 day of the week, use this command - T1157193020209
 * Q(1-2) - (Q1) Memory initialization  (Q2) RTC - Memory Dump
 *
 * If command = "C" RTC1307 Get Time and Date
 * If command = "P" RTC1307 Get Time and Date and put in memory
 * If command = "G" RTC1307 Get Time and Date from memory and display
 * Analog pin 4 - SDA (pin 5 on DS1307)
 * Analog pin 5 - SCL (pin 6 on DS1307)
 */   

#include <Wire.h>

int clockAddress = 0x68;  // This is the I2C address
int command = 0;  // This is the command char, in ascii form, sent from the serial port     
long previousMillis = 0;  // will store last time Temp was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte test; 

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

  // 1) Sets the date and time on the ds1307
  // 2) Starts the clock
  // 3) Sets hour mode to 24 hour clock
  // Assumes you're passing in valid numbers, 
  // Probably need to put in checks for valid numbers.

void setDateDs1307()                
{
                              // Use of (byte) type casting and ascii math to achieve result.  
  second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); 
  minute = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hour  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  dayOfWeek = (byte) (Serial.read() - 48);
  dayOfMonth = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year= (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(clockAddress);
  Wire.send(0x00);
  Wire.send(decToBcd(second));  // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));    // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();
}

                              // Gets the date and time from the ds1307 and prints result

void getDateDs1307() {        // Reset the register pointer
  Wire.beginTransmission(clockAddress);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(clockAddress, 7);

                              // A few of these need masks because certain bits are control bits

  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  
                              // Need to change this if 12 hour am/pm
  hour       = bcdToDec(Wire.receive() & 0x3f);  
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());

  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(year, DEC);

}

void getTimeDs1307() {        // Reset the register pointer
  Wire.beginTransmission(clockAddress);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(clockAddress, 7);

  second     = (Wire.receive() & 0x7f);
  minute     = (Wire.receive());
  hour       = (Wire.receive() & 0x3f);  
  dayOfWeek  = (Wire.receive());
  dayOfMonth = (Wire.receive());
  month      = (Wire.receive());
  year       = (Wire.receive());
}

void putMemDs1307() {
  Wire.beginTransmission(clockAddress);
  Wire.send(0x08);
  Wire.endTransmission();

  Wire.send(1010);  

}

void getMemDs1307() {
  Wire.beginTransmission(clockAddress);
  Wire.send(0x08);
  Wire.endTransmission();

  Wire.requestFrom(clockAddress, 1);


  second     = Wire.receive();

  Serial.print(second, DEC);

}  

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

}

void loop() {
  if (Serial.available()) {   // Look for char in serial que and process if found
    command = Serial.read();
    if (command == 84) {      //If command = "T" Set Date
      setDateDs1307();
      getDateDs1307();
      Serial.println(" ");
    }
    else if(command == 67){ //If command = "C" RTC1307 Get Time and Date
      getDateDs1307();
      Serial.println(" ");
    }
    else if(command == 80){ //If command = "P" RTC1307 Get Time and Date and put in memory
      getTimeDs1307();
      putMemDs1307();
      Serial.println(" ");
    }
    else if(command == 71){ //If command = "G" RTC1307 Get Time and Date from memory and display
      getMemDs1307();
      Serial.println(" ");
    }
    
    else if (command == 81) { //If command = "Q" RTC1307 Memory Functions
      delay(100);     
      if (Serial.available()) {
        command = Serial.read(); 
        
                              // If command = "1" RTC1307 Initialize Memory - All Data will be set to 255 (0xff).  
                              // Therefore 255 or 0 will be an invalid value.  
        if (command == 49) { 
          
                              // 255 will be the init value and 0 will be cosidered an error that 
                              // occurs when the RTC is in Battery mode. 
          Wire.beginTransmission(clockAddress);
          
                              // Set the register pointer to be just past the date/time registers.
          Wire.send(0x08);  
          for (int i = 1; i <= 27; i++) {
            Wire.send(0xff);
            delay(100);
          }   
          Wire.endTransmission();
          getDateDs1307();
          Serial.println(": RTC1307 Initialized Memory");
        }
        else if (command == 50) {      //If command = "2" RTC1307 Memory Dump
          getDateDs1307();
          Serial.println(": RTC 1307 Dump Begin");
          Wire.beginTransmission(clockAddress);
          Wire.send(0x00);
          Wire.endTransmission();
          Wire.requestFrom(clockAddress, 64);
          for (int i = 1; i <= 64; i++) {
            test = Wire.receive();
            Serial.print(i);
            Serial.print(":");
            Serial.println(test, DEC);
          }
          Serial.println(" RTC1307 Dump end");
        } 
      }  
    }
    Serial.print("Command: ");
    Serial.println(command);  // Echo command CHAR in ascii that was sent
  }

  command = 0;                // reset command                  
  delay(100);
}

Okay, I figured it out. I had some commands out of order. I was finally able to get the time entered into memory and then could return it out of memory for display. This was the step I've been needing to learn so I can move toward logging events.

Hi “flyboy” - can you read all 56bytes from memory? I can read the first 30 bytes, but past that, i cannot go.

In the code posted below (to initialize the memory), why is it “i<=27”, why is the memory not initialized up to 56? am I missing something?

Thanks for your help!

Wire.send(0x08);
for (int i = 1; i <= 27; i++) {
Wire.send(0xff);
delay(100);
}
Wire.endTransmission();

I'm not sure why that is there. I used the code from SparkFun here: http://wiring.org.co/learning/libraries/realtimeclock.html and then made some changes to fit my needs. I have since learned to write to certain locations. I can change the time and date without using serial on the computer as their code does. It is a good starting point so you don't have to re-invent the wheel.

Maybe someone else knows why it is written that way.

You could try one of these guys: RTC Control v.01 by John Vaughters Credit to: Maurice Ribble - http://www.glacialwanderer.com/hobbyrobotics for RTC DS1307 code

I have similar problem with DS1307. Writing past 32 bytes of memory addresses seem to be unsuccessful as zeroes are returned if read from these upper addresses.
Is there any clue, why is it like that?
Code is here:

boolean DS1307memwrite(byte startaddress, byte endaddress) {
  //Set DS1397 I2C chip address
  byte DS1307_CTRL_ID = B01101000;
  byte pointer = 0; //configarray pointer
  byte tmNbrFields = endaddress-startaddress;
  byte address = startaddress;
  
  while (pointer <= endaddress){
    //Writing first half of integer
    Wire.beginTransmission(DS1307_CTRL_ID);
    Wire.send(startaddress);
    Wire.send(highByte(configdata[pointer]));
    Wire.endTransmission();
    //Writing a second half of integer 
    startaddress++;
    Wire.beginTransmission(DS1307_CTRL_ID);
    Wire.send(startaddress);
    Wire.send(lowByte(configdata[pointer]));
    Wire.endTransmission();
    startaddress++;
    pointer++;
  }
  return true;
}

Allright folks, unability to read or write upper memory of DS1307 is solved. It appears it is not possible to read/write more than 32 bytes in a single request. So I broke it down to 2 bytes per request as I needed at least 2 bytes to combine a word out of these bytes.
The code of the function I wrote is here:

// Read from DS1307 memory space and convert and write data into array
boolean DS1307memread(byte wordstartaddress, byte wordendaddress) {
  //Set DS1397 I2C chip address
  byte DS1307_CTRL_ID = B01101000;
  //array pointer ans word address.
  byte pointer = wordstartaddress;
  //Actual address of single bytes in DS1307
  byte byteaddress = (wordstartaddress*2)+8;
  
  while (pointer <= wordendaddress) {
    Wire.beginTransmission(DS1307_CTRL_ID);
    //Writing a starting address to DS1307
    Wire.send(byteaddress);
    Wire.endTransmission();
    // request of data from addresses given
    byte requestedbytes = 2;
    Wire.requestFrom(DS1307_CTRL_ID, requestedbytes);
    byte highbyte = (Wire.receive());
    byteaddress++;
    byte lowbyte = (Wire.receive());
    //Bytes are combined into word and written into integer array
    configdatalocal[pointer] = word(highbyte, lowbyte);
    //For debugging purposes received data is sent out to serial
   Serial.print(int(pointer));
  Serial.print("-"); 
    Serial.print(configdatalocal[pointer]);
    Serial.print(" ");
    pointer++;
    byteaddress++;
  }  
  Serial.println();
  Serial.println("------------thats it folks-------------");
  return true;
}

the function reads from given addresses from DS1307 like there were words and writes these words into integer array. words addresses are 0-27

Hope that helps if anybody else hits the same problem.