/// 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.
#include <IRremote.hpp>
#include <RTClib.h>
#include <Adafruit_PCF8574.h>
#define IR_PIN 8
#define BUZZER_PIN 13
DS1302 rtc(10, SCL, SDA); // &I2C =? 0x68 /// No slide diz 1302/1307. Se 1302 precisa mudar Lib
Adafruit_PCF8574 pcf; // &I2C =? 0x20 // 8574 -> 8 I/O; 8575 -> 16 I/O
int display[4] = {4, 5, 6, 7};
byte binary[10] = {0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110,
0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
int prevSec = 0, irCode = 0;;
int timeNow[5];
int alarmSettings[4];
bool blink = true, alarmArmed = false, alarmBeeping = false, timeSet = false;
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
if (!rtc.begin()) {
Serial.println("Nao foi possivel conectar ao RTC DS1307");
while (1);
}
if (!pcf.begin(0x27, &Wire)) {
Serial.println("Nao foi possivel conectar ao PCF8574");
while (1);
}
for (int i = 0; i < 8; i++) {
pcf.pinMode(i, OUTPUT);
pcf.digitalWrite(i, LOW);
}
for (int i = 0; i < 4; i++) {
pinMode(display[i], OUTPUT);
digitalWrite(display[i], HIGH);
}
IrReceiver.begin(IR_PIN);
}
void loop() {
getTime();
printTime();
if (alarmArmed) checkAlarm();
irCode = irReceive();
if (irCode == 0xE2) setAlarmTime();
if (irCode == 0xA2) alarmArmed = !alarmArmed;
}
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() {
if (timeNow[4] != prevSec) {
prevSec = timeNow[4];
blink = !blink;
}
printDigit(timeNow[0], 7, false);
printDigit(timeNow[1], 6, blink);
printDigit(timeNow[2], 5, false);
printDigit(timeNow[3], 4, alarmArmed);
}
void printDigit(int val, int disp, bool dot) {
digitalWrite(disp, HIGH);
for (int i = 0; i < 7; i++) pcf.digitalWrite(i, (binary[val] & (1 << i)) ? HIGH : LOW);
pcf.digitalWrite(7, dot ? HIGH : LOW);
digitalWrite(disp, LOW);
delay(5); // Para efeito Persistência de Visão (POV)
digitalWrite(disp, HIGH);
}
int irReceive() {
int received = 0;
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.protocol == NEC) {
received = IrReceiver.decodedIRData.command;
// Serial.print("Command: 0x");
// Serial.println(received, HEX);
}
IrReceiver.resume();
}
return received;
}
int getButtonFromHex(int hex) {
int hexCode[10] = {0x16, 0xC, 0x18, 0x5E, 0x8,
0x1C, 0x5A, 0x42, 0x52, 0x4A}; // 0 à 9
if (hex == 0x47) return 10; // CH+ // liga/desliga
if (hex == 0x9) return 11; // EQ
if (hex == 0x43) 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};
if (timeSet) for (int i = 0; i < 4; i++) alarm[i] = alarmSettings[i];
int code = 0;
int count = 0;
while (!rollback){
for (int i = 0; i < 4; i++) timeNow[i] = alarm[i];
printTime();
if (count > 3) break;
code = getButtonFromHex(irReceive());
if (code == 11) rollback = true;
else if (code == 12) count++;
else if (code >= 0 && code < 10) {
if (count == 0) {
if (code == 0 || code == 1) alarm[0] = code;
else if (code == 2) {
alarm[0] = 2;
alarm[1] = (alarm[1] < 4) ? alarm[1] : 3;
} else continue;
} else if (count == 1) {
if (alarm[0] < 2) alarm[1] = code;
else alarm[1] = (code < 4) ? code : 3;
} else if (count == 2) alarm[2] = (code < 6) ? code : 5;
else alarm[3] = code;
}
else continue;
}
if (!rollback) {
for (int i = 0; i < 4; i++) alarmSettings[i] = alarm[i];
timeSet = true;
}
}
void checkAlarm() {
bool bip = true;
for (int i = 0; i < 4; i++) {
bip = (alarmSettings[i] != timeNow[i]) ? false : bip;
}
while (bip) {
getTime();
printTime();
if (irReceive() == 0xA2) {
alarmArmed = false;
bip = false;
}
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
}