Problem with RTC and time library

I am experimenting currently with RTC and the time library which works quite well together except I can't get the "weekday()" function to work. What ever I do, it always returns 5 (Thursday) no matter what day it is. It would be nice if somebody could point me in the right direction. I am working with the Arduino IDE 1.5.6-r2, a Arduino Uno and the Tiny RTC shield. Libraries used: DS1307RTC Time Wire

Thanks a lot

Provide links to the libraries and to the used hardware! Don't use a beta release with the UNO, use 1.0.5 for everything except the Due and the Yun.

It makes it easier for us if you post your code. With the cursor in the Arduino IDE, do Ctrl-T to format it in a standard way, then use the sharp sign ('#') and copy your code between the two code tags.

Thank you very much for the quick respond
The libraries I have downloaded from there: DS1307RTC Library, For Accessing Real Time Clock (RTC) Chips.
Since I am just experimenting, I use very basic code:

#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>

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

void loop() {
     tmElements_t tm;               
     if(RTC.read(tm)) {             
       currentHour = tm.Hour;       
       currentMinute = tm.Minute;   
       currentDay = tm.Wday;
    }
    Serial.print("Current day: ");
    Serial.println(currentDay);
    Serial.print("Current Time: ");
    Serial.print(currentHour);
    Serial.print(" : ");
    Serial.println(currentMinute);
}

Thanks again for having a look at

The returned time values make sense? Print out the date values as well, maybe the value 5 for weekday makes sense then. Did you check if the battery is still operating? If the RTC is reset each time you power on, it’s perfectly possible that you get the same value each time.

I have done that already, the time, the date everything shows perfectly correct, except the weekday. If it does reset it self every time the Arduino board was powered off, that should also effect the date, but the date is always correct. The same would be with a faulty battery. That would even effect the time settings but non of this happens. I was thinking that I was maybe missing something in the setup.

To synchronize the rtc module I use the sample code which came with the DS1307RTC library.

 #include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>

const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

tmElements_t tm;

void setup() {
  bool parse=false;
  bool config=false;

  // get the date and time the compiler was run
  if (getDate(__DATE__) && getTime(__TIME__)) {
    parse = true;
    // and configure the RTC with this info
    if (RTC.write(tm)) {
      config = true;
    }
  }

  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  delay(200);
  if (parse && config) {
    Serial.print("DS1307 configured Time=");
    Serial.print(__TIME__);
    Serial.print(", Date=");
    Serial.println(__DATE__);
  } else if (parse) {
    Serial.println("DS1307 Communication Error :-{");
    Serial.println("Please check your circuitry");
  } else {
    Serial.print("Could not parse info from the compiler, Time=\"");
    Serial.print(__TIME__);
    Serial.print("\", Date=\"");
    Serial.print(__DATE__);
    Serial.println("\"");
  }
}

void loop() {
}

bool getTime(const char *str)
{
  int Hour, Min, Sec;

  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
  tm.Hour = Hour;
  tm.Minute = Min;
  tm.Second = Sec;
  return true;
}

bool getDate(const char *str)
{
  char Month[12];
  int Day, Year;
  uint8_t monthIndex;

  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
    if (strcmp(Month, monthName[monthIndex]) == 0) break;
  }
  if (monthIndex >= 12) return false;
  tm.Day = Day;
  tm.Month = monthIndex + 1;
  tm.Year = CalendarYrToTm(Year);
  return true;
}

Looking through the sketch, it doesn’t seem that the weekday is extracted some where. Again, I might be missing something.

Thanks again for having a look at

That library you use is simply wrong. I doubt that the date is returned correctly if ran for more than a day:

  sec = Wire.read();
  tm.Second = bcd2dec(sec & 0x7f);   
  tm.Minute = bcd2dec(Wire.read() );
  tm.Hour =   bcd2dec(Wire.read() & 0x3f);  // mask assumes 24hr clock
  tm.Wday = bcd2dec(Wire.read() );
  tm.Day = bcd2dec(Wire.read() );
  tm.Month = bcd2dec(Wire.read() );
  tm.Year = y2kYearToTm((bcd2dec(Wire.read())));

Compare that with table 2 of the DS1307 datasheet. The DS1307 doesn't have a register for the weekday, so the weekday value was read/written to/from the day field, day to/from month and so on.

The DS1307 doesn’t have a register for the weekday…

Sure it does. Register 0x03 is the DAY register and is taken from bits 0-2 and has a value from 1 through 7 (it is not zero-based). An example of writing to the RTC is:

 Wire.beginTransmission(I2C_RTC); // Select RTC
  Wire.send(0);        // Start address
  Wire.send(DecToBcd(second));     // Second
  Wire.send(DecToBcd(minute));    // Minute
  Wire.send(DecToBcd(hour));    // Hour
  Wire.send(DecToBcd(weekday));    // Weekday
  Wire.send(DecToBcd(day));    // Day
  Wire.send(DecToBcd(month));     // Month (with century bit = 0)
  Wire.send(DecToBcd(year));    // Year
  Wire.endTransmission();

Note the Wire.send(0) statement near the start of the code. This call is done to reset the internal register pointer for the timekeeper register. The pointer autoincrements when a register is read/written. Passing in a zero value resets the pointer to the start of the timekeeper register. Failure to do that will cause the pointer to read/write to wherever the register pointer currently points. The pointer does “wrap around” after the last timekeeper register is read.

Thank you for your suggestions. I got the point. After a couple of days experimenting and testing, I can say that the sample code provided is working. It just does not address the weekday setting, meaning the weekday is not set and therefore it seems to repeat the initial day it set itself when powered up the first time. The time and date, which is addressed in the sketch is changing properly. Setting the RTC manually with Wire.send() seems to solve the problem. At least for 1 day change over testing.

Thanks again