// Librería para la comunicación I2C y la RTClib
#include <Wire.h>
#include "RTClib.h"
#include "TM1637Display.h"
#include "Button.h"
//Pines PWM para leds
#define PIN_PWM_AZUL 6
#define PIN_PWM_BLANCO 5
//para contar 1s o 2s desbordes de TMR2
#define TMR2_2S 63 //16ms*125 = 1s
//botones
#define HOUR_BTN A0
#define MINUTE_BTN A1
Button hourButton(HOUR_BTN);
Button minuteButton(MINUTE_BTN);
// Display tm1637
#define DISP_CLK A3
#define DISP_DIO A2
TM1637Display display(DISP_CLK, DISP_DIO);
int hour_actual;
int hour_before;
byte tmr2s_count= 0;
byte duty_azul = 0;
byte duty_blanco= 0;
byte duty_rampa = 0;
// Declaramos un RTC DS3231
RTC_DS1307 rtc;
byte rampa_duty(int hora_inicio, int hora_fin, int hora, boolean sentido, byte duty_inicial){
byte duty= duty_inicial;
for(int i=hora_inicio;i<=hora_fin;i++){
if(sentido){
duty++;
}else{
duty--;
}
if(i == hora) break;
}
return duty;
}
byte calcular_duty(byte duty){
return (duty*255)/100;
}
void write_pwm(byte duty_a, byte duty_b){
analogWrite(PIN_PWM_AZUL,calcular_duty(duty_a));
analogWrite(PIN_PWM_BLANCO,calcular_duty(duty_b));
}
void displayTime() {
DateTime now = rtc.now();
hour_actual = now.hour() * 100 + now.minute();
display.showHourDec(hour_actual, 56,true);
}
void incrementMinute() {
DateTime now = rtc.now();
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour(),
(now.minute() + 1) % 60);
rtc.adjust(newTime);
}
void incrementHour() {
DateTime now = rtc.now();
DateTime newTime = DateTime(now.year(), now.month(), now.day(),
(now.hour() + 1) % 24, now.minute());
rtc.adjust(newTime);
}
void checkButtons(){
if (hourButton.pressed()) {
incrementHour();
}
if (minuteButton.pressed()) {
incrementMinute();
}
}
//With the settings above, this IRS will trigger each 16ms.
ISR(TIMER2_COMPB_vect){
tmr2s_count++;
if(tmr2s_count == TMR2_2S){
tmr2s_count = 0;
}
}
void setup () {
Serial.begin(9600);
delay(1000);
// Comprobamos si tenemos el RTC conectado
if (! rtc.begin()) {
Serial.println("No hay un módulo RTC");
while (1);
}
// Ponemos en hora, solo la primera vez, luego comentar y volver a cargar.
// Ponemos en hora con los valores de la fecha y la hora en que el sketch ha sido compilado.
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.begin(9600);
hourButton.begin();
hourButton.set_repeat(500, 200);
minuteButton.begin();
minuteButton.set_repeat(500, 200);
display.setBrightness(4, true);
cli(); //stop interrupts for till we make the settings
//Timer2 (interrupt each 16 ms)
// interrupt time = (1/16Mhz)*1024 * 250 = 16ms;
TCCR2A = 0; // Reset entire TCCR1A to 0
TCCR2B = 0; // Reset entire TCCR1B to 0
TCCR2B |= B00000111; //Set CS20, CS21 and CS22 to 1 so we get prescalar 1024
TIMSK2 |= B00000100; //Set OCIE1B to 1 so we enable compare match B
OCR2B = 250; //Finally we set compare register B to this value
sei(); //Enable back the interrupts
pinMode(PIN_PWM_AZUL,OUTPUT);
pinMode(PIN_PWM_BLANCO,OUTPUT);
}
void loop() {
//actualiza display c/1s
if(tmr2s_count == 0){
displayTime();
if(hour_actual != hour_before){
hour_before = hour_actual; //actualizo la hora para el proximo cambio esto es c/1min
//mantiene apagado todo si esta fuera de ciclo
if((hour_actual < 600) || (hour_actual >= 2200)){
duty_azul = 0;
duty_blanco= 0;
}
if((hour_actual >= 600) && (hour_actual <800)){
duty_azul = 10;
duty_blanco= 0;
}
if((hour_actual >= 800) && (hour_actual <815)){
duty_azul = rampa_duty(800, 815, hour_actual, true, 10);
duty_blanco= 0;
}
if((hour_actual >= 815) && (hour_actual <900)){
duty_azul = 25;
duty_blanco = 0;
}
if((hour_actual >= 900) && (hour_actual <925)){
duty_azul = rampa_duty(900, 925, hour_actual, true, 25);
duty_blanco = rampa_duty(900, 925, hour_actual, true, 0);
}
if((hour_actual >= 925) && (hour_actual <1000)){
duty_azul = 50;
duty_blanco = 25;
}
if((hour_actual >= 1000) && (hour_actual <1025)){
duty_azul = rampa_duty(1000, 1025, hour_actual, true, 50);
duty_blanco= rampa_duty(1000, 1025, hour_actual, true, 25);
}
if((hour_actual >= 1025) && (hour_actual <1100)){
duty_azul = 75;
duty_blanco = 50;
}
if((hour_actual >= 1100) && (hour_actual <1125)){
duty_azul=75;
duty_blanco = rampa_duty(1100, 1125, hour_actual, true, 50);
}
if((hour_actual >= 1125) && (hour_actual <1200)){
duty_azul = 75;
duty_blanco = 75;
}
if((hour_actual >= 1200) && (hour_actual <1215)){
duty_azul = rampa_duty(1200, 1215, hour_actual, true, 75);
duty_blanco = rampa_duty(1200, 1215, hour_actual, true, 75);
}
if((hour_actual >= 1215) && (hour_actual <1700)){
duty_azul=90;
duty_blanco=90;
}
if((hour_actual >= 1700) && (hour_actual <1715)){
duty_azul = rampa_duty(1700, 1715, hour_actual, false, 90);
duty_blanco = rampa_duty(1700, 1715, hour_actual, false, 90);
}
if((hour_actual >= 1715) && (hour_actual <1800)){
duty_azul = 75;
duty_blanco = 75;
}
if((hour_actual >= 1800) && (hour_actual <1825)){
duty_azul = rampa_duty(1800, 1825, hour_actual, false, 75);
duty_blanco = rampa_duty(1800, 1825, hour_actual, false, 75);
}
if((hour_actual >= 1825) && (hour_actual <1900)){
duty_azul = 50;
duty_blanco = 50;
}
if((hour_actual >= 1900) && (hour_actual <1925)){
duty_azul = rampa_duty(1900, 1925, hour_actual, false, 50);
duty_blanco = rampa_duty(1900, 1925, hour_actual, false, 50);
}
if((hour_actual >= 1925) && (hour_actual <2000)){
duty_azul = 25;
duty_blanco = 25;
}
if((hour_actual >= 2000) && (hour_actual <2015)){
duty_azul = rampa_duty(2000, 2015, hour_actual, false, 25);
duty_blanco = rampa_duty(2000, 2015, hour_actual, false, 25);
}
if((hour_actual >= 2015) && (hour_actual <2200)){
duty_azul = 10;
duty_blanco = 10;
}
//escribo salida PWM para leds
write_pwm(duty_azul,duty_blanco);
}
}
checkButtons();
}