ich weis zwar nicht warum du ausgerechnet diese uralte lib verwendest und nicht eine aus der IDE, aber ok.
ungeprüft, da ich momentan keinen DS anschließen wollte:
/*
- Arduino hat permanent Strom (Notstromversorgung über Akku-Pack)
- RTC ermöglicht relativ genaue Uhrzeit
- Eingabe der Auslösezeit (in meinem Fall Kiste öffnen) und Dauer (z.B. 1 Stunde, dann schließen)
- max. 10 Auslösezeiten
- Auslösezeit (und bei Schließen) steuert für eine Fix definierte Zeit (ca. 40 Sekunden) ein Relais an
- externer Knopf ermöglicht Vorgang Öffnen oder Schließen zu jedem Gewünschten Zeitpunkt (Auffüllen)
http://forum.arduino.cc/index.php?topic=603373.0
by noiasca
* */
#include <Wire.h>
#include <DS3231.h> // http://www.rinkydinkelectronics.com/library.php?id=73
//Erklärung zu Relais - diese sind bei HIGH offen und bei LOW geschlossen
// Ralais Ansteuerung-Pin festlegen
const int Relay_1 = 2;
const int Relay_2 = 3;
const int Relay_3 = 4;
const int Relay_4 = 5;
// Taster Pin
const int Taster_stop = 7;
const int Taster_auf = 8;
const int Taster_zu = 9;
DS3231 rtc(SDA, SCL);
Time t;
uint32_t milliaktuell = millis(); //change:
const byte no_of_programs = 5; // wie viele Schaltprogramme sollen vorgesehen werden
struct {
byte hour;
byte min;
byte open;
} zeit[no_of_programs]; // jedes Zeitprogramm besteht aus 3 Elementen, daher ein struct, insgesamt brauchen wir dann mehrere Programme daher ein Array von diesem Struct
//Dauer Bewegung
const uint16_t bewegung = 10000; //change: hier brauchst kein signed int
uint32_t old_minute = 0 - 1; //speichert die Minute, wann die Zeitprogramme das letzte mal kontrolliert wurden
uint32_t previous_started = 0; //speichert wann die Motoren gestartet wurden
uint32_t previous_opend = 0; //speichert wann die Kiste geöffnet wurde, im Prinzip könnte man den letzten previous_started auch nehmen.
enum states {
idle, // warten auf tastendruck oder Zeitsteuerung
kiste_oeffnen,
kiste_schliessen
} state;
void schliessen()
{
digitalWrite(Relay_1, HIGH); // schalte andere Relais sicherheitshalber ab
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, LOW);
digitalWrite(Relay_4, LOW);
Serial.println(F("Kiste schliesst"));
state = kiste_schliessen;
}
void oeffnen()
{
digitalWrite(Relay_1, LOW);
digitalWrite(Relay_2, LOW);
digitalWrite(Relay_3, HIGH); // schalte andere Relais sicherheitshalber ab
digitalWrite(Relay_4, HIGH);
Serial.println(F("Kiste öffnet"));
state = kiste_oeffnen;
}
void alles_aus()
{
digitalWrite(Relay_1, HIGH);
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);
Serial.println(("Alles Aus - Vorgang beendet"));
state = idle;
}
void setup() {
Serial.begin(115200);
rtc.begin();
pinMode(Relay_1, OUTPUT);
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
pinMode(Taster_stop, INPUT_PULLUP);
pinMode(Taster_auf, INPUT_PULLUP);
pinMode(Taster_zu, INPUT_PULLUP);
digitalWrite(Relay_1, HIGH);
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);
// wahrscheinlich willst du die Zeiten aus einem EEPROM auslesen, hier mal hardcoded:
zeit[0].hour = 6; zeit[0].min = 0; zeit[0].open = 1;
zeit[1].hour = 10; zeit[1].min = 0; zeit[1].open = 1;
zeit[2].hour = 14; zeit[2].min = 0; zeit[2].open = 1;
zeit[3].hour = 18; zeit[3].min = 0; zeit[3].open = 1;
zeit[4].hour = 22; zeit[4].min = 0; zeit[4].open = 1;
Serial.println(F("Kiste Steuerung"));
state = idle;
}
void loop() {
//t = rtc.getTime(); // noiasca: hab nur ich auskommentiert weil ich diese Hardware nicht angeschlossen habe und die Lib kein failover macht
//Serial.println(t.min);
switch (state)
{
case idle:
break;
case kiste_oeffnen:
if (millis() - previous_started > bewegung)
{
alles_aus();
state = idle;
Serial.println(F("D124 öffnen beendet"));
}
break;
case kiste_schliessen:
if (millis() - previous_started > bewegung)
{
alles_aus();
state = idle;
Serial.println(F("D132 schließen beendet"));
}
break;
}
// Taster starten eine Aktion und setzen eventuell einen neuen Status
if (!digitalRead(Taster_auf)) {
oeffnen();
previous_started = millis();
state = kiste_oeffnen;
}
if (!digitalRead(Taster_zu)) {
schliessen();
previous_started = millis();
state = kiste_schliessen;
}
if (!digitalRead(Taster_stop)) {
alles_aus();
state = idle;
}
// einmal pro Minute die Schaltprogramme kontrollieren ob etwas zu tun ist
uint32_t current_minute = millis() / 60000;
if (old_minute != current_minute)
{
Serial.print(F("D164 Schaltprogramme durchgehen ")); Serial.println(t.min);
old_minute = current_minute;
for (byte i = 0; i < no_of_programs; i++)
{
if (t.hour == zeit[i].hour && t.min == zeit[i].min)
{
oeffnen();
state = kiste_oeffnen;
}
if (t.hour == zeit[i].hour + zeit[i].open && t.min == zeit[i].min)
{
schliessen();
state = kiste_schliessen;
}
}
}
}
da du nun die Öffnungsdauer in der Automatik hast, ist die State Machine langweilig. Ich habe es aber dennoch mal so gelassen.
ob du die States in den Aktionen oder in den Auslösern änderst, ist aktuell redundant. Nicht schön. Konnte mich aber nicht festlegen wo ich es hingeben soll. Tendenziell würde ich es eher zu den Tastern/den Auslösern geben und aus den funktionen eher wegnehmen.
Naja, soll ja nur so als Idee sein.
Ich wiederhole: Ist mangels Hardware ungeprüft!!!