DS1307 day of the week

Hello All

How to I go about obtaining day of the week from a DS1307 RTC?

This is partial code

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

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
}

void loop() {
  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.write(':');
    Serial.print(tm.Wday);
    Serial.println();

I figured that

Serial.print(tm.Wday);

Would give me something other than 0 ?

Are the other time values as you expect?

It looks like weekday 0 is an error code. The weekdays are 1 indexed.

All other values are good!

Ok, Time = 13:18:08, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:09, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:10, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:11, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:12, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:13, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:14, Date (D/M/Y) = 19/7/2017:0
Ok, Time = 13:18:15, Date (D/M/Y) = 19/7/2017:0

The value at the end of line is 0 for DayOfWeek

I have used to followed code to set the DS1307RTC. Perhaps it should be revised to include DOW?

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.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;
}

Would give me something other than 0 ?

It does for me when I run your sketch.

The DS1307 library reads the storage register (0x03) in the rtc chip to get the weekday. What is the setting in that register? Here's some test code to read and write the dow register.

// DS1307 I2C NVRAM test

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
#define startRegister 0x00
#define endRegister 0x07

void setup()
{

  Wire.begin();
  Serial.begin(9600);
  Serial.print("Register");
  Serial.print("\t");
  Serial.println("Bit Values");
  Serial.println();

  
  //write dow register use value 0-6
 // writeNVRAM(0x03,B00000100);//day4 

  for (int a = startRegister; a <= endRegister; a++)
  {
    byte b=readNVRAM(a);
    Serial.print("0X");
    if(a<16)
      Serial.print("0");
    Serial.print(a, HEX);
    Serial.print("\t");
    Serial.print("\t");


    for (int i = 7; i >= 0; i-- )
    {
      Serial.print((b >> i) & 0X01);//shift and select first bit, no speed advantage
    }

    Serial.println();

  }
}

void writeNVRAM(byte location, byte data)
// writes data to DS1307 NVRAM location
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(location); 
  Wire.write(data);
  Wire.endTransmission();  
}

byte readNVRAM(byte location)//// reads data from DS1307 NVRAM location
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(location); 
  Wire.endTransmission();  
  Wire.requestFrom(DS1307_I2C_ADDRESS, 1);//only 1 byte, does not need wire.available
  return Wire.read();
}

void loop(){
}

I ran your test code and get this

Register	Bit Values

0X00		00100101
0X01		01000111
0X02		00010011
0X03		00000000
0X04		00011001
0X05		00000111
0X06		00010111
0X07		00000011

OK, now uncomment the write piece of the code and set the day you want.

You're already using the Time library. If you set the RTC time using the library, it will automatically update the DOW register for you.

Well using the cattledog script solved my Problem. Thanks so much for your help :slight_smile:

The library already includes name strings that you can use.