// Arduino code for a clock with date and alarm using DS1307 RTC module
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <DS1307RTC.h>
// Define the LCD pins
#define LCD_RS 12
#define LCD_EN 11
#define LCD_D4 10
#define LCD_D5 9
#define LCD_D6 8
#define LCD_D7 7
// Define the buzzer pin
#define BUZZER_PIN 6
// Define the keypad keys and pins
const char keys[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[4] = {5, 4, 3, 2};
byte colPins[4] = {A3, A2, A1, A0};
// Initialize the LCD, keypad, and RTC objects
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, 4, 4 );
DS1307RTC rtc;
// Define some constants for display modes and time formats
enum DisplayMode {DisplayClock, DisplayDate, DisplayAlarmTime};
enum TimeFormat {Hour24, Hour12};
// Define some global variables for display mode and time format preferences
DisplayMode displayMode = DisplayClock;
TimeFormat timeFormat = Hour24;
// Define some global variables for alarm time and status (on or off)
int alarmHour = 0;
int alarmMinute = 0;
bool alarmOn = false;
// Define some global variables for input buffer and count (used for setting time and alarm)
char inputBuffer[5] = "";
int inputCount = 0;
void setup() {
// Set up the LCD size and turn on backlight
lcd.begin(16, 2);
// Turn on RTC oscillator and set time if needed (uncomment the following line)
// rtc.write(tmElements_t {0,29,16,Friday,22,9,(uint8_t)(tmYearToY2k(2023))}); // Set time to hh:mm:ss day dd/mm/yyyy (change as needed)
}
void loop() {
// Get current time and date from RTC module
tmElements_t now;
rtc.read(now);
int hour = now.Hour;
int minute = now.Minute;
int second = now.Second;
int day = now.Day;
int month = now.Month;
int year = tmYearToCalendar(now.Year);
// Check if alarm is on and matches current time (ignore seconds)
if (alarmOn && hour == alarmHour && minute == alarmMinute) {
// Sound the buzzer for one second
tone(BUZZER_PIN, 1000);
delay(1000);
noTone(BUZZER_PIN);
}
// Display current time, date, or alarm time based on display mode
switch (displayMode) {
case DisplayClock:
// Display current time in 24-hour or 12-hour format
lcd.clear();
lcd.print("Time: ");
if (timeFormat == Hour24) {
// Display time in 24-hour format
lcd.print(hour);
} else {
// Display time in 12-hour format
lcd.print(hour % 12 == 0 ? 12 : hour % 12);
lcd.print(hour < 12 ? " AM" : " PM");
}
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute);
// Display alarm status and time format on the second row
lcd.setCursor(0, 1);
lcd.print("Alarm: ");
lcd.print(alarmOn ? "ON " : "OFF");
lcd.print(" ");
lcd.print(timeFormat == Hour24 ? "24H" : "12H");
break;
case DisplayDate:
// Display current date in dd/mm/yyyy format
lcd.clear();
lcd.print("Date: ");
if (day < 10) {
lcd.print("0");
}
lcd.print(day);
lcd.print("/");
if (month < 10) {
lcd.print("0");
}
lcd.print(month);
lcd.print("/");
lcd.print(year);
break;
case DisplayAlarmTime:
// Display alarm time in hh:mm format
lcd.clear();
lcd.print("Alarm: ");
if (alarmHour < 10) {
lcd.print("0");
}
lcd.print(alarmHour);
lcd.print(":");
if (alarmMinute < 10) {
lcd.print("0");
}
lcd.print(alarmMinute);
}
// Read input from keypad and perform actions based on input
char key = keypad.getKey();
if (key != NO_KEY) {
switch (key) {
case 'A':
// Change display mode to clock
displayMode = DisplayClock;
break;
case 'B':
// Change display mode to date
displayMode = DisplayDate;
break;
case 'C':
// Change display mode to alarm time
displayMode = DisplayAlarmTime;
break;
case 'D':
// Toggle alarm status (on or off)
alarmOn = !alarmOn;
break;
case '*':
// Toggle time format (24-hour or 12-hour)
if (timeFormat == Hour24) {
timeFormat = Hour12;
} else {
timeFormat = Hour24;
}
break;
case '#':
// Set current time or alarm time based on input buffer
if (inputCount == 4) {
// Parse input buffer as hhmm format
int inputHour = (inputBuffer[0] - '0') * 10 + (inputBuffer[1] - '0');
int inputMinute = (inputBuffer[2] - '0') * 10 + (inputBuffer[3] - '0');
if (displayMode == DisplayClock) {
// Set current time to input time
rtc.write(tmElements_t {0, inputMinute, inputHour, now.Wday, now.Day, now.Month, now.Year});
} else if (displayMode == DisplayAlarmTime) {
// Set alarm time to input time
alarmHour = inputHour;
alarmMinute = inputMinute;
}
// Clear input buffer and count
inputBuffer[0] = '\0';
inputCount = 0;
}
break;
default:
// Append numeric key to input buffer if not full
if (inputCount < 4 && key >= '0' && key <= '9') {
inputBuffer[inputCount] = key;
inputCount++;
// Display input buffer on LCD
lcd.setCursor(6, 1);
for (int i = 0; i < inputCount; i++) {
lcd.print(inputBuffer[i]);
}
}
}
}
}