#include <Wire.h>
#include <RTClib.h>
#include <MemoryFree.h>
#include <WString.h>
#define LIGHT_CHANEL 6
#define LIGHT_VALUES 8
RTC_DS1307 rtc;
byte ledPin[]={3, 5, 6, 9, 10, 11};
unsigned long last_print = 0;
String inputString = "";
boolean stringComplete = false;
boolean manualLight=false;
long get_ts(uint8_t h, uint8_t m, uint8_t s){
uint32_t t;
t = h;
t *= 60;
t += m;
t *= 60;
t += s;
return t;
}
typedef struct {
uint32_t time;
byte level;
}LIGHT;
// Licht Einstellungen immer paar aus Uhrzeit und % angabe. Je reihe Zahl von LIGHT_VALUES, so viele Reihen wie in LIGHT_CHANEL
LIGHT light_channels[LIGHT_CHANEL][LIGHT_VALUES] ={
{{get_ts(0,1,0),0},{get_ts(10,0,0),0},{get_ts(11,30,0),100},{get_ts(19,0,0),100},{get_ts(20,0,0),0},{get_ts(21,30,0),0},{get_ts(23,30,0),0},{get_ts(23,32,0),0}},
{{get_ts(0,1,0),0},{get_ts(9,0,0),0},{get_ts(11,0,0),100},{get_ts(19,0,0),100},{get_ts(21,0,0),0},{get_ts(21,30,0),0},{get_ts(23,30,0),0},{get_ts(23,32,0),0}},
{{get_ts(0,1,0),0},{get_ts(10,0,0),0},{get_ts(11,30,0),100},{get_ts(19,0,0),100},{get_ts(20,0,0),0},{get_ts(21,30,0),0},{get_ts(23,30,0),0},{get_ts(23,32,0),0}},
{{get_ts(0,1,0),0},{get_ts(9,0,0),0},{get_ts(11,0,0),100},{get_ts(19,0,0),100},{get_ts(21,0,0),0},{get_ts(21,30,0),0},{get_ts(23,30,0),0},{get_ts(23,32,0),0}},
{{get_ts(0,1,0),0},{get_ts(9,0,0),0},{get_ts(11,0,0),100},{get_ts(19,0,0),100},{get_ts(21,0,0),0},{get_ts(21,30,0),0},{get_ts(23,30,0),0},{get_ts(23,32,0),0}},
{{get_ts(10,30,0),0},{get_ts(11,30,0),0},{get_ts(12,30,0),0},{get_ts(13,30,0),0},{get_ts(14,30,0),0},{get_ts(15,30,0),0},{get_ts(16,30,0),0},{get_ts(17,30,0),0}}
};
void setLight(){
for( byte i=0;i < LIGHT_CHANEL; i++){
byte c_PWM = PWM_Licht(i);
analogWrite(ledPin[i],c_PWM);
}
}
int PWM_Licht(int lightIndex){
int curIndex=0;
for(byte n=0;n<LIGHT_VALUES;n++){
if(light_channels[lightIndex][n].time < rtc.daystamp){
curIndex=n;
}
}
int Max,Min,pwm=255;
float dimTime,f,p;
float pastSeconds;
uint32_t Start,Ende;
int oMin,oMax;
if(curIndex ==(LIGHT_VALUES-1) ){
Start = light_channels[lightIndex][7].time;
Ende = light_channels[lightIndex][0].time;
oMin = light_channels[lightIndex][7].level;
oMax = light_channels[lightIndex][0].level;
pastSeconds = rtc.daystamp-Start+0.5; // vergangene Sekunden ~1616Sek ~ 27min
dimTime= get_ts(24,0,0) - Start + Ende;
}else if(curIndex>=1 || light_channels[lightIndex][0].time < rtc.daystamp){
Start = light_channels[lightIndex][curIndex].time;
Ende = light_channels[lightIndex][curIndex+1].time;
oMin = light_channels[lightIndex][curIndex].level;
oMax = light_channels[lightIndex][curIndex+1].level;
pastSeconds = rtc.daystamp-Start+0.5; // vergangene Sekunden ~1616Sek ~ 27min
dimTime=Ende - Start;
}else{
Start = light_channels[lightIndex][7].time;
Ende = light_channels[lightIndex][0].time;
oMin = light_channels[lightIndex][7].level;
oMax = light_channels[lightIndex][0].level;
pastSeconds = get_ts(24,0,0)-Start + rtc.daystamp+0.5;
dimTime= get_ts(24,0,0)-Start + Ende;
}
Min=uint16_t(pwm-(pwm/100*oMin)); // 0%=4095-(4095/100*0) =
Max=uint16_t(pwm-(pwm/100*oMax)); // 80% von 4095-(4095/100*80) sind 819
if(Min==Max){
return Min;
}
f= dimTime/(Max-Min); // 1800/2800=0,64
p = pastSeconds/f; // 1616 / 0,64=2525
pwm=Min+p;
return pwm; // Im Nofall ausschalten...
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
void serialHandler(String input){
int year;
uint8_t month,day,hour,minute;
int val,pin;
switch (input.substring(0,1).toInt()){
//1=2014/03/05/18:28
case 1:
year=input.substring(2,6).toInt();
month=input.substring(7,9).toInt();
day=input.substring(10,12).toInt();
hour=input.substring(13,15).toInt();
minute=input.substring(16,18).toInt();
rtc.adjust(year,month,day,hour,minute,0);
break;
//2=2:90
case 2:
pin= input.substring(2,3).toInt();
val= input.substring(4,7).toInt();
analogWrite(ledPin[pin],255-int(val*2.55));
manualLight=true;
Serial.print(pin);
Serial.print(F(" -> "));
Serial.println(255-int(val*2.55));
break;
case 3:
manualLight=false;
break;
}
}
void setup() {
Wire.begin();
rtc.begin();
Serial.begin(9600);
inputString.reserve(20);
}
void loop() {
rtc.now();
// print the string when a newline arrives:
if (stringComplete) {
serialHandler(inputString);
inputString = "";
stringComplete = false;
}
// Licht Dimmen
if(!manualLight){
setLight();
}
if (millis() - last_print > 1000) {
last_print = millis();
}
}