/*
* Clock_LED_Button_TimeChange by beta1042
* https://www.youtube.com/watch?v=IIiMjMNGg8g&lc=UgwuhdciO80rqHdsMIx4AaABAg.A8YblHYAzL7A8eyfMKtjYQ
*/
#include <IRremote.hpp>
const int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long IR_Value = 0;
/*
9768FF00 Key 0
CF30FF00 Key 1
E718FF00 Key 2
857AFF00 Key 3
EF10FF00 Key 4
C738FF00 Key 5
A55AFF00 Key 6
BD42FF00 Key 7
B54AFF00 Key 8
AD52FF00 Key 9
without FastLED.show();
9768FF00 Key 0
9768FF00
9768FF00
with FastLED.show();
541D6170 Key 0
D1ADAC46
A85442CF
*/
#include <Wire.h>
#include <RTClib.h>
#include <FastLED.h>
#define LED_PIN 7
#define NUM_LEDS 60
#define BRIGHTNESS 32
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
// https://howtomechatronics.com/tutorials/arduino/how-to-control-ws2812b-individually-addressable-leds-using-arduino/
// https://create.arduino.cc/projecthub/antiElectron/simple-wall-clock-using-adafruit-1-4-60-ring-neopixel-8ca99c?ref=tag&ref_id=clocks&offset=81
// RTC com CR2032 - Corte a TRILHA ou Remova o DIODO!!!!!!!!
// https://www.onetransistor.eu/2019/07/zs042-ds3231-battery-charging-circuit.html
CRGB leds[NUM_LEDS];
RTC_DS3231 RTC; // Define o módulo RTC
DateTime Clock; // Mantém a hora atual do relógio
byte hourval, minuteval, secondval;
int adjusthr, adjustmin, adjustsec;
//************Botões*****************//
int P1 = 3; // Botão de Horas (D3)
int P2 = 4; // Botão de Minutos (D4)
int P3 = 5; // Botão de Segundos (D5)
// As variáveis mudarão:
int lastButtonStateP1 = LOW; // a leitura anterior do pino de entrada
int lastButtonStateP2 = LOW;
int lastButtonStateP3 = LOW;
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
irrecv.blink13(true);
Wire.begin(); // Inicia o I2C
RTC.begin(); // Inicia o RTC
pinMode(P1, INPUT_PULLUP);
pinMode(P2, INPUT_PULLUP);
pinMode(P3, INPUT_PULLUP);
if (! RTC.lostPower()) {
// Serial.println("RTC is NOT running!");
// A linha a seguir define o RTC para a data e hora em que este sketch foi compilado
// RTC.adjust(DateTime(__DATE__, __TIME__));
}
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.clear(); // limpa todos os dados de pixel
FastLED.setBrightness( BRIGHTNESS );
FastLED.show();
}
void flash2hour(int flashhr) { // 'flashhr' deve ser a posição do LED. Ex. 6 horas são 30 flashhr (ou metade dos LEDs no relógio)
int adji;
for (int i = 1; i <= flashhr; i++) {
if (i >= 30) {
adji = i - 30;
}
else {
adji = i + 30;
}
leds[adji] = CRGB(255, 0, 0); // Vermelho
FastLED.show();
leds[adji] = CRGB(0, 0, 0); // Preto (apagado)
delay(100);
}
}
void loop() {
if (IrReceiver.decode()) {
IR_Value = IrReceiver.decodedIRData.decodedRawData;
Serial.println(IR_Value, HEX);
delay(1000);
irrecv.resume();
}
Clock = RTC.now(); // obtém o tempo do RTC
secondval = Clock.second(); // obtém segundos
minuteval = Clock.minute(); // obtém minutos
hourval = Clock.hour(); // obtém horas
// Esta linha define o RTC com uma data e hora explícitas. Por exemplo, para definir...
// January 21, 2014 às 3:02am, você chamaria:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 2));
// Lê o estado do botão em uma variável local:
int readingP1 = digitalRead(P1);
int readingP2 = digitalRead(P2);
int readingP3 = digitalRead(P3);
// Verifica se você pressionou o botão
// (i.e. a entrada foi de LOW para HIGH), e você esperou tempo
// suficiente desde a última pressão para ignorar qualquer ruído.
// Verifica se você pressionou o botão de Horas, e incrementa em 1
if (readingP1 != lastButtonStateP1)
{
if (readingP1 == HIGH) {
if (hourval == 23) {
hourval = 0; // apenas 24 horas, inicia em 0, então faz reset para 0
}
else {
hourval += 1; // avança em 1
}
RTC.adjust(DateTime(Clock.year(), Clock.month(), Clock.day(), hourval, Clock.minute(), Clock.second()));
}
}
// Verifica se você pressionou o botão Minuto, e incrementa em 1
if (readingP2 != lastButtonStateP2)
{
if (readingP2 == HIGH) {
if (minuteval == 59) {
minuteval = 0;
}
else {
minuteval += 1; // avança por 1
}
RTC.adjust(DateTime(Clock.year(), Clock.month(), Clock.day(), Clock.hour(), minuteval, Clock.second()));
}
}
// Verifica se você pressionou o botão de Segundos, e faz o reset para 0
if (readingP3 != lastButtonStateP3)
{
if (readingP3 == HIGH) {
secondval = 0;
RTC.adjust(DateTime(Clock.year(), Clock.month(), Clock.day(), Clock.hour(), Clock.minute(), secondval));
}
}
if (hourval > 11) hourval -= 12; // Este relógio é de 12 horas; se for de 13-23, converta para 0-11
// hourval = (hourval*60 + minuteval) / 12;
hourval = (hourval * 60) / 12;
// Ajusta os valores, pois a tira de LED inicia na marca de 6 horas em vez de 12 (ligado próximo a 6)
if (hourval >= 30) {
adjusthr = hourval - 30;
}
else {
adjusthr = hourval + 30;
}
if (minuteval >= 30) {
adjustmin = minuteval - 30;
}
else {
adjustmin = minuteval + 30;
}
if (secondval >= 30) {
adjustsec = secondval - 30;
}
else {
adjustsec = secondval + 30;
}
if (minuteval == 0 && secondval == 0) {
flash2hour(hourval);
}
leds[adjusthr] = CRGB(255, 0, 0); // Vermelho
// leds[hourval-1] = CRGB(0, 0, 0); // Cor mais clara que o vermelho
// leds[hourval+1] = CRGB(0, 0, 0);
leds[adjustmin] = CRGB(0, 0, 255); // Azul
// strip.setPixelColor(minuteval-1, 0x200020);strip.setPixelColor(minuteval+1, 0x200020);
leds[adjustsec] = CRGB(0, 255, 0); // Verde
FastLED.show();
leds[adjusthr] = CRGB(0, 0, 0); // Preto
leds[adjustmin] = CRGB(0, 0, 0); // Preto
leds[adjustsec] = CRGB(0, 0, 0); // Preto
delay(25);
lastButtonStateP1 = readingP1;
lastButtonStateP2 = readingP2;
lastButtonStateP3 = readingP3;
/*
Serial.print(hourval, DEC);
Serial.print(':');
Serial.print(minuteval, DEC);
Serial.print(':');
Serial.println(secondval, DEC);
*/
}