DS1302 Real Time Module

I am useing the DS1302 Real Time Module. I can't find how to set it to 12 hour format. I am using the <DS1302.h> library. Here is my code....I would appreciate it if you can tell me how to fix it.

#include <LiquidCrystal.h>
#include <DS1302.h>

DS1302 rtc(12, 11, 10);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void setup()
{
Serial.begin(9600);
rtc.halt(false);
rtc.writeProtect(false);
lcd.begin(16, 2);
rtc.setDOW(TUESDAY);
rtc.setTime(6, 17, 0);
rtc.setDate(10, 11, 2016);
}

void loop()
{

lcd.setCursor(4, 0);
lcd.print(rtc.getTimeStr());
lcd.setCursor(0, 1);
lcd.print(rtc.getDOWStr(FORMAT_SHORT));
lcd.setCursor(6, 1);
lcd.print(rtc.getDateStr());
delay (1000);
}

I'm not familiar with DS1302, but read the example program in this link:
http://playground.arduino.cc/Main/DS1302

I have seen that code before but it doesn't use the same library and I don't want to have to re write all of my code to add 12 hour format.

I have seen that code before but it doesn't use the same library

Please provide a link to the library you are using.

I am using this library

http://www.rinkydinkelectronics.com/library.php?id=5

From the datasheet:

AM-PM/12-24 MODE
Bit 7 of the hours register is defined as the 12– or
24–hour mode select bit. When high, the 12–hour mode
is selected. In the 12–hour mode, bit 5 is the AM/PM bit
with logic high being PM. In the 24–hour mode, bit 5 is
the second 10 hour bit (20 – 23 hours).

From the manual which downloaded with the library

Please note that this library only makes use of the 24-hr format.

I think you have three ways to go.

  1. You can modify the library to use the 12 hr format at the register level.
  2. You can modify your code to test the hour value, and if hour>12 then hour = hour -12 and PM = true
  3. You can modify the library to use the conditional test of #2.

You may find that changing your code is the easier path and will make the code more portable.

If you wish to modify the library as #1, you will have to do two things.

First you will need to set the bit in the hours register has been noted in the previous post. You can use the library function writeRegister() to OR the new bits with the exitising value. Then you will have to modify the code (_decodeH) which reads the hour register to evaluate the 12-24 bit and the am-pm bit and report the hour and am/pm based on that.

You could also modify the library in a less fundamental way (#3), and that is to leave it in the 24 hour mode, and modify the hours section of the getTime() code to add add the conditional test code described.

t.hour = _decodeH(_burstArray[2]);
//add code here to test hour value and subtract 12 if >12 and set pm=true

when I added your code in and up loaded it to my nano i got an error..

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows NT (unknown)), Board: "Arduino Nano w/ ATmega328"
DS1302_LCD.ino: In function 'void setup()':
DS1302_LCD:19: error: 't' was not declared in this scope
DS1302_LCD:19: error: '_burstArray' was not declared in this scope
DS1302_LCD:19: error: '_decodeH' was not declared in this scope

The code I posted was for modifying the DS1302.h library, not for placement in the sketch.

I think you are better off modifying your sketch code rather than the library.

Take a look at the library example code DS 1302_Serial_Hard. You want to be using the Time data structure t and the methods of that sketch to get access to t.hour. You can then work with an hour value to develop 12 hour format. You want to be working with the hour as a number rather than a character string.

You are making things hard for yourself by using this RTC and library. Why are you using the DS1302 instead of the more common i2c rtcs like the DS 3231 or DS1307. They are better documented and have more examples floating around.

I am using that module because it is what came in my sensor kit and a dident want to buy another one. Believe me I wish I had gotten the ds 3231.

I had the same problem and instead modify the library I used the following command after I read the data from the clock.

t = rtc.getTime();

clk_hrs = t.hour;

clk_hrs = clk_hrs & 0x3F;

am_pm=" AM";

if (clk_hrs >= 12){am_pm = " PM";}

if (clk_hrs>=13){clk_hrs = clk_hrs - 12;}

but finally I decided to write my own routine to write and read the clock data.

Thank you. what library did you use and were did you insert the code or delete any thing

Hi,
I used the following library

#include <DS1302RTC.h>
#include <Time.h>

This is how I read the clock and then break it by registers. You need to down load the library.
//************** read the clock ****************

t = rtc.getTime();

r_byte[1] = t.sec ; r_byte[2] = t.min;
r_byte[3] = t.hour ; r_byte[4] = t.date;
r_byte[5] = t.mon ; r_byte[6] = t.dow;
r_byte[7] = t.year ;

Then use the t.hour & 0x1F. This is to remove the 24 hours and left the 12 hours only. In this way you do not have to do anything to the library. To set the clock for 12 hours you need to set bit 7 of the hour register. Then check bit 5 to see if = 1 then is PM and if bit 5 = 0 is AM. Also you can manually set the reg 3 to 12 hours. If it is 12 PM then you must set the bit 5.

Please correct the 0x3F to 0x1F. What you do it is remove bit 7 and 5. When bit 5 it is set is PM
bit 5 = AM or PM
bit 7 = 12/24

I got it in 12 hour mode now the date it all meat up it is written as 18/10/16 and I would like it to be 10/18/16 I have looked in the library and haven't found how to fix it. It only started doing that after I put it in 12 hour mode.

Please post the code you used to get your sketch to 12 hour mode.

If you changed any code in the library, post those changes as well.

Please use the code tags icon </> in the tool bar to produce the code tags so that your code posts like this in a scrolling box

your code here

i used the code on Arduino Playground - DS1302 set to 12 hour.
then i uploaded the code

#include <LiquidCrystal.h>
#include <DS1302.h>

DS1302 rtc(12, 11, 10);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void setup()
{
Serial.begin(9600);
rtc.halt(false);
rtc.writeProtect(false);
lcd.begin(16, 2);
rtc.setDOW(TUESDAY);
//rtc.setTime(6, 17, 0);
rtc.setDate(10, 11, 2016);
}

void loop()
{

lcd.setCursor(4, 0);
lcd.print(rtc.getTimeStr());
lcd.setCursor(0, 1);
lcd.print(rtc.getDOWStr(FORMAT_SHORT));
lcd.setCursor(6, 1);
lcd.print(rtc.getDateStr());
delay (1000);
}

I got it in 12 hour mode now the date it all meat up it is written as 18/10/16 and I would like it to be 10/18/16 I have looked in the library and haven't found how to fix it. It only started doing that after I put it in 12 hour mode.

There are three ways the library can report the date

  1. day/month/year which the library defines as FORMAT_LITTLEENDIAN
  2. year/month/day which the library defines as FORMAT_BIGENDIAN
  3. month/day/year which the library defines as FORMAT_MIDDLEENDIAN

The default argument for the rtc.getDateStr() function which you use is LITTLEENDIAN which will give you the 18/10/16 you saw. Why you see a / as a divider instead of a . is a mystery, as the default divider appears to be the latter.

In your code, replace

rtc.getDateStr();

with

rtc.getDateStr(FORMAT_SHORT, FORMAT_MIDDLEENDIAN, '/');

Try changing SHORT to LONG which should give 16 and 2016 for the year.
Try the different ENDIAN options to see what they give.
Also try use ':' and '.' as well as '/' to see the possible dividers.

Her is the details on the arguments of the library function get.DateStr()

// function in DS1302.cpp
char *DS1302::getDateStr(uint8_t slformat, uint8_t eformat, char divider)

//showing defaults in DS1302.h
char	*getDateStr(uint8_t slformat=FORMAT_LONG, uint8_t eformat=FORMAT_LITTLEENDIAN, char divider='.');

I will try that

it worked thanks for all your help.