#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
/*
Buttons:
Red - Plus (minuty,hodiny...)
Blue - Minus
Yellow - hodiny / minuty option
Gray - Mode: 1 - aktualny cas / 2 - zmenit cas / 3 - alarm
*/
#define plus 2 // red
#define minus 3 // blue
bool plusPressed = false;
bool minusPressed = false;
#define settings 4 // yellow
#define HaM 5 // gray
#define BUZZER_PIN 6
bool buzzerActivated = false;
DateTime dateTime;
int minuta;
int hodina;
int sekunda;
int menu = 0;
int jednotka = 0;
unsigned long lastButtonTime = 0;
const unsigned long debounceDelay = 200;
// Alarm
int AlarmMinuta;
int AlarmHodina;
int AlarmSekunda;
int stlacenie = 0;
int buttonState;
int lastDebounceTime4 = 0;
int reading4;
int tlacidlo = 0;
int buttonState2;
int lastDebounceTime5 = 0;
int reading5;
void setup() {
Serial.begin(115200); //serial
lcd.init();
lcd.backlight(); // podsvietenie
// settings pinov
pinMode(settings, INPUT_PULLUP);
pinMode(plus, INPUT_PULLUP);
pinMode(minus, INPUT_PULLUP);
pinMode(HaM, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
if (!rtc.begin()) { // Ak sa nepodarí inicializovať RTC modul
lcd.print("Hodiny nie su pripojene!"); // Zobrazenie chybovej správy
while (1);
}
if (!rtc.isrunning()) { // Ak RTC modul nie je spustený
Serial.println("Hodiny nie su zapnute!"); // Výpis chybovej správy
lcd.print("Nastavte cas:");
while (true) {
lcd.clear();
lcd.print("HH:MM");
lcd.setCursor(0, 1);
lcd.print(">");
int hodiny = 0;
int minuty = 0;
bool potvrdenie = false;
while (!potvrdenie) {
if (!digitalRead(plus)) { // Ak je stlačené tlačidlo "plus"
hodiny = (hodiny + 1) % 24;
delay(250); // debounce
}
if (!digitalRead(minus)) { // Ak je stlačené tlačidlo "minus"
hodiny = (hodiny + 23) % 24;
delay(250); // debounce
}
lcd.setCursor(0, 1);
lcd.print(hodiny < 10 ? "0" : ""); // Formátovanie zobrazenia hodín s dodatočnou 0 pre jednociferné hodiny
lcd.print(hodiny);
lcd.print(":");
lcd.print(minuty < 10 ? "0" : ""); // Formátovanie zobrazenia minút s dodatočnou 0 pre jednociferné minúty
lcd.print(minuty);
if (!digitalRead(settings)) { // Ak je stlačené tlačidlo "settings"
potvrdenie = true;
delay(250); // debounce
}
}
potvrdenie = false;
lcd.clear();
lcd.print("HH:MM");
lcd.setCursor(3, 1);
lcd.print(">");
while (!potvrdenie) {
if (!digitalRead(plus)) { // Ak je stlačené tlačidlo "plus"
minuty = (minuty + 1) % 60;
delay(250); // debounce
}
if (!digitalRead(minus)) { // Ak je stlačené tlačidlo "minus"
minuty = (minuty + 59) % 60;
delay(250); // debounce
}
lcd.setCursor(0, 1); // druhý riadok
lcd.print(hodiny < 10 ? "0" : ""); // Formátovanie zobrazenia hodín s dodatočnou 0 pre jednociferné hodiny
lcd.print(hodiny);
lcd.print(":");
lcd.print(minuty < 10 ? "0" : ""); // Formátovanie zobrazenia minút s dodatočnou 0 pre jednociferné minúty
lcd.print(minuty);
if (!digitalRead(settings)) { // Ak je stlačené tlačidlo "settings"
potvrdenie = true;
delay(250); // debounce
}
}
lcd.clear();
lcd.print("Cas nastaven");
rtc.adjust(DateTime(2024, 4, 27, hodiny, minuty, 0));
delay(2000);
break; // Ukocnenie nastavovania casu
}
lcd.clear();
}
}
void loop() {
/*//Debug
Serial.print("AlarmHodina: ");
Serial.print(AlarmHodina);
Serial.print(" - AlarmMinuta: ");
Serial.print(AlarmMinuta);
Serial.print(" | Hodina: ");
Serial.print(hodina);
Serial.print(" - Minuta: ");
Serial.print(minuta);
Serial.print(" - Sekunda: ");
Serial.println(sekunda);
*/
if ((millis() - lastDebounceTime4) > debounceDelay) {
reading4 = digitalRead(settings);
if (reading4 != buttonState) {
buttonState = reading4;
if (buttonState == LOW) {
stlacenie++;
if(stlacenie > 3) {
stlacenie = 1;
}
}
}
}
if ((millis() - lastDebounceTime5) > debounceDelay) {
reading5 = digitalRead(HaM);
if (reading5 != buttonState2) {
buttonState2 = reading5;
if (buttonState2 == LOW) {
tlacidlo++;
if(tlacidlo > 2) {
tlacidlo = 1;
}
}
}
}
dateTime = rtc.now();
if (!digitalRead(settings)) {
menu++;
jednotka++;
delay(250);
while (!digitalRead(settings));
}
// zobrazuje aktualny cas / kontroluje alarm
if (menu == 0) {
CurrentTime();
AlarmKontrola();
}
// zmena aktualneho casu
if (menu == 1) {
if (jednotka == 1) {
lcd.clear();
jednotka = 0;
tlacidlo = 0;
}
ZmenaHodin();
}
// nastavenie alarmu
if (menu == 2) {
if (jednotka == 1) {
lcd.clear();
jednotka = 0;
minuta = 0;
hodina = 0;
sekunda = 0;
}
ZmenaAlarmu();
}
// spat na default mode
if (menu == 3) {
lcd.clear();
menu = 0;
jednotka = 0;
}
delay(250);
}
void CurrentTime() {
dateTime = rtc.now();
// berie cas z rtc a priradi ku premenam
hodina = dateTime.hour();
minuta = dateTime.minute();
sekunda = dateTime.second();
//displej vypis
lcd.setCursor(0,0);
lcd.print("Cas: ");
lcd.setCursor(5,0);
lcd.print(hodina);
lcd.setCursor(7,0);
lcd.print(':');
lcd.setCursor(8,0);
lcd.print(minuta);
lcd.setCursor(10,0);
lcd.print(':');
lcd.setCursor(11,0);
lcd.print(sekunda);
}
void ZmenaHodin() {
unsigned long currentMillis = millis();
if (stlacenie == 1) {
if (!digitalRead(plus) && !plusPressed && (currentMillis - lastButtonTime >= debounceDelay)) {
plusPressed = true;
lastButtonTime = currentMillis;
if (tlacidlo == 1) { // Ak režim na minúty
minuta++;
if (minuta > 59) {
minuta = 0;
}
} else { // Ak režim na hodiny
hodina++;
if (hodina > 23) {
hodina = 0;
}
}
}
if (digitalRead(plus)) {
plusPressed = false;
}
if (!digitalRead(minus) && !minusPressed && (currentMillis - lastButtonTime >= debounceDelay)) {
minusPressed = true;
lastButtonTime = currentMillis;
if (tlacidlo == 1) { // Ak režim na minuty
minuta--;
if (minuta < 0) {
minuta = 59;
}
} else { // Ak režim na H hodiny
hodina--;
if (hodina < 0) {
hodina = 23;
}
}
}
if (digitalRead(minus)) {
minusPressed = false;
}
// formatovanie na 2 cislice
char formattedHour[3];
sprintf(formattedHour, "%02d", hodina);
char formattedMinute[3];
sprintf(formattedMinute, "%02d", minuta);
lcd.setCursor(0,0);
lcd.print("Zmena casu");
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(formattedHour);
lcd.setCursor(2,1);
lcd.print(':');
lcd.setCursor(3,1);
lcd.print(formattedMinute);
lcd.setCursor(5,1);
lcd.print(':');
lcd.setCursor(6,1);
lcd.print(sekunda);
// Zobrazenie režimu H alebo M na základe stlačenia tlačidla HaM
lcd.setCursor(15,1);
if (tlacidlo == 1) {
lcd.print("M");
} else{
lcd.print("H");
}
}
else if (stlacenie == 2) {
lcd.setCursor(0, 0);
lcd.print("Zmena alarmu");
}
}
void ZmenaAlarmu() {
unsigned long currentMillis = millis();
AlarmMinuta = minuta;
AlarmHodina = hodina;
// Zmena hodnoty hodin alarmu
if (!digitalRead(plus) && !plusPressed && (currentMillis - lastButtonTime >= debounceDelay)) {
plusPressed = true;
lastButtonTime = currentMillis;
if (tlacidlo == 1) { // Ak je režim nastavený na M (minúty)
minuta++;
AlarmMinuta = minuta; // Zvýšiť hodnotu minút
if (minuta > 59) {
minuta = 0;
}
buzzerActivated = false; // Nastavíme príznak na false, pretože sme zmenili čas
} else { // Ak je režim nastavený na H (hodiny)
hodina++;
AlarmHodina = hodina; // Zvýšiť hodnotu hodín
if (hodina > 23) {
hodina = 0;
}
buzzerActivated = false; // Nastavíme príznak na false, pretože sme zmenili čas
}
}
if (digitalRead(plus)) {
plusPressed = false;
}
if (!digitalRead(minus) && !minusPressed && (currentMillis - lastButtonTime >= debounceDelay)) {
minusPressed = true;
lastButtonTime = currentMillis;
if (tlacidlo == 1) { // Ak je režim na minúty
minuta--;
AlarmMinuta = minuta;
if (minuta < 0) {
minuta = 59;
}
buzzerActivated = false;
} else { // Ak je režim na hodiny
hodina--;
AlarmHodina = hodina;
if (hodina < 0) {
hodina = 23;
}
buzzerActivated = false;
}
}
if (digitalRead(minus)) {
minusPressed = false;
}
// Formátovanie hodín na dve číslice
char formattedHour[3];
sprintf(formattedHour, "%02d", hodina);
char formattedMinute[3];
sprintf(formattedMinute, "%02d", minuta);
lcd.setCursor(0, 0);
lcd.print("Zmena alarmu");
lcd.setCursor(1, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(formattedHour);
lcd.setCursor(2, 1);
lcd.print(':');
lcd.setCursor(3, 1);
lcd.print(formattedMinute);
lcd.setCursor(5, 1);
lcd.print(':');
lcd.setCursor(6, 1);
lcd.print(sekunda);
lcd.setCursor(15, 1);
if (tlacidlo == 1) {
lcd.print("M");
} else{
lcd.print("H");
}
}
void AlarmKontrola() {
// Získanie aktuálneho času z RTC
DateTime now = rtc.now();
// porovnanie casu s aktualnym
if (now.hour() == AlarmHodina && now.minute() == AlarmMinuta && !buzzerActivated) {
tone(BUZZER_PIN, 1000, 2000);
// Reset alarmu
AlarmHodina = 0;
AlarmMinuta = 0;
buzzerActivated = true;
//debug
//Serial.println("Buzzer: " + buzzerActivated);
}
}