Hallo Community,
bin mal wieder auf ein Problem gestoßen und komme momentan nicht zu einer einigermaßen sauberen Lösung.
Grundlegend soll die Routine ein Relay im Controllino schalten. Das Relay soll nach einer festgelegten Startzeit für eine bestimmte Zeit schalten. Drei unterschiedliche Zeiten werden über einen Drehschalter mit 3 Stellungen bzw. 2 Schließern bestimmt.
Ich habe mir gedacht, nicht über millis() zu gehen, um das Relay auch nach Stromausfall wieder weiterlaufen zu lassen.
Ist:
//Button Logic
-->Schalter auslesen und aktuell eingestellte Zeitmodi erfassen.
//RTC
-->RTC auslesen und Tageszeit in Millis seit 0 Uhr umrechnen.
//Relay
-->Startzeitunkt nach geg. Variable in Millisekunden festlegen.
-->Endzeitpunkt in Millisekunden berechnen. (Hier überlauf über 0 Uhr teilweise je nachdem)
-->Relay Schalten
Problem:
-->Wenn die Ausschaltzeit später als 0 Uhr ist wird es Brecherisch.
-->Relay soll natürlich nicht um 0 Uhr kurz ausgehen, sondern konstant durchlaufen
-->Relay triggert beim Hochladen des Codes am Anfang einmal trotz gesetztem digitalWrite LOW im Setup.
Habt ihr Lösungen auf Lager, wie man den Code verbessern kann bzw. gangbar macht?
#include <SPI.h>
#include <Controllino.h>
//BUTTON LOGIC
//switches
const int switchPinPHASE1 = A1;
const int switchPinPHASE2 = A2;
int switchStatePHASE1 = 0;
int switchStatePHASE2 = 0;
bool Mode1;
bool Mode2;
bool Mode3;
//RTC
int h;
int m;
int s;
//Relay
int startTimeHourRelay = 13;//Startstunde
int startTimeMinRelay = 0;//Startminute
int relayPin = 30;
void setup() {
Serial.begin(9600);
//BUTTON LOGIC
//Switches
pinMode(switchPinPHASE1, INPUT);
pinMode(switchPinPHASE2, INPUT);
//RTC
Controllino_RTC_init();
/* set time and date by separate values values to the RTC chip */
/* Day, WeekDay, Month, Year, Hour, Minute, Second); */
//Controllino_SetTimeDate(12, 4, 1, 17, 15, 41, 23);
/* or use another possibility and define the time and date by strings, e.g. "Nov 15 2018", "11:41:02" */
/* following example uses predefined C macros __DATE__ and __TIME__ which represent compilation time */
Controllino_SetTimeDateStrings(__DATE__, __TIME__); /* set compilation time to the RTC chip */
//Relay
digitalWrite(relayPin, LOW);
pinMode(relayPin, OUTPUT);
}
void loop() {
//BUTTON LOGIC
switchStatePHASE1 = digitalRead(switchPinPHASE1);
switchStatePHASE2 = digitalRead(switchPinPHASE2);
//3 unterschiedliche Modi aus Drehschalterstellung festlegen
if (switchStatePHASE1 == HIGH && switchStatePHASE2 == LOW) {
Mode1 = true;
} else {
Mode1 = false;
}
if (switchStatePHASE1 == LOW && switchStatePHASE2 == LOW) {
Mode2 = true;
} else {
Mode2 = false;
}
if (switchStatePHASE1 == LOW && switchStatePHASE2 == HIGH) {
Mode3 = true;
} else {
Mode3 = false;
}
//RTC
unsigned long timeMillis;
//Schreibe Zeitvariablen
h = Controllino_GetHour();
m = Controllino_GetMinute();
s = Controllino_GetSecond();
Serial.print(" t: ");
Serial.print(h);
Serial.print(":");
Serial.print(m);
Serial.print(":");
Serial.print(s);
//Tageszeit in Millisekunden umrechnen
timeMillis = ( h * 3600000UL + m * 60000UL + s * 1000UL);
//Relay
//Startzeit in Millis berechnen
unsigned long relayStartMillis = startTimeHourRelay * 3600000UL + startTimeMinRelay * 60000UL;
//Laufzeit je nach Schalterstellung berechnen (20h, 10h, 5h)
unsigned long relayPhaseTime;
if (Mode1 == true) {
relayPhaseTime = 20 * 3600000UL;
}
else if (Mode2 == true) {
relayPhaseTime = 10 * 3600000UL;
}
else if (Mode3 == true) {
relayPhaseTime = 5 * 3600000UL;
}
//Ausschaltzeitpunkt festlegen
unsigned long relayEndMillis = relayStartMillis + relayPhaseTime ;
Serial.print(" relayStartMillis: ");
Serial.print(relayStartMillis);
Serial.print(" relayEndMillis: ");
Serial.print(relayEndMillis);
//Wenn die Endzeit über 24 spät ist...
unsigned long dayOver;
if (relayEndMillis >= 86399000) {
dayOver = relayEndMillis - 86399000;
}
Serial.print(" dayOver: ");
Serial.print(dayOver);
//Schaltlogic bestimmen
if (86399000 >= timeMillis >= relayStartMillis || 0 <= timeMillis <= dayOver ) {
digitalWrite(relayPin, HIGH);
} else {
digitalWrite(relayPin, LOW);
}
Serial.println();
}