Go Down

Topic: DS1307 won't work... Everything is hooked up properly (Read 4709 times) previous topic - next topic

magician13134

I'm trying to get a Real Time Clock (DS1307) to work with my Arduino, and I know it should be easy, but I'm having a ton of trouble. My circuit is very simple, the DS1307 is connected to a coin-cell (3V), a 32.768kHz 12.5pF clock crystal, SDA and SCL have 4.7kOhm pull-ups and are connected to the correct input pins (I have tried several different libraries that require different input pins, which is why I didn't specify). The official Time library always just reads 00:00:00 00/00/00 while another library I found reads xxxxxxxxx 85.85.2165 -- 27:85:85

Here is my code and the serial monitor output:
Code: [Select]
// DS1307_Serial_Easy (C)2010 Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
//
// A quick demo of how to use my DS1307-library to
// quickly send time and date information over a serial link
//
// I assume you know how to connect the DS1307.
// DS1307:  SDA pin   -> Arduino Digital 20
//          SCL pin   -> Arduino Digital 21

// I changed these to digital I/O 2 and 3

#include <DS1307.h>

// Init the DS1307
DS1307 rtc(2, 3);

void setup()
{
  // Set the clock to run-mode
  rtc.halt(false);
 
  // Setup Serial connection
  Serial.begin(9600);

  // The following lines can be commented out to use the values already stored in the DS1307
  rtc.setDOW(MONDAY);        // Set Day-of-Week to SUNDAY
  rtc.setTime(1, 8, 00);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(8, 8, 2011);   // Set the date to October 3th, 2010
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
 
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
 
  // Wait one second before repeating :)
  delay (1000);
}


Quote
Monday 08.08.2011 -- 01:08:00
Monday 08.08.2011 -- 01:08:01
xxxxxxxxx 85.85.2165 -- 27:85:85
xxxxxxxxx 85.85.2165 -- 27:85:85
xxxxxxxxx 85.85.2165 -- 27:85:85
xxxxxxxxx 85.85.2165 -- 27:85:85
xxxxxxxxx 85.85.2165 -- 27:85:85


As you can see, it works intermittently. I have tried with multiple DS1307 chips, they all give the same result; they work about 5% of the time, randomly. I cannot pin-point what causes them to start or stop working. I'm measuring 4.98V across the Vcc and GND of the chip. My grounds are all tied together (Vbat, Vcc, etc.)

If anyone has any advice at all, I'd love to hear it. Thank you!
Ben

MarkT

Firstly do you have proper decoupling?

How is the crystal connected to the DS1307 - those wires are too fine for a breadboard and the crystal must be very close to the chip and away from any digital signals.

And lastly why not use SDA and SCL pins to talk to it?
[ I won't respond to messages, use the forum please ]

alvarojusten

Maybe the information on this page can help: https://github.com/turicas/DS1307
Blog pt_BR: http://blog.justen.eng.br/
Curso de Arduino (Arduino Course, in Brazil) - http://www.CursoDeArduino.com.br/

magician13134


Firstly do you have proper decoupling?

How is the crystal connected to the DS1307 - those wires are too fine for a breadboard and the crystal must be very close to the chip and away from any digital signals.

And lastly why not use SDA and SCL pins to talk to it?


My DS1307 is on a breakout board which has the crystal very close to the chip with no other traces under or around it, I also have a decoupling capacitor on the board, 0.1uF ceramic, but it's only between ground and Vbat... There should be one between ground and Vcc also, right? And is it ok that they're ceramic or should they be electrolyte? I also have tried using SDA and SCL (analog 4 and 5) as per the example in the Time library. That didn't help.

Alvarojusten - I'm on my phone now, but I will look at that when I get home.

Thank you both for the suggestions

CrossRoads

#4
Aug 09, 2011, 04:13 am Last Edit: Aug 09, 2011, 04:17 am by CrossRoads Reason: 1
Magician,
This is the simple sketch I wrote to test the RTC on my Bobuino.
I tested via Seial1 on the 1284, with simple commands to set the time.
It reads back every 5 seconds.
Hopefully you can figure this out, halejandro on another thread is having the same problem.  I'll ask him about the pullup resisters.
Mine is wired like this (but without C12, that was for experimenting)
Code: [Select]

/*
Test of RTC DS1307 via I2C.
Counts
Seconds,
Minutes,
Hours,
Date of the Month,
Month,
Day of the week, and
Year with Leap-Year

56 bytes battery backed RAM
Square Wave Output, can connect to INT2/D6 or PD7
*/

#include <Wire.h>

//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9
byte minutes_address = 0x01;
byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes
byte hours_address = 0x02;
byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
byte day_week_address = 0x03;
byte day_week = 0; // range 01-07
byte date_month_address = 0x04;
byte date_month = 0; // range 01-31
byte month_address = 0x05;
byte month = 0; // range 01-12
byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9
byte square_address = 0x07;
byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz
byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F

int RTC_address = 0x68; // 1101 000

byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;
// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back
// use C0xx to read RAM back
byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;

void setup() {
 Wire.begin(); // no address, we are master
 Serial1.begin (57600);  
 Serial1.flush();
 currentMillis = millis();  
}

void loop() {

 if (Serial1.available() >1){
   incomingCommand = Serial1.read();
   //incomingRegister = Serial.read();
   incomingData = Serial1.read();
   Serial1.print ("command ");
   Serial1.println (incomingCommand & 0xF0, HEX);
   Serial1.print ("register ");
   Serial1.println(incomingCommand & 0x0F, HEX);
   Serial1.print ("data ");
   Serial1.println (incomingData, HEX);
 }
 // *******************************************
 RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
 if (RTC_write_command == 0xF0){  // e033check for Write command
   RTC_register = incomingCommand & 0x0F;  // mask off low btye
   incomingCommand = 0;
   new_data = incomingData;
   Serial1.print (" Sending a command ");
   switch (RTC_register){
   case 0: // write seconds
       Serial1.println ("Seconds ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(seconds_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
     delay (delay_time);
     break;
   case 1: // write minutes
   Serial1.print ("Minutes ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(minutes_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
     delay (delay_time);
     break;
   case 2: // write hours
       Serial1.print ("Hours ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(hours_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 3: // write day
       Serial1.print ("Day ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(day_week_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 4: // write date of month
       Serial1.print ("Day of Month ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(date_month_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 5: // write month
       Serial1.print ("Month ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(month_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 6: // write year
       Serial1.print ("Year ");
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(year_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 7: // write square wave
       Serial1.print ("Square Wave ");
   Serial1.println (RTC_register, HEX);
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(square_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
   case 8: // write RAM
       Serial1.print ("RAM ");
   Serial1.println (RTC_register, HEX);
     Wire.beginTransmission(RTC_address); // select device
     Wire.send(RTC_ram_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it
    delay (delay_time);
     break;
     // all others,do nothing
     Serial.println ("Invalid command ");
   }  // end Switch
 } // end if command == F
 // ************************************

 currentMillis = millis();
 if ( (currentMillis - previousMillis) >= duration){
   previousMillis = currentMillis;  
   // Reset the register pointer  
   Wire.beginTransmission(RTC_address);  
   Wire.send(0x00);  
   Wire.endTransmission();  

   Wire.requestFrom(RTC_address,8 );  
   seconds = Wire.receive();  
   minutes = Wire.receive();  
   hours = Wire.receive();  
   day_week = Wire.receive();  
   date_month = Wire.receive();  
   month = Wire.receive();  
   year = Wire.receive();  
   sqwe = Wire.receive();

   // Seconds
   // bit 7 = Clock Halt, Enabled = 0, Halt = 1
   // bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9

   // Hours
   // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
   // bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
   // bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

   Serial1.print ("Hrs " );
   Serial1.print (hours, HEX);
   Serial1.print (" Mins ");
   Serial1.print (minutes, HEX);
   Serial1.print (" Secs ");
   Serial1.print (seconds, HEX);
   Serial1.print (" Day ");
   Serial1.print (day_week, HEX);
   Serial1.print (" Date ");
   Serial1.print (date_month, HEX);
   Serial1.print (" Month ");
   Serial1.print (month, HEX);
   Serial1.print (" Year 20");
   Serial1.print (year, HEX);
   Serial1.print (" Square Wave ");
   Serial1.println (sqwe, HEX);

 }
}



Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

magician13134

#5
Aug 09, 2011, 06:52 am Last Edit: Aug 09, 2011, 06:55 am by magician13134 Reason: 1
I appreciate everyone's help, but I think the problem is actually the chips... I could be wrong, but here's why I suspect them:
I changed a few things around (used a shorter jumper cable for Vcc and added a capacitor) and it looked as if it was suddenly working, but as soon as I swapped the chip, it stopped working
I thought maybe just that one chip was bad so I removed it from the breakout and soldered a new one, I could set the time on that one just fine, but the date would not change (1/1/2011) no matter what I try
Occasionally they will begin to smoke and get very hot. I'll shut off the Arduino and when I turn it back on, they continue to work as if nothing has happened.
Even when they appear to work perfectly they stray by a matter of seconds to the minute, I know they aren't THAT inaccurate
I bought them for very cheap from a dealer on eBay

I can't be certain that the chips are bad, but since I've had more than one smoke on different breakout boards and a circuit where one works perfectly another will fail to set the date, I'm pretty sure something is wrong with the chips... I guess I'll order a few from Mouser and hopefully they will work much better. It will be a while before I get them or start using them again, but I will post back when I do.

CrossRoads

Were you ever able to send it a change seconds command?
0x68  << address
0x00 << seconds register
0x00  << seconds high byte nibble (0-5), if high bit is set here, time updates are halted; and low byte nibble, 0-9.

Also possible counterfeit parts if they smoke with 5V.

      Wire.beginTransmission(RTC_address); // select device
      Wire.send(seconds_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it

The non-lead free surface mount parts I got from dipmicro all worked fine so far.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

All the unpowered chips I bought put out all 0's and 0x80 for seconds and 0x03 for the square wave register when powered up.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

magician13134


Were you ever able to send it a change seconds command?
0x68  << address
0x00 << seconds register
0x00  << seconds high byte nibble (0-5), if high bit is set here, time updates are halted; and low byte nibble, 0-9.

Also possible counterfeit parts if they smoke with 5V.

     Wire.beginTransmission(RTC_address); // select device
     Wire.send(seconds_address);          // queue the register
     Wire.send(new_data);                  // queue data
     Wire.endTransmission();            // send it

The non-lead free surface mount parts I got from dipmicro all worked fine so far.


I tried this code, and here is the output:
Code: [Select]

Hrs 0 Mins 0 Secs 0 Day 0 Date 0 Month 0 Year 200 Square Wave 0
Hrs 0 Mins 0 Secs 0 Day 0 Date 0 Month 0 Year 200 Square Wave 0
Hrs 0 Mins 0 Secs 0 Day 0 Date 0 Month 0 Year 200 Square Wave 0
Hrs 0 Mins 0 Secs 0 Day 0 Date 0 Month 0 Year 200 Square Wave 0

//This is when I realized the chip was smoking, reset the Arduino and got this output:

Hrs 0 Mins 0 Secs 80 Day 1 Date 1 Month 1 Year 200 Square Wave 3
Hrs 0 Mins 0 Secs 80 Day 1 Date 1 Month 1 Year 200 Square Wave 3


Although my square wave is not attached to anything.

I tried sending these three commands and got this output:
0x68  << address
Code: [Select]
command 30
register 0
data 78
command 30
register 6
data 38
command 20
register 0
data 20
command 30
register C
data 3C
command 20
register 0
data 61
command 60
register 4
data 64
command 70
register 2
data 65
command 70
register 3
data 73

0x00 << seconds register
Code: [Select]
command 30
register 0
data 78
command 30
register 0
data 30
command 20
register 0
data 3C
command 30
register C
data 20
command 70
register 3
data 65
command 60
register 3
data 6F
command 60
register E
data 64
command 70
register 3
data 20
command 70
register 2
data 65
command 60
register 7
data 69
command 70
register 3
data 74
command 60
register 5
data 72

0x00  << seconds high byte nibble 0
Code: [Select]
command 30
register 0
data 78
command 30
register 0
data 30
command 20
register 0
data 20
command 30
register C
data 3C
command 20
register 0
data 73
command 60
register 5
data 63
command 60
register F
data 6E
command 60
register 4
data 73
command 20
register 0
data 68
command 60
register 9
data 67
command 60
register 8
data 20
command 60
register 2
data 79
command 70
register 4
data 65
command 20
register 0
data 6E
command 60
register 9
data 62
command 60
register 2
data 6C
command 60
register 5
data 20


If they are counterfeit is it possible that some of them would actually work?

CrossRoads

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

Magician,
Figured out the problem on the other thread
http://arduino.cc/forum/index.php/topic,68752.15.html

See reply #27 I think, where I have a screen shot.

Turned out to be interface settings problems.
Using RS232 Mon from EVMSoft, messages sent to the DS1307 are just straight hex bytes:
F004, F112, etc.
Stuff coming back needed to be interpreted as hex.
I was testing using ATMega1284's 2 com ports - but USB was showing as COM13, RS232MON only supports COM8.
I was downloading sketches via USB, so I did interfacing over Serial1.
TRS232MON allows mixing of HEX out and TEXT back in, I think would have to modify the sketch to expect TEXT in vs HEX.
(i.e. instead of acting on 0xF0, 0x33, have to act on 'F', '0', (just change If statements and switch:case), and convert '3', '3' into 0x33 to send to the DS1307, may along these lines:
(where I used F indicate a register access, and 0 -7 to indicate which register,so 0xF004 would be write 0x00 to register 0:
//after getting the 'F' and '0', then this:
incomingByte = Serial.Read();
uppernibble = (incomingByte - 0x30)<<4; // convert ascii to hex, put in upper nibble
incomingByte = Serial.Read();
lowernibble = (incomingByte - 0x30); // convert ascii to hex,
data_for_DS1307 = uppernibble+lowernibble;

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Boffin1

I too am completely lost now with this dang RTC,  I have done some searches, and there seems to be so many different ideas of how to try and use the DS1307 with Arduino !
There are more posts on this than on Blinking LEDs!!!  :-)

I have a small board with the DS1307, 3.2v battery,  Xtal  right on the pins, decoupling on the 5v, 10k pull ups on the  SCL and ADA pins.

I have tried several sketches just to set the time and read it, I have removed the settings in setup and uploaded again, but each time I get random results, sometimes just everything switching from 00-000-00 00;00;00  to the correct time for a few seconds.

And Crossroads, your "simple" sketch is way over my "Global Newbie"  head I am afraid :-)

This was the result from the latest attempt using the DS1307 library example from Álvaro Justen aka Turicas;
Code: [Select]

Please enter date and time in the format "YYYY-MM-DD HH:MM:SS D",
Where D is the number of the day of week (0 = Sunday, 6 = Saturday).
Example: 2011-04-23 02:25:27 6
Date and time set!
Reading data from RTC...
20165-08-11 12:58:00 - day of week: Friday
2000-00-00 00:00:00 - day of week: Sunday
2000-00-00 00:00:00 - day of week: Sunday
2011-08-11 12:58:03 - day of week: Friday
2011-08-11 12:58:04 - day of week: Friday
20165-165-165 12:58:05 - day of week: Friday
2000-00-00 00:00:00 - day of week: Sunday
2011-08-11 12:58:07 - day of week: Friday
2011-08-11 12:58:08 - day of week: Friday
2011-08-11 12:58:09 - day of week: Friday
2000-00-00 00:00:00 - day of week: Sunday
2000-00-00 00:00:00 - day of week: Sunday
2011-08-11 12:58:12 - day of week: Friday


anybody have a failsafe equivalent to Blink without delay for DS1307 chips !

the code for above is :
Code: [Select]

/*
This example firstly waits for Serial input and then sets date and time on DS1307
Real-Time Clock based on what user sent.
Secondly it reads the date and time from DS1307 Real-Time Clock
and send this information to your PC using USB/Serial (like the ReadDate example).
Make the connections below, upload the code and open Serial Monitor.

Made by Álvaro Justen aka Turicas

Pin connections on DS1307 module:

[DS1307] <--> [Arduino]
5V       <--> 5V
GND      <--> GND
SQW      <--> (not connected)
SCL      <--> Analog Input 5
SDA      <--> Analog Input 4

This software is free software.
*/

#include <Wire.h>
#include <DS1307.h>

char dateTime[22];
int RTCValues[7], i = 0, year, month, dayOfMonth, dayOfWeek, hour, minute,
    second;

void setup() {
    Serial.begin(9600);
    Serial.println("Please enter date and time in the format \"YYYY-MM-DD HH:MM:SS D\",");
    Serial.println("Where D is the number of the day of week (0 = Sunday, 6 = Saturday).");
    Serial.println("Example: 2011-04-23 02:25:27 6");
    DS1307.begin();

    while (i < 21) {
        if (Serial.available()) {
            char c = Serial.read();
            dateTime[i] = c;
            i++;
        }
    }
    dateTime[i] = '\0';

    year = 10 * (dateTime[2] - 48) + (dateTime[3] - 48);
    month = 10 * (dateTime[5] - 48) + (dateTime[6] - 48);
    dayOfMonth = 10 * (dateTime[8] - 48) + (dateTime[9] - 48);
    dayOfWeek = (dateTime[20] - 48);
    hour = 10 * (dateTime[11] - 48) + (dateTime[12] - 48);
    minute = 10 * (dateTime[14] - 48) + (dateTime[15] - 48);
    second = 10 * (dateTime[17] - 48) + (dateTime[18] - 48);

    DS1307.setDate(year, month, dayOfMonth, dayOfWeek, hour, minute, second);
    Serial.println("Date and time set!");
    Serial.println("Reading data from RTC...");
}

void loop() {
    DS1307.getDate(RTCValues);
    sprintf(dateTime, "20%02d-%02d-%02d %02d:%02d:%02d", RTCValues[0],
            RTCValues[1], RTCValues[2], RTCValues[4], RTCValues[5],
            RTCValues[6]);
    Serial.print(dateTime);
    Serial.print(" - day of week: ");
    Serial.println(fromNumberToWeekDay(RTCValues[3]));

    delay(1000);
}

Boffin1

OK everything works with the DS1307RTC library !

tokuro

have you try removing the back up battery?  i had case where my vcc was very close to batt + 1.25v and getting unreliable results becasue ds1307 thought i was on batt.

CrossRoads

Too much reliance on libraries.  People can't figure out 3 simple transfers using wire.h to read or write a register.
Conceptually:
wire.send 0x68;// device IC
wire.sedn 0x0X; // X = register
wire.send 0xAB; // high & low nibbles with the data,
// or
AB = wire.receive() to read the data back.

Actual commands:
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(minutes_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it

Read the registers back

    // Reset the register pointer  , device specific
    Wire.beginTransmission(RTC_address); 
    Wire.send(0x00); 
    Wire.endTransmission();

    Wire.requestFrom(RTC_address,8 );  // read 8 registers back
    seconds = Wire.receive(); 
    minutes = Wire.receive(); 
    hours = Wire.receive(); 
    day_week = Wire.receive(); 
    date_month = Wire.receive(); 
    month = Wire.receive(); 
    year = Wire.receive(); 
    sqwe = Wire.receive();

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up