Go Down

Topic: i2c and a Dallas RTC Anyone?? (Read 3 times) previous topic - next topic

jfernsler

Has anyone used the new i2c functions in the arduino 006 or 007 to read a dallas DS1307 real time clock? How would I go about implementing something like that in code and spitting out the time over the serial port? What Pins should things be hooked to and how would I use the Wire lib to call the time in from the clock chip?

Thanks!

Any direction would be of great help...

-Jeremy

bluesterror

Hi there,

I've done this using the breakout module from Spark Fun.  Basically, assuming the atmega8, you connect analog 4 to SDA and A5 to SCL, and attach a pull-up resistor (I think I used 2.2k) from both of these to the 5V line.  I used the data sheet for the chip to figure out how to program it and read it over I2C.  Here's my code for a circuit that reads the time and displays the hours/minutes/seconds on a single 7 segment display.  I use straight C++ outside the IDE, so you can probably kill the #includes.
Code: [Select]

/*
* A single-digit clock
* (c) 2007 Bob Copeland <me at bobcopeland.com>
*/
#include <WProgram.h>
#include <Wire.h>
#include <HardwareSerial.h>

char bcd_to_7seg[] = {
   0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x00
};

// pins a-g on 7 seg display
int pins[] = { 11, 10, 7, 3, 4, 8, 12 };

void setup()
{
   int i;

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

   for (i=0; i<7; i++)
       pinMode(pins[i], OUTPUT);

/*
   // program the time & enable clock
   Wire.beginTransmission(0x68);
   Wire.send(0);
   Wire.send(0x00);
   Wire.send(0x52);
   Wire.send(0x80 | 0x21);
   Wire.endTransmission();
*/
}

void write_digit(char digit)
{
   int i;
   char byte = bcd_to_7seg[digit];
   for (i=0; i<7; i++)
   {
       digitalWrite(pins[i], byte & 1);
       byte >>= 1;
   }
}

void write_number(char num)
{
   write_digit(10);
   delay(50);
   write_digit((num >> 4) & 0x0f);
   delay(200);

   write_digit(10);
   delay(50);
   write_digit(num & 0x0f);
   delay(200);
}

void loop()
{
   // reset register pointer
   Wire.beginTransmission(0x68);
   Wire.send(0);
   Wire.endTransmission();
   delay(100);

   Wire.requestFrom(0x68, 3);
   char secs = Wire.receive();
   char mins = Wire.receive();
   char hrs = Wire.receive();

   write_number(hrs & 0x3f);
   delay(100);
   write_number(mins);
   delay(100);
   write_number(secs & 0x7f);
   delay(1000);
}


bluesterror

BTW I finally got around to taking a picture of the device using the above sketch.  It's a one-digit clock using the DS1307.  Most of the arduino's outputs are dedicated to the inputs a-g on the 7 segment display.  I built the thing on Sparkfun's spiffy little ProtoShield.  (Yeah, the picture is too dark...)


jfernsler

nice!

I'm working on a 2 digit clock, myself.. Unfortunately I may have just somehow wrecked my ds1307 - also on a carrier board from sparkfun..

lately when I make a request for data from it, it gives me junk data. I'm not sure how I would have wrecked it, but it certainly appears as such.

I also just ordered the atmega168 so I can use i2c and an LCD in a sketch... currently you can just BARELY do it before you're out of space. Making a request and putting it up on the LCD raw leaves me w/ like 4 bytes.

I also think my code for culling the digits is a little fat. I'll try to post it up once I get home...

-JF


jfernsler

ah.. not wrecked. Just got reset somehow ... I reset the time and it's running like a champ again. Now just waiting for bigger chips and some digits.. :)

Go Up