RTC DS3231 Help

I am new to this and I am really struggling with some conversions for the RTC chip I am trying to get my Arduino to talk to.

I have been trying to get an understanding of how the libraries actually talk to the program and in doing so I am trying to write a simple program to get the time from my RTC to output to the serial.

Here is what I have so far…


// My attempt to write an RTC sketch to show the time on an LCD screen

#include <Wire.h>
#include <LiquidCrystal.h>

#define DS3231_IC2_Address 0x68

byte read_second;
byte read_minute;
byte read_hour;
byte read_day;
byte read_date;
byte read_month;
byte read_year;
int count = 0;

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup(){
Serial.begin(9600);
lcd.begin(16, 2);
lcd.println(" Lindsay’s Clock ");
lcd.setCursor(0,1);
delay(2000);
lcd.clear();
Wire.begin();
}

void loop(){
delay(1000);
Wire.beginTransmission(DS3231_IC2_Address);
Wire.write((uint8_t) 0x00);
Wire.endTransmission();

Wire.requestFrom(DS3231_IC2_Address, 7);
read_second = Wire.read();
read_minute = Wire.read();
read_hour = Wire.read();
read_day = Wire.read();
read_date = Wire.read();
read_month = Wire.read();
read_year = Wire.read();

read_second = (((read_second & B11110000)>>4)*10 + (read_second & B00001111)); // convert BCD to decimal
read_minute = (((read_minute & B11110000)>>4)*10 + (read_minute & B00001111)); // convert BCD to decimal
read_hour = (((read_hour & B11110000)>>4)*10 + (read_hour & B00001111)); // convert BCD to decimal

Serial.print("Hour - “);
Serial.print(read_hour);
Serial.print(” Minute - “);
Serial.print(read_minute);
Serial.print(” Second - ");
Serial.println(read_second);
}


The read_minute and the read_second output perfectly but the read_hours is outputting “70” at 10PM.

Can anyone help me and explain what I am doing wrong?

Thanks

scoopthepoop:
The read_minute and the read_second output perfectly but the read_hours is outputting "70" at 10PM.

Can anyone help me and explain what I am doing wrong?

The top 4 bits of the hour byte are:

Zero
12-hour mode flag
PM flag
Tens of hours

Since you get 0111 0000 at 10:00 that means the clock is in 12-hour mode, it's PM, and the hour is > 9 which is all correct.

if (read_hour & 0b01000000)  // 12-hour mode
    {
    if (read_hour & 0b00100000)  // PM flag
          read_hour = (((read_hour & B00010000)>>4)*10 + (read_hour & B00001111)) + 12; // convert BCD to decimal and add 12 for PM
    else
         read_hour = (((read_hour & B00010000)>>4)*10 + (read_hour & B00001111)); // convert BCD to decimal
    }
else
    {  // 24-hour mode
    read_hour = (((read_hour & B00110000)>>4)*10 + (read_hour & B00001111)); // convert BCD to decimal
    }

John, thanks for the reply. I had not but 10 minutes ago figured out that it was the PM AM, 12 hour 24 hour issue when I finally got ahold of this file...

http://datasheets.maxim-ic.com/en/ds/DS3231.pdf

You are EXACTLY right. I didn't take into account how the RTC dealt with the hours in 24 hour mode.

I do like your "if" statement so I am probably going to snag that.

Thanks again.