Please be aware of all shipping deadlines before placing your order - we cannot guarantee orders will arrive before Christmas!

Adjusting the time with the DS1307 breakout board
Moderators: adafruit_support_bill, adafruit

Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Sat Aug 28, 2010 3:29 pm

Hello,
I bought two of the DS1307 breakout boards, they're a really great and inexpensive way to add RTC capabilities to the Arduino. I have some tact switches that I'd like to use to adjust the time for daylight savings and whatnot.

If I'm understanding the example code right, I would receive a long datatype using now.unixtime(). To add a second to the time, I would add 1 to this number, to add a minute, I would add 60, and to add an hour I would add 60*60 = 3600.

I'm unsure how to upload the adjusted time back to the DS1307, though. Do I just pass the changed long int back to the DS1307 via RTC.adjust(), or is it expecting some other format?

Thanks!
Last edited by ohnoezitasploded on Sat Aug 28, 2010 4:29 pm, edited 1 time in total.
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm

Re: Adjusting the time with DS1307

by adafruit_support_bill on Sat Aug 28, 2010 4:08 pm

RTC.adjust is expecting a DateTime. But you can construct a DateTime with your unixtime().
User avatar
adafruit_support_bill
 
Posts: 32638
Joined: Sat Feb 07, 2009 10:11 am

Re: Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Sat Aug 28, 2010 5:15 pm

How, please?

I can't find any documentation on what a DateTime is or what methods are available to change the fields of an existing DateTime. I see in the example sketches that you can pull out the hours and whatnot when you already have one...

From the example code:
Code: Select all | TOGGLE FULL SIZE
// calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);


It looks like I can just add seconds or take them away as in my prior post, maybe? So to increase the hours by one, I would do:

Code: Select all | TOGGLE FULL SIZE
RTC.adjust(now.unixtime() + 3600);


Is that right?
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm

Re: Adjusting the time with the DS1307 breakout board

by adafruit_support_bill on Sat Aug 28, 2010 6:56 pm

Code: Select all | TOGGLE FULL SIZE
    DateTime now = RTC.now();  // get current time
    DateTime PlusOne (now.unixtime() + 3600); // add one hour
    RTC.adjust(PlusOne); // set to new time
User avatar
adafruit_support_bill
 
Posts: 32638
Joined: Sat Feb 07, 2009 10:11 am

Re: Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Sun Aug 29, 2010 12:48 am

I actually can't get the RTC.adjust() method to work at all-- with the automatic date and time field or with manual adjustments. I tried with both RTC boards that I bought and with my Arduino Duemilanove and the RBBB that I'm using for the clock.

I don't get the "RTC is NOT running!", so RTC.isrunning() is returning true, but on the serial port I just get the midnight 2000 time, so the DS1307 is stopped, I assume.

What would you recommend I try?

Thanks for all your help thus far, by the way.
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm

Re: Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Sun Aug 29, 2010 3:09 am

Okay, here's what I've done to troubleshoot:

I tried both RTC boards that I bought. Identical results with both, so that rules out a faulty DS1307.

I tried it on two different Arduinos that I own, so it's not the Arduino.

I tried downloading the Jeelabs version of the library and running that, with identical results so it's not the software.

I tried compiling and uploading on a different machine, so it's not the computer.

I'm stumped, I think that rules out everything, right? But I'm still getting nothing the 2000 date that indicates that the RTC is stopped.
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm

Re: Adjusting the time with the DS1307 breakout board

by adafruit_support_bill on Sun Aug 29, 2010 6:12 am

Have you tried the "softRTC' example in RTCLib? That calls RTC.Begin with the current date/time. RTC.Begin calls RTC.adjust. It works here on my Chronodot which supposed to be compatible with the DS1307.
User avatar
adafruit_support_bill
 
Posts: 32638
Joined: Sat Feb 07, 2009 10:11 am

Re: Adjusting the time with the DS1307 breakout board

by Volkemon on Sun Aug 29, 2010 4:08 pm

Hi!

I found this code from fat16lib to be most helpful:

Code: Select all | TOGGLE FULL SIZE
// Utility sketch to set DS1307 time, date and control register - from fat16lib. THANKS!!!

#include <Wire.h>
/*
The DS1307 control register is used to control the operation of the SQW/OUT pin.
+-----------------------------------------------+
|BIT 7|BIT 6|BIT 5|BIT 4|BIT 3|BIT 2|BIT 1|BIT 0|
+-----------------------------------------------+
|OUT  |  0  |  0  |SQWE |  0  |  0  | RS1 | RS0 |
+-----------------------------------------------+

OUT (Output control): This bit controls the output level of the SQW/OUT pin
when the square wave output is disabled. If SQWE = 0, the logic level on the
SQW/OUT pin is 1 if OUT = 1 and is 0 if OUT = 0.

SQWE (Square Wave Enable): This bit, when set to a logic 1, will enable the
oscillator output. The frequency of the square wave output depends upon the
value of the RS0 and RS1 bits. With the square wave output set to 1Hz, the
clock registers update on the falling edge of the square wave.

Squarewave Output Frequency for SQWE = 1.
RS1 RS0 FREQUENCY
0   0  1Hz
0   1  4.096kHz
1   0  8.192kHz
1   1  32.768kHz
*/

// i2c 7-bit address
#define DS1307_ADDRESS 0X68


// day of week U.S. convention
char *Ddd[] = {"Bad", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

// forward declaration
uint8_t hexRead(uint16_t &v);
//------------------------------------------------------------------------------
uint8_t bcdRead(uint8_t min, uint8_t max, uint8_t &n)
{
  uint16_t v;
  if (!hexRead(v)) return 0;
  uint8_t d = 10 * (v >> 4) + (v & 0XF);
  if ((v >> 4) > 9 || (v & 0XF) > 9 || d < min || d > max) {
    Serial.println("Invalid");
    return 0;
  }
  n = v;
  return 1;
}
//------------------------------------------------------------------------------
void displayTime(void)
{
  char r[8];
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 8);
  delay(100);
  if (Wire.available() != 8) {
    Serial.println("Read Failed");
    return;
  }
  for (uint8_t i = 0; i < 8; i++) {
    r[i] = Wire.receive();
  }
  Serial.print("The current time is ");
  // month
  hexPrint(r[5]);
  Serial.print("/");
  // day
  hexPrint(r[4]);
  Serial.print("/20");
  // year
  hexPrint(r[6]);
  Serial.print(' ');
  Serial.print(Ddd[r[3] < 8 ? r[3] : 0]);
  Serial.print(' ');
  // hour
  hexPrint(r[2]);
  Serial.print(":");
  // minute
  hexPrint(r[1]);
  Serial.print(":");
  // second
  hexPrintln(r[0]);
  Serial.print("Control: ");
  hexPrintln(r[7]);
}
//------------------------------------------------------------------------------
void dumpAll(void)
{
  for (uint8_t a = 0; a < 64; a += 8) {
    hexPrint(a);
    Serial.print(' ');
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.send(a);
    Wire.endTransmission();
    Wire.requestFrom(DS1307_ADDRESS, 8);
    if (Wire.available() != 8) {
      Serial.println("Read Failed");
      return;
    }
    for (uint8_t i = 0; i < 8; i++) {
      Serial.print(' ');
      hexPrint(Wire.receive());
    }
    Serial.println();
  }
}
//------------------------------------------------------------------------------
void hexPrint(uint8_t v)
{
  Serial.print(v >> 4, HEX);
  Serial.print(v & 0XF, HEX);
}
//------------------------------------------------------------------------------
void hexPrintln(uint8_t v)
{
  hexPrint(v);
  Serial.println();
}
//------------------------------------------------------------------------------
uint8_t hexRead(uint16_t &v)
{
  uint16_t n = 0;
  while (!Serial.available());
  while (Serial.available()) {
    uint8_t c = Serial.read();
    n <<= 4;
    if ('a' <= c && c <= 'f') {
      n += c - ('a' - 10);
    }
    else if ('A' <= c && c <= 'F') {
      n += c - ('A' - 10);
    }
    else if ('0' <= c && c <= '9') {
      n +=  c - '0';
    }
    else {
      Serial.println("Invalid");
      return 0;
    }
    delay(10);
  }
  v = n;
  return 1;
}
//------------------------------------------------------------------------------
void setControl(void)
{
  Serial.println("SQW/OUT pin: ");
  Serial.println("(00) Low");
  Serial.println("(10) 1Hz");
  Serial.println("(11) 4.096kHz");
  Serial.println("(12) 8.192kHz");
  Serial.println("(13) 32.768kHz");
  Serial.println("(80) High");
  Serial.print("Enter control: ");
  uint16_t r;
  if (!hexRead(r)) return;
  hexPrintln(r);
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send(7);
  Wire.send((uint8_t)r);
  Wire.endTransmission();
}

//------------------------------------------------------------------------------
void setDate(void)
{
  uint8_t r[4];
  Serial.print("Enter year (00-99): ");
  if (!bcdRead(0, 99, r[3])) return;
  hexPrintln(r[3]);
  Serial.print("Enter month (01-12): ");
  if (!bcdRead(1, 12, r[2])) return;
  hexPrintln(r[2]);
  Serial.print("Enter date (01-31): ");
  if (!bcdRead(1, 31, r[1])) return;
  hexPrintln(r[1]); 
  Serial.print("Enter day (01-07): ");
  if (!bcdRead(1, 7, r[0])) return;
  hexPrintln(r[0]);
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send(3);
  for(uint8_t i = 0; i < 4; i++) {
    Wire.send(r[i]);
  }
  Wire.endTransmission();
}
//------------------------------------------------------------------------------
void setNvRam(void)
{
  Serial.print("Enter HEX value for all NV RAM locations (0-FF): ");
  uint16_t v;
  if (!hexRead(v)) return;
  hexPrint(v);
  for (uint8_t a = 8; a < 64; a += 8) {
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.send(a);
    for (uint8_t i = 0; i < 8; i++) {
      Wire.send((uint8_t)v);
    }
    Wire.endTransmission();
  }
}
//------------------------------------------------------------------------------
void setTime(void)
{
  uint8_t r[3];
  Serial.print("Enter hours (00-23): ");
  if (!bcdRead(0, 23, r[2])) return;
  hexPrintln(r[2]);
  Serial.print("Enter minutes (00-59): ");
  if (!bcdRead(0, 59, r[1])) return;
  hexPrintln(r[1]);
  Serial.print("Enter seconds (00-59): ");
  if (!bcdRead(0, 59, r[0])) return;
  hexPrintln(r[0]);
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send(0);
  Wire.send(r[0]);
  Wire.send(r[1]);
  Wire.send(r[2]);
  Wire.endTransmission();
}
//------------------------------------------------------------------------------
void setup(void)
{
  Serial.begin(9600);
  Wire.begin();
  delay(1000);
}
//------------------------------------------------------------------------------
void loop(void)
{
  Serial.println();
  displayTime();
  Serial.println("\nOptions are:");
  Serial.println("(0) Display date and time");
  Serial.println("(1) Set time");
  Serial.println("(2) Set date");
  Serial.println("(3) Set Control");
  Serial.println("(4) Dump all");
  Serial.println("(5) Set NV RAM");
  Serial.print("Enter option: ");
   
  uint16_t n;
  if (!hexRead(n)) n = 99;
  Serial.println(n, DEC);
  if (n == 0) return;
  Serial.println();
  if (n == 1) {
    setTime();
  }
  else if (n == 2) {
    setDate();
  }
  else if (n == 3) {
    setControl();
  }
  else if (n == 4) {
    dumpAll();
  }
  else if (n == 5) {
    setNvRam();
  }
  else {
    Serial.println("Invalid option");
  }
}
Livin' , learnin' , lovin' and laffin'. Thanks for the help!
Image
User avatar
Volkemon
 
Posts: 127
Joined: Mon May 10, 2010 8:24 pm
Location: Melbourne FL USA

Re: Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Mon Aug 30, 2010 12:36 am

The softRTC library works just fine, but that doesn't use an external RTC...

The RTC utility code seems very handy, unfortunately I get "Read Failed" when I try to use it.

Is it possible I have bad kits? I can't figure out anything else that it could be. I double checked the assembly instructions and it's correct. My solder points all look good, and it's unlikely in any case that I did a bad solder point on both kits.
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm

Re: Adjusting the time with the DS1307 breakout board

by ohnoezitasploded on Mon Aug 30, 2010 1:10 am

OMFG, I2C connects to ANALOG 4 and 5, not DIGITAL 4 and 5.

Haha, it's always something completely stupid, in hindsight, isn't it?

Is working now.
ohnoezitasploded
 
Posts: 12
Joined: Thu Jul 29, 2010 4:05 pm