Pages: [1]   Go Down
Author Topic: Can the DS3231 RTC calculate the Day of Week based on the Date set?  (Read 612 times)
0 Members and 1 Guest are viewing this topic.
NY, USA
Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I created a digital clock using the DS3231 and a 16x2 LCD. I set the time and date through a gui that I wrote. There is a set button on the clock. Pressing it steps the user through each settable field which they can then increment up or down with 2 other buttons.



The day and date are manually set with the buttons. Here’s the code for each field as the user steps through them:

Code:
//hours
  if (buttonCount == 1) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("HOURS:");
    lcd.setCursor(0,1);
    
    if (display12HrMode == false) {  //display 24 hour format
      if (hours < 10) {
        lcd.print("0");
      }
      lcd.print(hours);
    }

    else { //in 12 hr mode
       switch(hours){
    case 0:
      lcd.print("12 AM");
      break;
    case 1:
      lcd.print("1 AM");
      break;
    case 2:
      lcd.print("2 AM");
      break;
    case 3:
      lcd.print("3 AM");
      break;
    case 4:
      lcd.print("4 AM");
      break;
    case 5:
      lcd.print("5 AM");
      break;
    case 6:
      lcd.print("6 AM");
      break;
    case 7:
      lcd.print("7 AM");
      break;
    case 8:
      lcd.print("8 AM");
      break;
    case 9:
      lcd.print("9 AM");
      break;
    case 10:
      lcd.print("10 AM");
      break;
    case 11:
      lcd.print("11 AM");
      break;
    case 12:
      lcd.print("12 PM");
      break;
    case 13:
      lcd.print("1 PM");
      break;
    case 14:
      lcd.print("2 PM");
      break;
    case 15:
      lcd.print("3 PM");
      break;
    case 16:
      lcd.print("4 PM");
      break;
    case 17:
      lcd.print("5 PM");
      break;
    case 18:
      lcd.print("6 PM");
      break;
    case 19:
      lcd.print("7 PM");
      break;
    case 20:
      lcd.print("8 PM");
      break;
    case 21:
      lcd.print("9 PM");
      break;
    case 22:
      lcd.print("10 PM");
      break;
    case 23:
      lcd.print("11 PM");
      break;
    }
      
    }
  
    delay(200);
  }
  //mins
  if (buttonCount == 2) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("MINUTES:");
    lcd.setCursor(0,1);
    if(minutes < 10) {
      lcd.print("0");
    }
    lcd.print(minutes);
    delay(200);
  }
  //day of week
  if (buttonCount == 3) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("DAY OF WEEK:");
    lcd.setCursor(0,1);
    switch(dayOfWeek){
    case 1:
      lcd.print("Sun");
      break;
    case 2:
      lcd.print("Mon");
      break;
    case 3:
      lcd.print("Tue");
      break;
    case 4:
      lcd.print("Wed");
      break;
    case 5:
      lcd.print("Thu");
      break;
    case 6:
      lcd.print("Fri");
      break;
    case 7:
      lcd.print("Sat");
      break;
    }
    delay(200);
  }
  //month
  if (buttonCount == 4) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("MONTH:");
    lcd.setCursor(0,1);
    if(month < 10) {
      lcd.print("0");
    }
    lcd.print(month);
    delay(200);
  }
  //day of month
  if (buttonCount == 5) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("DAY OF MONTH:");
    lcd.setCursor(0,1);
    if(dayOfMonth < 10) {
      lcd.print("0");
    }
    lcd.print(dayOfMonth);
    delay(200);
  }
  //year
  if (buttonCount == 6) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("YEAR:");
    lcd.setCursor(0,1);
    lcd.print("20");
    lcd.print(year);
    delay(200);
  }

As you step through and set each field, the changes are pushed to the RTC like this:

Code:
void set_date()
{
  Wire.beginTransmission(104);
  Wire.write(3);
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void set_time()
{
  Wire.beginTransmission(104);
  Wire.write(0);
  Wire.write(decToBcd(seconds));
  Wire.write(decToBcd(minutes));
  Wire.write(decToBcd(hours));
  Wire.endTransmission();
}

So you see, the Date and the Day of Week are sort of independent of each other. It’s possible to set the Day of Week incorrectly based on the date.

My question is, do I have to manually set the Day of Week like I’m doing? Is there a way to calculate the Day of Week based on the date? Does the DS3231 provide that feature? I’ve searched high and low and can’t seem to find the answer. I’d like to be able to configure the Day of Week automatically based on the date that is set by the user instead of the user having to do it.
« Last Edit: May 14, 2013, 10:23:15 am by ryemac3 » Logged

Connecticut, USA
Offline Offline
Full Member
***
Karma: 6
Posts: 162
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

From DS3231 library keyword.txt try this: getDoW.  It worked great for my DS1307 RTC, as its library has the same function. For the DS1307 it was:
Code:
switch (RTC.dow)
« Last Edit: May 14, 2013, 10:40:16 am by elac » Logged

It's all about the skills

Norfolk UK
Offline Offline
Edison Member
*
Karma: 52
Posts: 2203
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The DS3231 cannot calculate the DoW but maybe some of the libraries for the DS1307/DS3231 will have functions to do that. The DoW value just increments every day then rolls back to 1 when it exceeds 7. It's your choice what the value means. You could decide 1=Sunday or any other day of the week.
Logged

Handle every stressful situation like a dog. If you can't eat it or hump it. Piss on it and walk away.

Grand Blanc, MI, USA
Online Online
Faraday Member
**
Karma: 71
Posts: 3498
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to expand a bit on what Riva said, the DS3231 has a register (0x03) that tracks DoW as a number between 1 and 7. It increments at midnight and rolls back to 1 after 7. It's up to the user to decide which day corresponds to which value and set it correctly.

Personally, I usually use the Time library which does the calculation. Set the time and date, and it calculates the correct DoW. When using the Time library with an RTC, the RTC's DoW register is irrelevant (but not, of course, the date and time registers).
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

NY, USA
Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool. Thanks. Maybe I'll look at the Time library. I just think it's silly to have to set the DOW as well as the date. I figured if I have the date, there's no need to set the DOW. It should be automatic.
Logged

Pages: [1]   Go Up
Jump to: