Project showcase
RTC DS3231 Clock in 12Hours with Date Month DayOfWeek.

RTC DS3231 Clock in 12Hours with Date Month DayOfWeek. © GPL3+

RTC DS3231 Clock in 12Hours with Date Month DayOfWeek using I2C 1602 LCD.

  • 2 views
  • 0 comments
  • 0 respects

Components and supplies

Apps and online services

About this project

I want to build simple digital clock as 'Do It Yourself' using easy and convenient microcontroller and my favourite 'C' programming. Therefore I chose Arduino Uno also tried Nano V3 board. Its works on both boards.

Its all about hobby as well as free educational purpose.

After several failed attempt to code properly, I lookup tutorial based on RTC DS3231 at OSOYOO.COM, which helps easy to understand function of RTC and the code.

However I want to display clock in 12 hours format with AM/PM and day of the week. Its really fun to code this part on 16x2 LCD. With the help of original code I tried to modify it also I added short month name to display in date.

Original code can be found in tutorial : http://osoyoo.com/2017/09/12/arduino-lesson-real-time-clock-rtc-module-ds3231/

Code

DS3232RTC_12hours_Date_I2C_1602_LCDC/C++
Modified code for 12hours clock. Original code can be found here - http://osoyoo.com/2017/09/12/arduino-lesson-real-time-clock-rtc-module-ds3231/
/* Source - http://osoyoo.com/2017/09/12/arduino-lesson-real-time-clock-rtc-module-ds3231/
   Modified 12 hours format removing Temp with simple if-else. Also 3 char month name print on lcd.
   Printing 4 digit year on 16x2 lcd with leading '20' is merely showing century and looks good until end of this century ;)
   Thanks OSOYOO.COM
*/
#include <Wire.h>          // For the i2c devices
#include <LiquidCrystal_I2C.h>  // For the LCD
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#define DS3231_I2C_ADDRESS 104    // RTC is connected, address is Hex68 (Decimal 104)

// SCL - pin A5
// SDA - pin A4
// To set the clock, run the sketch and use the serial monitor.
// Enter T0000123010119; the code will read this and set the clock. See the code for full details.
//
byte seconds, minutes, hours, day, date, month, year;
char monthName[4];
char weekDay[4];

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  lcd.init();                      // initialize the lcd 
}

void loop()
{
  watchConsole(); 
  get3231Date();
  
// Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Time ");
    if (hours<=12)
     {
       lcd.print(hours, DEC);
       lcd.print(":");
       lcd.print(minutes, DEC);
       lcd.print(":");
       lcd.print(seconds, DEC);
       lcd.print("  ");
       lcd.setCursor(14,0);
       lcd.print("AM");
    } else { 
  lcd.print((hours-12), DEC);
  lcd.print(":");
  lcd.print(minutes, DEC);
  lcd.print(":");
  lcd.print(seconds, DEC);
  lcd.print("  ");
  lcd.setCursor(14,0);
  lcd.print("PM");
    }
  lcd.setCursor(0,1);
  lcd.print(weekDay); 
  lcd.print(", ");
  lcd.print(date, DEC); 
  lcd.print("-"); 
  //lcd.print(month, DEC);
  lcd.print(monthName);
  lcd.print("-20"); 
  lcd.print(year, DEC);
  delay(1000);
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

void watchConsole()
{
  if (Serial.available()) {      // Look for char in serial queue and process if found
    if (Serial.read() == 84) {      //If command = "T" Set Date
      set3231Date();
      get3231Date();
    }
  }
}
 
void set3231Date()
{
//T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year)
//T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
//Example: 01-Jan-19 @ 12:00:00 for the 3rd day of the week -> T0000123010119
// T0000123010119
  seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result.  
  minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  day     = (byte) (Serial.read() - 48);
  date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.write(decToBcd(seconds));
  Wire.write(decToBcd(minutes));
  Wire.write(decToBcd(hours));
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(date));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}


void get3231Date()
{
  // send request to receive data starting at register 0
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x00); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes

  if(Wire.available()) {
    seconds = Wire.read(); // get seconds
    minutes = Wire.read(); // get minutes
    hours   = Wire.read();   // get hours
    day     = Wire.read();
    date    = Wire.read();
    month   = Wire.read(); //temp month
    year    = Wire.read();
       
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
  else {
    //NULL
  }
 
  switch (day) {
    case 1:
      strcpy(weekDay, "Sun");
      break;
    case 2:
      strcpy(weekDay, "Mon");
      break;
    case 3:
      strcpy(weekDay, "Tue");
      break;
    case 4:
      strcpy(weekDay, "Wed");
      break;
    case 5:
      strcpy(weekDay, "Thu");
      break;
    case 6:
      strcpy(weekDay, "Fri");
      break;
    case 7:
      strcpy(weekDay, "Sat");
      break;
  }

switch (month) {
  
    case 1:
      strcpy(monthName, "Jan");
      break;
    case 2:
      strcpy(monthName, "Feb");
      break;
    case 3:
      strcpy(monthName, "Mar");
      break;
    case 4:
      strcpy(monthName, "Apr");
      break;
    case 5:
      strcpy(monthName, "May");
      break;
    case 6:
      strcpy(monthName, "Jun");
      break;
    case 7:
      strcpy(monthName, "Jul");
      break;
    case 8:
      strcpy(monthName, "Aug");
       break;
    case 9:
      strcpy(monthName, "Sep");
      break;
    case 10:
      strcpy(monthName, "Oct");
      break;
    case 11:
      strcpy(monthName, "Nov");
      break;
    case 12:
      strcpy(monthName, "Dec");
      break;  
    }
}

Schematics

RTC DS3231 Clock
Modified in 12hour format with month name using source code on http://osoyoo.com/2017/09/12/arduino-lesson-real-time-clock-rtc-module-ds3231/
Hardware diagram zaxfh9wxwo

Comments

Add projectSign up / Login