//Copyright (C) 22.09.2023, Kirill ZHivotkov
#include <IRremote.h>
#include <LiquidCrystal_I2C.h>
#include <ezBuzzer.h>
#include "RTClib.h"
#include <Wire.h>
ezBuzzer buzzer(9);
LiquidCrystal_I2C lcd(39, 16, 2); //Address = 39
RTC_DS1307 rtc;
//Notes in the melody:
int melody[] = {
NOTE_E5, NOTE_E5, NOTE_E5,
NOTE_E5, NOTE_E5, NOTE_E5,
NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5,
NOTE_E5,
NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5,
NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
NOTE_E5, NOTE_D5, NOTE_D5, NOTE_E5,
NOTE_D5, NOTE_G5
};
//Notes in the melody:
//Note durations: 4 = quarter note, 8 = eighth note, etc., also called tempo:
int noteDurations[] = {
8, 8, 4,
8, 8, 4,
8, 8, 8, 8,
2,
8, 8, 8, 8,
8, 8, 8, 16, 16,
8, 8, 8, 8,
4, 4
};
//Note durations: 4 = quarter note, 8 = eighth note, etc., also called tempo:
//Alarm clock set icon
byte alarm_icon[8] = { B00000, B10001, B01110, B10001, B10001, B01110, B11111, B00000 };
//Alarm clock set icon
//Alarm clock melody icon
byte melody_icon[8] = { B00000, B00100, B00110, B00101, B00100, B11100, B11100, B00000 };
//Alarm clock melody icon
//Implement class "Cursor"
class Cursor {
private:
int cursor = 0;
int pos = 0;
int row = 0;
bool isSetMode = 0;
bool isSetAlarmMode = 0;
double cursorTiming = 0.0;
public:
void setLCDCursor(int, int);
void setCursorPos(int);
int getCursorPos();
void setCursorTiming(double);
double getCursorTiming();
void setIsSetModeValue(bool);
bool getIsSetModeValue();
void setIsSetAlarmModeValue(bool);
bool getIsSetAlarmModeValue();
void cursorStopBlink();
void cursorStartBlink();
void switchEditTimeMode(unsigned long);
void showAlarmMessage(String);
void switchEditAlarmMode(unsigned long);
void setCursorMaxBlinking();
//Конструктор по умолчанию
Cursor() {}
//Конструктор по умолчанию
};
//Implement class "Cursor"
//Implement class setters
void Cursor::setCursorPos(int cursor) { //Set LCD cursor position
this->cursor = cursor;
}
void Cursor::setCursorTiming(double cursorTiming) {
this->cursorTiming = cursorTiming;
}
void Cursor::setLCDCursor(int pos, int row) { //Set cursor position on LCD display
if ((pos >= 0 && pos <= 15) && (row == 0 || row == 1)) {
this->pos = pos;
this->row = row;
lcd.setCursor(this->pos, this->row);
}
}
void Cursor::setIsSetModeValue(bool isSetMode) { //Set time set status (cursor is blinking or not)
this->isSetMode = isSetMode;
}
void Cursor::setIsSetAlarmModeValue(bool isSetAlarmMode) { //Set time set status (cursor is blinking or not)
this->isSetAlarmMode = isSetAlarmMode;
}
//Implement class setters
//Implement class getters
int Cursor::getCursorPos() { //Get cursor position on LCD display
return this->cursor;
}
double Cursor::getCursorTiming() {
return this->cursorTiming;
}
bool Cursor::getIsSetModeValue() { //Get time set status (cursor is blinking or not)
return this->isSetMode;
}
bool Cursor::getIsSetAlarmModeValue() { //Get alarm set status (cursor is blinking or not)
return this->isSetAlarmMode;
}
//Implement class getters
void Cursor::cursorStopBlink() { //Switch cursor blinking off
lcd.noBlink();
}
void Cursor::cursorStartBlink() { //Switch cursor blinking on
lcd.blink();
}
void Cursor::switchEditTimeMode(unsigned long a) { //Describe time setting mode (for cursor)
if (a == 1336999680 && this->getIsSetModeValue() == 0) {
lcd.setCursor(this->getCursorPos(), 0);
this->cursorStartBlink();
this->isSetMode = 1;
} else if (a == 1470693120 && this->getIsSetModeValue() == 1) {
lcd.setCursor(0, 0);
this->cursorStopBlink();
this->isSetMode = 0;
}
}
void Cursor::showAlarmMessage(String msg) { //Output an error message (time or date were set incorrectly)
this->cursorStopBlink();
this->setLCDCursor(0, 1);
lcd.print(msg);
this->setLCDCursor(this->getCursorPos(), 0);
this->cursorStartBlink();
}
void Cursor::switchEditAlarmMode(unsigned long a) { //Describe alarm setting mode (for cursor)
if (this->getIsSetModeValue() == 1) {
if (a == 1738080000 && this->getIsSetAlarmModeValue() == 0) {
//lcd.setCursor(this->getCursorPos(), 0);
//this->cursorStartBlink();
this->isSetAlarmMode = 1;
} else if (a == 4244832000 && this->getIsSetAlarmModeValue() == 1) {
//lcd.setCursor(0, 0);
//this->cursorStopBlink();
this->showAlarmMessage(" ");
this->showAlarmMessage("Alarm is set");
//this->isSetAlarmMode = 0;
}
}
}
void Cursor::setCursorMaxBlinking() { //Set cursor maximum blinking
if (((millis() - this->getCursorTiming()) >= 120000) && (this->getIsSetModeValue() == 1)) { //Max blinking = 2 minutes
this->cursorStopBlink();
this->isSetMode = 0;
this->setLCDCursor(this->getCursorPos(), 0);
}
}
//Create instances of the classes described above
Cursor* cur = new Cursor();
//Create instances of the classes described above
//Implement class "Display"
class LCD {
private:
int digit = 0;
//Time (clock)
int h = 0;
int hh = 0;
int m = 0;
int mm = 0;
//Time
//Time (alarm)
int h_a = 0;
int hh_a = 0;
int m_a = 0;
int mm_a = 0;
//Time
//Date (clock)
int d = 0;
int dd = 1;
int mth = 0;
int mmth = 1;
int y = 2;
int yy = 0;
int yyy = 0;
int yyyy = 0;
//Date (clock)
//Date (alarm)
int d_a = 0;
int dd_a = 1;
int mth_a = 0;
int mmth_a = 1;
int y_a = 2;
int yy_a = 0;
int yyy_a = 3;
int yyyy_a = 0;
//Date (alarm)
//Weekday
int weekDay = -1;
//Weekday
bool isOff = 0;
bool isSetAlarm = 0;
bool isStopAlarm = 1;
public:
bool checkHours(int);
bool checkMinutes(int);
bool checkDays(int);
bool checkMonths(int);
bool checkYears(int);
bool checkLeapYear(int);
int getMinute();
int getMinuteAlarm();
int getHour();
int getHourAlarm();
int getDay();
int getDayAlarm();
int getMonth();
int getMonthAlarm();
int getYear();
int getYearAlarm();
int getWeekDay();
void setIsAlarm(bool);
bool getIsSetAlarm();
void setStopAlarm(bool);
bool getIsStopAlarm();
bool checkDisplayData();
bool checkAlarmValidity();
void showAlarmMessage(String);
void copyClockValuesToAlarm(unsigned long);
void setIsOff(bool);
bool getIsOff();
void showAlarmIcon(byte*);
void setClockTimeMode(unsigned long);
void setClockDigit(int);
void setAdjustedClockTime();
void setDisplay(int);
void setDisplay(String);
void displayProcessedDate();
void displayProcessedWeekDay();
void displayProcessedTime();
void switchDisplayOn();
void switchBackLightOn();
void switchDisplayOff();
void switchBackLightOff();
void clearDisplay();
void switchDisplayOnOff(unsigned long);
//Default constructor
LCD() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
//pinMode(9, OUTPUT); //if LCD backlight jumper is removed (for Arduino Uno)
//analogWrite(9, 10);
}
//Default constructor
};
//Implement class "Display"
bool LCD::checkHours(int h) { //Check hours range
if (h >= 0 && h <= 23) {
return true;
}
return false;
}
bool LCD::checkMinutes(int m) { //Check minutes range
if (m >= 0 && m <= 59) {
return true;
}
return false;
}
bool LCD::checkDays(int d) { //Check days range
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (checkLeapYear(this->getYear()) == true && days[1] == 28) {
days[1]++;
}
if (d >= 1 && d <= days[this->getMonth() - 1]) {
return true;
}
return false;
}
bool LCD::checkMonths(int m) { //Check months range
if (m >= 1 && m <= 12) {
return true;
}
return false;
}
bool LCD::checkYears(int y) { //Check years range
if (y >= 2000 && y <= 2030) {
return true;
}
return false;
}
bool LCD::checkLeapYear(int y) { //Check leap year
if (y % 400 == 0) {
return true;
} else if (y % 100 == 0) {
return false;
} else if (y % 4 == 0) {
return true;
} else {
return false;
}
}
int LCD::getMinute() { //Get a minute (clock)
return this->m * 10 + this->mm;
}
int LCD::getMinuteAlarm() { //Get a minute (alarm)
return this->m_a * 10 + this->mm_a;
}
int LCD::getHour() { //Get an hour (clock)
return this->h * 10 + this->hh;
}
int LCD::getHourAlarm() { //Get an hour (alarm)
return this->h_a * 10 + this->hh_a;
}
int LCD::getDay() { //Get a day (clock)
return this->d * 10 + this->dd;
}
int LCD::getDayAlarm() { //Get a day (alarm)
return this->d_a * 10 + this->dd_a;
}
int LCD::getMonth() { //Get a month (clock)
return this->mth * 10 + this->mmth;
}
int LCD::getMonthAlarm() { //Get a month (alarm)
return this->mth_a * 10 + this->mmth_a;
}
int LCD::getYear() { //Get a year (clock)
return this->y * 1000 + this->yy * 100 + this->yyy * 10 + this->yyyy;
}
int LCD::getYearAlarm() { //Get a year (alarm)
return this->y_a * 1000 + this->yy_a * 100 + this->yyy_a * 10 + this->yyyy_a;
}
int LCD::getWeekDay() { //Get a weekday
return this->weekDay;
}
//Functions for clock alarm
void LCD::setIsAlarm(bool isSetAlarm) { //Set alarm status
this->isSetAlarm = isSetAlarm;
}
bool LCD::getIsSetAlarm() { //Get alarm status
return this->isSetAlarm;
}
void LCD::setStopAlarm(bool stopAlarm) { //Set alarm status
this->isStopAlarm = stopAlarm;
}
bool LCD::getIsStopAlarm() { //Get alarm status
return this->isStopAlarm;
}
//Functions for clock alarm
bool LCD::checkDisplayData() { //Check input data format
if (this->checkHours(this->getHour()) == true &&
this->checkMinutes(this->getMinute()) == true &&
this->checkDays(this->getDay()) == true &&
this->checkMonths(this->getMonth()) == true &&
this->checkYears(this->getYear()) == true) {
return true;
}
return false;
}
bool LCD::checkAlarmValidity() { //Check alarm validity
if ((this->getHour() != this->getHourAlarm()) ||
(this->getMinute() != this->getMinuteAlarm()) ||
(this->getDay() != this->getDayAlarm()) ||
(this->getMonth() != this->getMonthAlarm()) ||
(this->getYear() != this->getYearAlarm())) {
return true;
}
return false;
}
void LCD::showAlarmMessage(String msg) { //Output an alarm error
cur->cursorStopBlink();
cur->setLCDCursor(0, 1);
this->setDisplay(msg);
cur->setLCDCursor(cur->getCursorPos(), 0);
cur->cursorStartBlink();
}
void LCD::copyClockValuesToAlarm(unsigned long a) {
if (a == 1738080000 && cur->getIsSetAlarmModeValue() == 1) {
//Time (alarm)
this->h_a = this->getHour() / 10;
this->hh_a = this->getHour() % 10;
this->m_a = this->getMinute() / 10;
this->mm_a = this->getMinute() % 10;
//Time (alarm)
//Date (alarm)
this->d_a = this->getDay() / 10;
this->dd_a = this->getDay() % 10;
this->mth_a = this->getMonth() / 10;
this->mmth_a = this->getMonth() % 10;
this->y_a = this->getYear() / 1000;;
this->yy_a = this->getYear() / 100 % 10;;
this->yyy_a = this->getYear() / 10 % 10;;
this->yyyy_a = this->getYear() % 10;
//Date (alarm)
cur->showAlarmMessage("Alarm mode on");
} else if (a == 3091726080 && cur->getIsSetAlarmModeValue() == 1) {
//cur->setIsSetModeAlarmValue(0);
//showAlarmMessage("Alarm mode off");
}
}
void LCD::setIsOff(bool isOff) { //Set LCD status (if display is on or off)
this->isOff = isOff;
}
bool LCD::getIsOff() { //Get LCD status (if display is on or off)
return this->isOff;
}
void LCD::showAlarmIcon(byte* icon) { //Show alarm icon (set or melody states)
lcd.createChar(0, icon);
lcd.setCursor(15, 1);
lcd.print(char(0));
}
void LCD::setClockTimeMode(unsigned long a) { //Time setting function
if (cur->getIsSetModeValue() == 1) {
if (a == 534839040) { //Move cursor to the left
if (cur->getCursorPos() > 0) {
//Time
if (cur->getCursorPos() == 3) {
cur->setCursorPos(1);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
//Time
//Date
else if (cur->getCursorPos() == 6) {
cur->setCursorPos(4);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else if (cur->getCursorPos() == 9) {
cur->setCursorPos(7);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else if (cur->getCursorPos() == 12) {
cur->setCursorPos(10);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else {
cur->setCursorPos(cur->getCursorPos() - 1);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
//Date
}
} else if (a == 1871773440) { //Move cursor to the right
if (cur->getCursorPos() < 16) {
//Time
if (cur->getCursorPos() == 1) {
cur->setCursorPos(3);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
//Time
//Date
else if (cur->getCursorPos() == 4) {
cur->setCursorPos(6);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else if (cur->getCursorPos() == 7) {
cur->setCursorPos(9);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else if (cur->getCursorPos() == 10) {
cur->setCursorPos(12);
cur->setLCDCursor(cur->getCursorPos(), 0);
} else {
cur->setCursorPos(cur->getCursorPos() + 1);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
//Date
}
} else {
if (cur->getCursorPos() >= 0 && cur->getCursorPos() <= 15) {
if (a == 2540240640) { //Key 0
this->setClockDigit(0);
} else if (a == 3476094720) { //Key 1
this->setClockDigit(1);
} else if (a == 3877175040) { //Key 2
this->setClockDigit(2);
} else if (a == 2239430400) { //Key 3
this->setClockDigit(3);
} else if (a == 4010868480) { //Key 4
this->setClockDigit(4);
} else if (a == 3342401280) { //Key 5
this->setClockDigit(5);
} else if (a == 2774204160) { //Key 6
this->setClockDigit(6);
} else if (a == 3175284480) { //Key 7
this->setClockDigit(7);
} else if (a == 3041591040) { //Key 8
this->setClockDigit(8);
} else if (a == 2907897600) { //Key 9
this->setClockDigit(9);
}
}
}
} else { //
}
}
void LCD::setClockDigit(int digit) { //Input and output LCD dispay digits from 1 to 9
this->digit = digit;
if (this->digit >= 0 && this->digit <= 9) {
if (cur->getCursorPos() == 0) { //Hours
if (cur->getIsSetAlarmModeValue() == 0) {
this->h = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->h);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->h_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->h_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 1) { //Hours
if (cur->getIsSetAlarmModeValue() == 0) {
this->hh = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->hh);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->hh_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->hh_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 3) { //Minutes
if (cur->getIsSetAlarmModeValue() == 0) {
this->m = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->m);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->m_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->m_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 4) { //Minutes
if (cur->getIsSetAlarmModeValue() == 0) {
this->mm = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mm);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->mm_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mm_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 6) { //Days
if (cur->getIsSetAlarmModeValue() == 0) {
this->d = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->d);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->d_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->d_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 7) { //Days
if (cur->getIsSetAlarmModeValue() == 0) {
this->dd = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->dd);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->dd_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->dd_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 9) { //Months
if (cur->getIsSetAlarmModeValue() == 0) {
this->mth = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mth);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->mth_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mth_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 10) { //Months
if (cur->getIsSetAlarmModeValue() == 0) {
this->mmth = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mmth);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->mmth_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->mmth_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 12) { //Years
if (cur->getIsSetAlarmModeValue() == 0) {
this->y = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->y);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->y_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->y_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 13) { //Years
if (cur->getIsSetAlarmModeValue() == 0) {
this->yy = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yy);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->yy_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yy_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 14) { //Years
if (cur->getIsSetAlarmModeValue() == 0) {
this->yyy = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yyy);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->yyy_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yyy_a);
cur->cursorStartBlink();
}
} else if (cur->getCursorPos() == 15) { //Years
if (cur->getIsSetAlarmModeValue() == 0) {
this->yyyy = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yyyy);
cur->cursorStartBlink();
} else if (cur->getIsSetAlarmModeValue() == 1) {
this->yyyy_a = this->digit;
cur->cursorStopBlink();
this->setDisplay(this->yyyy_a);
cur->cursorStartBlink();
}
}
if (this->checkDisplayData() == true) { //Move through the first display row to the right after a digit was confirmed to be set
if (cur->getCursorPos() != 1 &&
cur->getCursorPos() != 4 &&
cur->getCursorPos() != 7 &&
cur->getCursorPos() != 10) {
if (cur->getCursorPos() >= 0 && cur->getCursorPos() < 15) {
cur->setCursorPos(cur->getCursorPos() + 1);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
} else {
cur->setCursorPos(cur->getCursorPos() + 1);
cur->setCursorPos(cur->getCursorPos() + 1);
cur->setLCDCursor(cur->getCursorPos(), 0);
}
}
}
}
void LCD::setAdjustedClockTime() { //Set a new time (clock)
if (this->getIsOff() == 0) { //If LCD display is on
if (this->checkAlarmValidity() == true || this->getIsStopAlarm() == 1) {
DateTime now = rtc.now();
if (now.hour() < 10) {
this->h = 0;
this->hh = now.hour();
Serial.print("h >>> ");
Serial.print(this->h);
Serial.print(" hh >>> ");
Serial.print(this->hh);
} else {
this->h = now.hour() / 10;
this->hh = now.hour() % 10;
Serial.print("h >>> ");
Serial.print(this->h);
Serial.print(" hh >>> ");
Serial.print(this->hh);
}
if (now.minute() < 10) {
this->m = 0;
this->mm = now.minute();
Serial.print(" m >>> ");
Serial.print(this->m);
Serial.print(" mm >>> ");
Serial.print(this->mm);
} else {
this->m = now.minute() / 10;
this->mm = now.minute() % 10;
Serial.print(" m >>> ");
Serial.print(this->m);
Serial.print(" mm >>> ");
Serial.print(this->mm);
}
Serial.print(" ");
Serial.print(now.second());
Serial.println();
if (now.day() >= 0 && now.day() < 10) {
this->d = 0;
this->dd = now.day();
} else {
if (now.day() >= 1 && now.day() <= 31) {
this->d = now.day() / 10;
this->dd = now.day() % 10;
}
}
if (now.month() >= 0 && now.month() < 10) {
this->mth = 0;
this->mmth = now.month();
} else {
if (now.month() >= 10 && now.month() <= 12) {
this->mth = now.month() / 10;
this->mmth = now.month() % 10;
}
}
if (now.year() >= 2000 && now.year() <= 2030) {
this->y = now.year() / 1000;
this->yy = now.year() / 100 % 10;
this->yyy = now.year() / 10 % 10;
this->yyyy = now.year() % 10;
}
//Очищаем дисплей, если день недели изменился
if (this->weekDay != -1 && this->weekDay != now.dayOfTheWeek()) {
this->clearDisplay();
}
//Очищаем дисплей, если день недели изменился
this->weekDay = now.dayOfTheWeek();
this->displayProcessedTime();
this->displayProcessedDate();
this->displayProcessedWeekDay();
Serial.print("Alarm h => ");
Serial.println(this->getHourAlarm());
Serial.print("Alarm m => ");
Serial.println(this->getMinuteAlarm());
Serial.print("Alarm d => ");
Serial.println(this->getDayAlarm());
Serial.print("Alarm m => ");
Serial.println(this->getMonthAlarm());
Serial.print("Alarm y => ");
Serial.println(this->getYearAlarm());
//Serial.print("1 => ");
//Serial.println(cur->getIsSetModeValue());
//Serial.print("2 => ");
//Serial.println(cur->getIsSetAlarmModeValue());
delay(1000);
} else { //Будильник сработал
this->displayProcessedTime();
this->displayProcessedDate();
this->displayProcessedWeekDay();
}
} else { //Else
//Reset time
//this->clearDisplay();
//rtc.adjust(DateTime(2000, 1, 1, 0, 0, 0));
//Reset time
}
}
void LCD::setDisplay(int data) { //Output info to the display (number)
lcd.print((String)data);
}
void LCD::setDisplay(String data) { //Output info to the display (string)
lcd.print(data);
}
void LCD::displayProcessedDate() { //Output calculated date
cur->setLCDCursor(6, 0);
//Day
if (this->d * 10 + this->dd < 10) {
this->setDisplay("0" + (String)(this->d * 10 + this->dd));
} else {
this->setDisplay((String)(this->d * 10 + this->dd));
}
//Day
this->setDisplay("-");
//Month
if (this->mth * 10 + this->mmth < 10) {
this->setDisplay("0" + (String)(this->mth * 10 + this->mmth));
} else {
this->setDisplay((String)(this->mth * 10 + this->mmth));
}
//Month
this->setDisplay("-");
//Year
int tmp_year = this->y * 1000 + this->yy * 100 + this->yyy * 10 + this->yyyy;
if (tmp_year >= 2000 && tmp_year <= 2030) {
this->setDisplay((String)(tmp_year));
} else {
this->setDisplay("2000");
}
//Year
}
void LCD::displayProcessedWeekDay() { //Output calculated weekday
String week[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
if (this->getIsSetAlarm() == 0) {
cur->setLCDCursor(0, 1);
//this->clearDisplay();
this->setDisplay(week[this->weekDay]);
} else if (this->getIsSetAlarm() == 1 && (cur->getIsSetAlarmModeValue() == 1)) {
cur->setLCDCursor(0, 1);
//this->clearDisplay();
this->setDisplay(week[this->weekDay]);
this->showAlarmIcon(alarm_icon);
}
}
void LCD::displayProcessedTime() { //Output calculated time
cur->setLCDCursor(0, 0);
//Hour
if (this->h * 10 + this->hh < 10) {
this->setDisplay("0" + (String)(this->h * 10 + this->hh));
} else {
this->setDisplay((String)(this->h * 10 + this->hh));
}
//Hour
this->setDisplay(":");
//Minute
if (this->m * 10 + this->mm < 10) {
this->setDisplay("0" + (String)(this->m * 10 + this->mm));
} else {
this->setDisplay((String)(this->m * 10 + this->mm));
}
//Minute
}
void LCD::switchDisplayOn() { //Switch LCD display on
lcd.display();
}
void LCD::switchBackLightOn() { //Switch LCD backlight on
lcd.backlight();
}
void LCD::switchDisplayOff() { //Switch LCD display off
lcd.noDisplay();
}
void LCD::switchBackLightOff() { //Switch LCD backlight off
lcd.noBacklight();
}
void LCD::clearDisplay() { //Clear the whole display
cur->cursorStopBlink();
cur->setIsSetModeValue(0);
lcd.clear();
}
void LCD::switchDisplayOnOff(unsigned long a) { //Compound function to switch LCD display on/off
if (this->getIsOff() == 0) {
//this->switchDisplayOff();
this->switchBackLightOff();
this->setIsOff(1);
//cur->cursorStopBlink();
} else if (this->getIsOff() == 1) {
//this->switchDisplayOn();
this->switchBackLightOn();
//cur->setIsSetModeValue(0);
this->setIsOff(0);
}
}
//Create an instance of the class described above
LCD* disp;
//Create an instance of the class described above
//Setup
void setup() {
disp = new LCD();
disp->clearDisplay();
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(2000, 1, 1, 0, 0, 0));
pinMode(A0, INPUT);
IrReceiver.begin(A0, ENABLE_LED_FEEDBACK);
Serial.begin(9600);
}
//Setup
//Implement class "Sound"
class Sound {
private:
String msg = "";
public:
void setErrorMessage(String);
void showErrorMessage();
void playErrorSound();
};
//Implement class "Sound"
void Sound::setErrorMessage(String msg) { //Set an error message restriction
if (msg.length() == 16) {
this->msg = msg;
}
}
void Sound::showErrorMessage() { //Output an error message (time or date were set incorrectly)
cur->cursorStopBlink();
cur->setLCDCursor(0, 1);
disp->setDisplay(this->msg);
cur->setLCDCursor(cur->getCursorPos(), 0);
cur->cursorStartBlink();
}
void Sound::playErrorSound() { //Make an error sound if the clock input data were incorrect
if (disp->checkDisplayData() == false) {
buzzer.beep(100);
this->setErrorMessage("Incorrect format");
this->showErrorMessage();
} else {
this->setErrorMessage(" ");
this->showErrorMessage();
}
}
Sound* snd = new Sound();
//Program loop
void loop() {
cur->setCursorMaxBlinking();
//Output time that was set with RTC
if (disp->checkDisplayData() == true) { //If clock data is correct
if (cur->getIsSetModeValue() == 0) { //If clock is not in edit mode
if (disp->checkAlarmValidity() == false && disp->getIsSetAlarm() == 1) {
//Uncomment for IDE
//buzzer.loop();
//Uncomment for IDE
disp->showAlarmIcon(melody_icon);
disp->setStopAlarm(0);
//Uncomment for IDE
/*
if (buzzer.getState() == BUZZER_IDLE) {
int length = sizeof(noteDurations) / sizeof(int);
buzzer.playMelody(melody, noteDurations, length);
}
*/
//Uncomment for IDE
Serial.println("RINGING...");
} else if (disp->checkAlarmValidity() == false && disp->getIsSetAlarm() == 0) {
disp->setAdjustedClockTime();
} else if (disp->checkAlarmValidity() == true && disp->getIsSetAlarm() == 0) {
disp->setAdjustedClockTime();
} else if (disp->checkAlarmValidity() == true && disp->getIsSetAlarm() == 1) {
disp->setAdjustedClockTime();
}
} else if (disp->getIsSetAlarm() == 0) {
//...
}
}
//Output time that was set with RTC
if (IrReceiver.decode()) {
unsigned long a = IrReceiver.decodedIRData.decodedRawData; //Receive a value from remote control
IrReceiver.resume();
//Serial.println(a);
//delay(200000);
//btn->setRemoteControlButton(a); //Get button name by its code (remote control)
//btn->setDisplayBrightness(); //Display brightness control
disp->setClockTimeMode(a); //Set a clock time and date
cur->switchEditTimeMode(a); //Switch between edit mode and running time (cursor)
cur->switchEditAlarmMode(a); //Set alarm time and date
if (a == 1336999680) { //EDIT ON > Set edit mode on
//Set the current time for the blinking cursor
cur->setCursorTiming(millis());
//Set the current time for the blinking cursor
//Exit from the mode of setting the alarm
disp->setIsAlarm(0);
disp->setStopAlarm(1);
cur->setIsSetAlarmModeValue(0);
//Exit from the mode of setting the alarm
//Turn the alarm off (uncomment for IDE)
/*
if (buzzer.getState() == BUZZER_MELODY) {
buzzer.stop();
cur->setIsSetModeValue(0);
disp->setIsAlarm(0);
disp->setStopAlarm(1);
cur->setIsSetAlarmModeValue(0);
disp->clearDisplay();
}
*/
//Turn the alarm off (uncomment for IDE)
}
if (a == 1470693120) { //EDIT OFF > Set new RTC values if some new time settings' values were confirmed (a user entered new time and date)
disp->clearDisplay();
rtc.adjust((DateTime(disp->getYear(), disp->getMonth(), disp->getDay(), disp->getHour(), disp->getMinute(), 0)));
}
if (a == 1738080000) { //EDIT_ALARM_ON > Copy clock values to alarm
if (cur->getIsSetModeValue() == 1) {
disp->copyClockValuesToAlarm(a);
cur->setIsSetAlarmModeValue(1);
}
}
if (a == 4244832000) { //EDIT_ALARM_OFF > Set alarm RTC values
if ((cur->getIsSetModeValue() == 1) && (cur->getIsSetAlarmModeValue() == 1)) {
if (disp->checkAlarmValidity() == true) {
disp->setIsAlarm(1);
} else {
disp->showAlarmMessage(" ");
disp->showAlarmMessage("Alarm error");
}
}
}
if (a == 1570963200) { //Power LCD on/off
disp->switchDisplayOnOff(a);
}
if (a == 2540240640 || //0 Emit a sound if some incorrect time settings were applied (wrong time or date formats)
a == 3476094720 || //1
a == 3877175040 || //2
a == 2239430400 || //3
a == 4010868480 || //4
a == 3342401280 || //5
a == 2774204160 || //6
a == 3175284480 || //7
a == 3041591040 || //8
a == 2907897600) { //9
if (cur->getIsSetModeValue() == 1) {
snd->playErrorSound();
}
if (cur->getIsSetAlarmModeValue() == 1) {
cur->showAlarmMessage(" ");
cur->showAlarmMessage("Alarm mode on");
}
}
}
}
//Program loop