Overview
This project reads value of the current date and time from the RTC module and displays it on a 20x4 LCD with an I2C backpack.
Components
Component | Purpose |
---|---|
Arduino Nano | This will be the microcontroller |
I2C LCD 20X4 | This will be the LCD display |
DS3231 RTC | The will the real time clock |
Circuit Diagram
Connections
DS3231 RTC Pin Connections
Nano Pin | DS3231 RTC Pin |
---|---|
A4 | SDA |
A5 | SCL |
5V | VCC |
GND | GND |
I2C LCD Pin
Nano Pin | I2C LCD Pin |
---|---|
A4 | SDA |
A5 | SCL |
5V | VCC |
GND | GND |
Code
/*
Project: Real time clock.
Project Description:
This module maintains real time for circuits and has a battery to retain the time even when they are powered off.
Author: STEMVentor Educonsulting
This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs.
This code is for educational purposes only and is not for production use.
*/
// LIBRARIES
// Used for communicating with I2C devices
#include <Wire.h>
// https://www.arduino.cc/reference/en/libraries/liquidcrystal-i2c/
// Install the LiquidCrystal I2C by Frank de Brabander from the IDE library manager.
#include <LiquidCrystal_I2C.h>
// RTCLib by NeiroN
#include <RTClib.h>
// PIN DEFINTIONS
// CONSTANT DEFINITIONS
// GLOBAL VARIABLES
DS3231 rtc;
char dateString[32];
char timeString[32];
// Define the display size
const byte rows = 4;
const byte cols = 20;
/* INITIALIZE OBJECTS
* Libraries usually follow an object-oriented approach that requires
* an instance of the class to call its methods.
*/
/*
* All I2C components have an address, the default is usually 0x27
* If that doesn't work, see this:https://playground.arduino.cc/Main/I2cScanner/
* The init statement accepts the address and the number of columns and rows.
*/
LiquidCrystal_I2C lcd(0x27, cols, rows);
// LOCAL FUNCTIONS
/*
Function to print to LCD on a single row.
Takes the row number and the text to display on that row (max 20 chars, rest will be truncated).
The entire display is cleared if the clearAll flag is true, else only the row is cleared (the default).
*/
void printToLcdByRow(int row, String text, bool clearAll = false) {
const char* twentySpaces = " ";
if (clearAll) {
lcd.clear(); // clears the entire display
}
lcd.setCursor(0, row - 1);
lcd.print(twentySpaces); // clears the row
lcd.setCursor(0, row - 1); // cursor has to be set again after printing spaces
lcd.print(text);
}
/*
Function to print to LCD across rows with each row having 20 chars.
Messages can be a maximum of 20x4 chars, rest will be truncated.
The entire display is cleared before printing the text.
Test string of 20 char:
12345678901234567890
Test strings of 80 chars:
12345678901234567890123456789012345678901234567890123456789012345678901234567890
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius est donec.
*/
void printToLcd(String text) {
lcd.clear(); // clears the entire display
byte charsRemaining = text.length();
byte charFrom = 0;
byte charTo = charsRemaining < cols ? text.length() : charFrom + cols;
byte row = 1;
while (charsRemaining > 0) {
String line = text.substring(charFrom, charTo);
printToLcdByRow(row, line);
charsRemaining = text.length() - charTo;
charFrom = charTo;
charTo = charsRemaining < cols ? text.length() : charFrom + cols;
row++;
}
Serial.println("Data string has been displayed on LCD");
}
void lcdSetup() // function to LCD setup
{
// Initializing wire
Wire.begin();
// Initialize the LCD.
lcd.init();
// Turn on the blacklight and print a message.
lcd.backlight();
// Use the function to display text on each line individually.
printToLcdByRow(1, "I2C LCD Ready!", true);
printToLcdByRow(2, "Enter some text.", false);
printToLcdByRow(3, "Max 80 characters.", false);
printToLcdByRow(4, "For a 20x4 LCD.", false);
delay(1000);
}
void rtcSetup()
{
rtc.begin();
// rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
rtc.adjust(DateTime(2019, 1, 21, 5, 0, 0));
}
// THE setup FUNCTION RUNS ONCE WHEN YOU PRESS RESET OR POWER THE BOARD.
void setup() {
// Start the serial communication with baud rate suitable for your components.
Serial.begin(9600);
lcdSetup();
rtcSetup();
Serial.println("The board is ready!");
printToLcdByRow(1, "Date :", true);
printToLcdByRow(3, "Time :", true);
}
void readRTCValue()
{
DateTime now = rtc.now();
sprintf(dateString, "%02d/%02d/%02d", now.day(), now.month(), now.year());
sprintf(timeString, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
}
// THE loop FUNCTION RUNS OVER AND OVER AGAIN FOREVER UNTIL THE BOARD IS POWERED OFF.
void loop() {
readRTCValue();
printToLcdByRow(2 , dateString , true);
printToLcdByRow(4, timeString, true);
delay(1000);
}