How to get DS1307 hour in AM/PM Format easily?

Hello and Happy new year beforehand!

After getting my DS1307 working beautifully I put together a nice sketch (at least for me) to print out the temperature (from a 1-Wire DS18B20) and the date time (from Lady Ada DSRTC1307 breakout board) by toggling a switch to a serial enabled (by SparkFun serial backpack) 16x2 LCD. Everything works perfect right now, but I would like to change the time format to AM/PM instead of the 24Hrs format. I have looked at the RTClib.h and haven't found a method or functions for this. Maybe I'm not looking at the right place or something but I'm sure there should be a method or library where that should be already implemented. I have used methods/functions from many others around. Also feel free to use it as your heart desires.

Anyway, here's my code (sorry for the coding mess, it's been almost 10 years since I programmed again and it's a wip:

/*                         
  Sketch to print the temperature from a DS18B20 on a 16x2 serial enabled
  LCD (SparkFun v2.5) attached to a SparkFun LCD serial backpack.  Also prints the 
  date and time from an AdaFruit RTC 1307 breakout board. 
*/
#include <Wire.h>              // for easy I2C communications with the RTC
#include <OneWire.h>           // OneWire communication library 
#include <DallasTemperature.h> // TEmp Sensor DS18B20 library
#include <math.h>              // library for math manipulations (might not be needed)
#include <SparkSoftLCD.h>  // library to manipulate the LCD
#include "RTClib.h"            //Real Time Clock library (by LadyAda)

#define RTC5vPin 17 // pin 17 (analog pin 3) will be used to provide +5v to the RTC 
#define RTCgndPin 16 // pin 16 (analog pin 2) will be used to provide GND to the RTC

RTC_DS1307 RTC;

#define LCDtxPin 2           // Using Digital Pin 2 as the Soft Serial Tx output
#define LCD_WIDTH 16         // LCD width definition
#define TempSensor_PIN 14    // Analog Pin 0, digital 14
#define buttonPin 12         // Digital pin 12 for push button
#define LED_PIN 13           // Digital Pin 13 led

float temp;                  // temperature variable
int decimals = 1;            // Decimal precision on the temperature
int gate = 0;                // counter to preserve state on push button switch

OneWire oneWire(TempSensor_PIN);  // instantiate a OneWire object
DallasTemperature sensors(&oneWire); // instantiate a sensor (DS18B20) object(s)

long interval = 500;            // interval in ms to get temperature and print it on LCD

SparkSoftLCD LCD = SparkSoftLCD(LCDtxPin, LCD_WIDTH); // create an LCD object with soft serial on pin 2.

void setup() {
 
  pinMode(LED_PIN, OUTPUT);       //sets pin for output
  pinMode(RTC5vPin, OUTPUT);      //sets Pin for output
  digitalWrite(RTC5vPin, HIGH);   // turn pin on (5v) to power RTC
  pinMode(RTCgndPin, OUTPUT);     //sets Pin for output
  digitalWrite(RTCgndPin, LOW);   // turn pin off to (GND) to power RTC
  pinMode(buttonPin, INPUT);      //Sets pin for input
  Wire.begin();                   // Initialize I2C protocol for clock communications
  pinMode(LCDtxPin, OUTPUT);      // Set defined Pin as an Output Pin for transmission
  LCD.begin(9600);                // Set baud rate speed to the LCD backpack on the defined Pin
  LCD.clear();
  RTC.begin(); 
  sensors.begin();
  if (! RTC.isrunning()) {
    LCD.print("RTC is NOT running!");
//  following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  } // end if for RTC adjust
}
void loop(){
  if(digitalRead(buttonPin)  == LOW){
     gate++;
  }
  if(gate == 0){
    digitalWrite(LED_PIN, LOW);
    printTemp();
 //   delay(interval);
  }
  if(gate == 1){
    digitalWrite(LED_PIN, HIGH);
    printClock();
    gate = 0;
    delay(500);
  }
}

/***********************************************************************/
/**********************  BEGIN RTC FUNCTIONS  **************************/
/***********************************************************************/

void printClock(){
    DateTime now = RTC.now();
    LCD.clear();
    LCD.print("Date: ");
    LCD.print(now.month(), DEC);
    LCD.print('/');
    LCD.print(now.day(), DEC);
    LCD.print('/');
    LCD.print(now.year(), DEC);
    LCD.print("Time: ");
    LCD.print(now.hour(), DEC);
    LCD.print(':');
    LCD.print(now.minute(), DEC);
    LCD.print(':');
    LCD.print(now.second(), DEC);

}
/***********************************************************************/
/**********************  END RTC FUNCTIONS  **************************/
/***********************************************************************/


/***********************************************************************/
/*******************  BEGIN TEMPERATURE FUNCTIONS  *********************/
/***********************************************************************/
void printTemp(){
  float temp;
  sensors.requestTemperatures(); // Send the command to get temperatures
  LCD.cursorTo(1,1);
  LCD.print("Real Time Temp: "); 
  LCD.cursorTo(2,1);
  temp = sensors.getTempCByIndex(0);
  printDouble(temp,decimals); LCD.print((char)223); LCD.print("C ,");    // display in Celsius
  temp = sensors.getTempFByIndex(0);
  printDouble(temp,decimals); LCD.print((char)223); LCD.print("F  "); // display in Fahrenheit
}

void printDouble(double val, byte precision) {
  // prints val with number of decimal places determine by precision
  // precision is a number from 0 to 6 indicating the desired decimal places
  // example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)
  LCD.print (int(val));  //prints the int part
  if( precision > 0) {
    LCD.print("."); // print the decimal point
    unsigned long frac, mult = 1;
    byte padding = precision -1;
    while(precision--) mult *=10;
    if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val) - val) * mult;
    unsigned long frac1 = frac;
    while(frac1 /= 10) padding--;
    while(padding--) LCD.print("0");
    LCD.print(frac,DEC) ;
  }
}
/***********************************************************************/
/**********************  END TEMPERATURE FUNCTIONS  ********************/
/***********************************************************************/

I can see your code was nicely put together. Good job.
Instead of getting the library to do AM/PM, you can program a bit more like this:
int hr_24, hr_12;
hr_24=now.hour();

if (hr_24==0) hr_12=12;
else hr_12=hr_24%12;

then
LCD.print(hr_12, DEC);
... everything in between now last line:
if (hr_24<12) LCD.print("AM");
else LCD.print("PM");

Good Idea Liudr! I got so fixated on the libraries that your method never crossed my mind. I'll give it a try tomorrow when my eye-hand-brain coordination gets stable :o. Right now I have 3 mojitos in me and a couple more waiting.

Happy New Year, fellow Arduinites!!!! ;D

Hello Liudr,

Thanks for the suggestion! This is what I ended up doing, look for the time section:

void printClock(){
    DateTime now = RTC.now();
    LCD.clear();
    LCD.cursorTo(1,1);              // Functions to move the cursor to first line fisrt position
    LCD.print("Date ");
    if(now.month() < 10){           // Zero padding if value less than 10 ie."09" instead of "9"
      LCD.print("0");
      LCD.print(now.month(), DEC);
    }
    LCD.print('/');
    if(now.day() < 10){            // Zero padding if value less than 10 ie."09" instead of "9"
      LCD.print("0");
      LCD.print(now.day(), DEC);
    }
    LCD.print('/');
    LCD.print(now.year(), DEC);
/*************  Now comes the time section  **************/
    const uint8_t h = now.hour();
    const uint8_t hr_12 = h%12;
    LCD.cursorTo(2,1);              // Functions to move the cursor to second line fisrt position
    LCD.print("Time ");
    if(hr_12 < 10){                // Zero padding if value less than 10 ie."09" instead of "9"
      LCD.print(" ");
      LCD.print((h > 12) ? h - 12 : ((h == 0) ? 12 : h), DEC); // Conversion to AM/PM  
    }
    else{
      LCD.print((h > 12) ? h - 12 : ((h == 0) ? 12 : h), DEC); // Conversion to AM/PM
    }
    LCD.print(':');
    if(now.minute() < 10){         // Zero padding if value less than 10 ie."09" instead of "9"
      LCD.print("0");
      LCD.print(now.minute(), DEC);
    }
    else{
       LCD.print(now.minute(), DEC);
    }
    LCD.print(':');
    if(now.second() < 10){        // Zero padding if value less than 10 ie."09" instead of "9"
      LCD.print("0");
      LCD.print(now.second(), DEC);
    }
    else{
       LCD.print(now.second(), DEC);
    }
    if(h < 12){                  // Adding the AM/PM sufffix
      LCD.print(" AM");
    }
    else{
      LCD.print(" PM");
    }
}

Great! I never considered 12hr since it is a bit confusing and requires all the programming. :wink:

obbi13, I forgot to mention. I have a fully-functional alarm clock program that you can take whatever parts you want. Here it is:

You will need a few buttons to interact with the clock, setting alarm and the clock.