// Includes
#include <Time.h>
#include <Wire.h>
//#include <LiquidCrystal.h>
#include "RTClib.h"
// Konstanten
const int DS1307_ADRESSE = 0x50; // I2C Addresse der Echtzeituhr
const int RELAY_1 = 7; // I/O-Pin Relais 1
const int RELAY_2 = 6; // I/O-Pin Relais 2
const int RELAY_3 = 5; // I/O-Pin Relais 3
const int RELAY_4 = 4; // I/O-Pin Relais 4
const int FADER_1 = 9; // PWM-Pin LED-Modul 1
const int FADER_2 = 10; // PWM-Pin LED-Modul 2
// Alle Zeiten: Sekunden nach Mitternacht (0 - 86399)
const long CO2_START = 21600; // 06:00
const long DAWN_START = 25200; // 07:00
const long SIESTA_START = 46800; // 13:00
const long SIESTA_END = 54000; // 16:00
const long CO2_STOP = 72000; // 20:00
const long DUSK_START = 79200; // 22:00
const long FADE_DUR = 3600; // 60min dimmen
const int DAY_STATE[] = { 255 , 255 }; // 100% PWM Tagmodus
const int SIESTA_STATE[] = { 63 , 63 }; // 25% PWM Mittagspause
const int NIGHT_STATE[] = { 0 , 0 }; // 0% PWM Nacht
// Variablen
long Counter;
int StateChan1, StateChan2;
//LiquidCrystal lcd(8, 11, 13, 12, 3, 2); // LCD-Pins initialiseren
RTC_DS1307 RTC; // Alias für Ehctzeituhr
void fader(long StartTime, const int StartState[], const int EndState[], int Output[2]) {
float PerSecondDelta0 = (float) (EndState[0] - StartState[0]) / FADE_DUR;
float PerSecondDelta1 = (float) (EndState[1] - StartState[1]) / FADE_DUR;
long Elapsed = Counter-StartTime;
Output[0] = StartState[0] + PerSecondDelta0 * Elapsed;
Output[1] = StartState[1] + PerSecondDelta1 * Elapsed;
}
long SecondsSinceMidnight() {
DateTime now = RTC.now();
long hr = now.hour();
long min = now.minute();
long sec = now.second();
long Total = hr * 3600 + min * 60 + sec;
return Total;
}
// PWM-Tastverhaeltnis setzen
void set_state(const int STATE[]) {
if (STATE[0] >= 0 && STATE[0] <= 255) {
analogWrite(FADER_1, STATE[0]);
StateChan1 = STATE[0]; }
if (STATE[1] >= 0 && STATE[1] <= 255) {
analogWrite(FADER_2, STATE[1]);
StateChan2 = STATE[1]; }
}
void determine_state() {
// CO2 schalten
if ( Counter >= CO2_START && Counter < CO2_STOP) {
digitalWrite(RELAY_1, HIGH);
} else {
digitalWrite(RELAY_1, LOW);
}
if ( Counter >= 0 && Counter < DAWN_START ) { // Nacht
set_state(NIGHT_STATE);
Serial.print("STATE 1\n"); //debug
} else if ( Counter >= DAWN_START && Counter < (DAWN_START+FADE_DUR) ) { // Sonnenaufgang
int State[2];
fader(DAWN_START, NIGHT_STATE, DAY_STATE, State);
set_state(State);
Serial.print("STATE 2\n"); //debug
} else if ( Counter >= (DAWN_START+FADE_DUR) && Counter < SIESTA_START ) { // vor Mittagspause
set_state(DAY_STATE);
Serial.print("STATE 3\n"); //debug
} else if ( Counter >= SIESTA_START && Counter < (SIESTA_START+FADE_DUR) ) { // Dimmen zur Mittagspause
int State[2];
fader(SIESTA_START, DAY_STATE, SIESTA_STATE, State);
set_state(State);
Serial.print("STATE 4\n"); //debug
} else if ( Counter >= SIESTA_START+FADE_DUR && Counter < (SIESTA_END) ) { // Mittagspause
set_state(SIESTA_STATE);
Serial.print("STATE 5\n"); //debug
} else if ( Counter >= SIESTA_END && Counter < (SIESTA_END+FADE_DUR) ) { // Dimmen von Mittagspause
int State[2];
fader(SIESTA_END, SIESTA_STATE, DAY_STATE, State);
set_state(State);
Serial.print("STATE 6\n"); //debug
} else if ( Counter >= (SIESTA_END+FADE_DUR) && Counter < DUSK_START ) { // nach Mittagspause
set_state(DAY_STATE);
Serial.print("STATE 7\n"); //debug
} else if ( Counter >= DUSK_START && Counter < (DUSK_START+FADE_DUR) ) { // Sonnenuntergang
int State[2];
Serial.print(State[1]);
fader(DUSK_START, DAY_STATE, NIGHT_STATE, State);
set_state(State);
Serial.print("STATE 8\n"); //debug
} else if ( Counter >= (DUSK_START+FADE_DUR) && Counter < 86400 ) { // Nacht
set_state(NIGHT_STATE);
Serial.print("STATE 9\n"); //debug
} else {
Serial.print("STATE NOT MATCHED"); //debug
}
}
void digitalClockDisplay() {
DateTime now = RTC.now();
Serial.print(now.day(), DEC);
Serial.print('.');
Serial.print(now.month(), DEC);
Serial.print('.');
Serial.print(now.year(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void setup() {
pinMode(RELAY_1, OUTPUT);
pinMode(RELAY_2, OUTPUT);
pinMode(RELAY_3, OUTPUT);
pinMode(RELAY_4, OUTPUT);
pinMode(FADER_1, OUTPUT);
pinMode(FADER_2, OUTPUT);
// Serielle Kommunikstion initialisieren
Serial.begin(9600);
// I2C initialisieren
Wire.begin();
// RTC initialisieren
RTC.begin();
// RTC auf compile time des Scetches setzen
RTC.adjust(DateTime(__DATE__, __TIME__));
}
void loop() {
Counter = SecondsSinceMidnight();
determine_state();
Serial.print("Counter: ");
Serial.print(Counter);
Serial.println();
Serial.print("Channel 1, 2: ");
Serial.print(StateChan1);
Serial.print(", ");
Serial.print(StateChan2);
Serial.println();
digitalClockDisplay();
delay(1000);
}