/// DISPLAY 4x7-segmento 5461AS-1 (45) VERIFICAR SE COMMON ANODE ou CATHODE
/// ON@ -> Cathode = HIGH; Anode = LOW (SINK com resistor ao PCF)
/// READ ME:
/// Pressiona MENU para definir um horario para o ALARME
/// Ao inserir digito válido, pressiona PLAY para avançar ao próximo campo
/// Concluido os 4 digitos, pressiona PLAY p/ salvar HORA DO ALARME
/// Pressiona POWER p/ Liga/desliga alarme.
/// RTC DS1302, LCD 16x2, Adaptador LCD I2C PCF8574, IR Receptor 1838, Buzzer
#include <IRremote.hpp> // Do not change header order.
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#define IR_PIN 8
#define BUZZER_PIN 13
RTC_DS1307 rtc; // &I2C =? 0x68 /// No slide diz 1302/1307. Se 1302 precisa mudar Lib
LiquidCrystal_I2C lcd(0x27,20,4);
bool blink = true, alarmArmed = false;
int irCode = 0;
int timeNow[5];
int alarmSettings[4];
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
if (!rtc.begin()) {
Serial.println("Nao foi possivel conectar ao RTC DS1307");
while (1);
}
lcd.init();
lcd.backlight();
IrReceiver.begin(IR_PIN);
EEPROM.get(0, alarmSettings);
}
void loop() {
printTime();
if (alarmArmed) checkAlarm();
irCode = irReceive();
if (irCode == 0xE2) setAlarmTime();
if (irCode == 0xA2) {
alarmArmed = !alarmArmed;
lcd.clear();
}
}
void getTime() {
DateTime n = rtc.now();
timeNow[0] = n.hour() / 10;
timeNow[1] = n.hour() % 10;
timeNow[2] = n.minute() / 10;
timeNow[3] = n.minute() % 10;
timeNow[4] = n.second();
}
void printTime() {
getTime();
lcd.setCursor(4, 0);
for (int i = 0; i < 4; i++) {
lcd.print(timeNow[i]);
if (i == 1 || i == 3) lcd.print(":");
}
if (timeNow[4] < 10) lcd.print("0");
lcd.print(timeNow[4]);
if (alarmArmed) {
lcd.setCursor(14, 0);
lcd.print("ON");
}
delay(200);
}
int irReceive() {
int received = 0;
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.protocol == NEC) {
received = IrReceiver.decodedIRData.command;
}
IrReceiver.resume();
}
return received;
}
int getButtonFromHex(int hex) {
int hexCode[10] = {0x68, 0x30, 0x18, 0x7A, 0x10,
0x38, 0x5A, 0x42, 0x4A, 0x52}; // 0 à 9
if (hex == 0xA2) return 10; // POWER
if (hex == 0xE2) return 11; // MENU
if (hex == 0xA8) return 12; // PLAY
for (int i = 0; i < 10; i++) {
if (hexCode[i] == hex) return i;
}
return -1;
}
void setAlarmTime() {
bool rollback = false;
int alarm[4] = {0};
for (int i = 0; i < 4; i++) alarm[i] = alarmSettings[i];
int count = 0;
while (!rollback){
printTime();
printSetAlarm(alarm, count);
if (count > 3) break;
irCode = getButtonFromHex(irReceive());
if (irCode == 11) rollback = true;
else if (irCode == 12) count++;
else if (irCode >= 0 && irCode < 10) {
if (count == 0) {
if (irCode == 0 || irCode == 1) alarm[0] = irCode;
else {
alarm[0] = 2;
alarm[1] = (alarm[1] < 4) ? alarm[1] : 3;
}
} else if (count == 1) {
if (alarm[0] < 2) alarm[1] = irCode;
else alarm[1] = (irCode < 4) ? irCode : 3;
} else if (count == 2) alarm[2] = (irCode < 6) ? irCode : 5;
else alarm[3] = irCode;
}
else continue;
}
if (!rollback) {
for (int i = 0; i < 4; i++) {
alarmSettings[i] = alarm[i];
}
EEPROM.put(0, alarmSettings);
}
lcd.clear();
}
void printSetAlarm(int *a, int digit) {
blink = !blink;
lcd.setCursor(2, 1);
lcd.print("ALARME ");
for (int i = 0; i < 4; i++) {
if (i == 2) lcd.print(":");
if (digit == i && blink) lcd.print(" ");
else lcd.print(a[i]);
}
}
void checkAlarm() {
bool bip = true;
for (int i = 0; i < 4; i++) {
bip = (alarmSettings[i] != timeNow[i]) ? false : bip;
}
while (bip) {
digitalWrite(BUZZER_PIN, !blink);
blink = !blink;
printTime();
lcd.setCursor(5, 1);
lcd.print((blink) ? " " : "BIP!!!");
if (irReceive() == 0xA2) {
alarmArmed = false;
bip = false;
lcd.clear();
}
}
digitalWrite(BUZZER_PIN, LOW);
}