Hi , ich baue gerade ein Bewässerungssteuerung für meinen Garten. Ich habe hierzu den Sketch von jurs aus dem Forum genommen und wollte ihn etwas erweitern.
zum Aufbau: Ich habe 2 Ventile ,eine Pumpe und einen "Regensensor" und eine RTC3231
Die Pumpe (Pin 4) soll von 20:30Uhr - 20:40 laufen
der Regensensor überprüft ob es geregnet hat oder nicht -> wenn ja dann sollen die Ventile (Pin 7+8) geschlossen bleiben
wenn es nicht geregnet hat, sollen die Ventile (Pin 7+8 ) zeitversetzt auf
Ventil 1 (Pin 7) 20:30 - 20:35 Uhr
Ventil 2 (Pin 8) 20:35 - 20:40 Uhr
Der Regensensor besteht einfach nur aus 2 Drähten die messen ob sich Wasser in einem kleinen Behälter befindet oder nicht, angeschlossen ist er auf Pin 9
Ich habe jetzt schon einiges Probiert aber war leider erfolglos . Vielleicht habt ihr ja eine Idee wie ich das umsetzen könnte. Vielleicht ist der Code von jurs aber einfach zu overkill für mein Vorhaben..was denkt ihr?
grüße Alex
#define EIN LOW
#define AUS HIGH
const int sensorPin = 9; //Pin D9
int sensorState = 0;
struct schaltRelais_t {
byte pin;
int ein1; int aus1;
int ein2; int aus2;
int ein3; int aus3;
};
// Hier die Relais-Pins definieren mit Ein- und Ausschaltzeiten
schaltRelais_t schaltRelais[3] = {
{4, 2030, 2040,}, // Pumpe Relais Pin, Einschaltzeit, Ausschaltzeit
{7, 2030, 2035,}, // Ventil Beet 1
{8, 2035, 2040,}, // Ventil Beet 2
};
void relaisSchaltenNachZeit(int thishour, int thisminute)
// Schaltet die Zeitschaltuhr ein und aus und setzt den Ausgang entsprechend
{
boolean state;
// Aus der aktuellen Zeit eine Schaltzeit bilden
int thisTime = thishour * 100 + thisminute;
// Alle Schaltzeiten durchgehen, falls eine davon EIN sagt, einschalten
for (int i = 0; i < sizeof(schaltRelais) / sizeof(schaltRelais_t); i++)
{
state = AUS; // Amnahme: Es sei nichts geschaltet
if (
(thisTime >= schaltRelais[i].ein1 && thisTime < schaltRelais[i].aus1) ||
(thisTime >= schaltRelais[i].ein2 && thisTime < schaltRelais[i].aus2) ||
(thisTime >= schaltRelais[i].ein3 && thisTime < schaltRelais[i].aus3)
)
{
state = EIN;
}
if (digitalRead(schaltRelais[i].pin) != state) // Falls geschaltet werden soll
{ // ein paar Debug-Ausgaben machen
Serial.print("Relais ");
Serial.print(i + 1); // Relais-Index zählt ab 0, einfach 1 dazuzählen
Serial.print(": ");
if (state == EIN) Serial.println("EIN"); else Serial.println("AUS");
}
digitalWrite(schaltRelais[i].pin, state); // Schaltzustand setzen
}
}
#include <Wire.h>
// I2C Adresse der RTC ist 0x68 für DS1307 und DS3231
#define RTC_I2C_ADDRESS 0x68
int jahre, monate, tage, stunden, minuten, sekunden;
// wochentag bleibt in diesem Test-Sketch unberücksichtigt
void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
// aktuelle Zeit aus RTC auslesen
{
// Reset the register pointer
Wire.beginTransmission(RTC_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(RTC_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
sekunden = bcdToDec(Wire.read() & 0x7f);
minuten = bcdToDec(Wire.read());
stunden = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
/*wochentag = */bcdToDec(Wire.read());
tage = bcdToDec(Wire.read());
monate = bcdToDec(Wire.read());
jahre = bcdToDec(Wire.read()) + 2000;
}
void rtcWriteTime(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
// aktuelle Zeit in der RTC speichern
{
Wire.beginTransmission(RTC_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(sekunden)); // 0 to bit 7 starts the clock
Wire.write(decToBcd(minuten));
Wire.write(decToBcd(stunden)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.write(decToBcd(0)); // Wochentag unberücksichtigt
Wire.write(decToBcd(tage));
Wire.write(decToBcd(monate));
Wire.write(decToBcd(jahre - 2000));
Wire.endTransmission();
}
byte decToBcd(byte val) // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert decimal number to binary coded decimal
// Hilfsfunktion für die Echtzeituhr
{
return ( (val / 10 * 16) + (val % 10) );
}
byte bcdToDec(byte val) // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert binary coded decimal to decimal number
// Hilfsfunktion für die Echtzeituhr
{
return ( (val / 16 * 10) + (val % 16) );
}
int getIntFromString (char *stringWithInt, byte num)
// input: pointer to a char array
// returns an integer number from the string (positive numbers only!)
// num=1, returns 1st number from the string
// num=2, returns 2nd number from the string, and so on
{
char *tail;
while (num > 0)
{
num--;
// skip non-digits
while ((!isdigit (*stringWithInt)) && (*stringWithInt != 0)) stringWithInt++;
tail = stringWithInt;
// find digits
while ((isdigit(*tail)) && (*tail != 0)) tail++;
if (num > 0) stringWithInt = tail; // new search string is the string after that number
}
return (strtol(stringWithInt, &tail, 10));
}
void setup()
{
pinMode(sensorPin, INPUT);
Wire.begin(); // initialisiert die Wire-Library
Serial.begin(9600); // Serielle Kommunikation starten
while (!Serial); // wait for serial port to connect. Needed for Leonardo only
Serial.println("\r\nZeitschaltuhr- und Kurzzeittimer-Demo Sketch");
Serial.println("Coded by jurs for German Arduino Forum.");
Serial.println("Jede Minute wird die aktuelle Zeit im 'Seriellen Monitor' angezeigt.");
Serial.println("Ebenso alle Ein- und Ausschaltungen und die Kurzzeittimer-Aktion");
Serial.println();
Serial.println("Du kannst die Zeit mit einem 'set' Befehl im 'Serial Monitor' neu setzen.");
Serial.println("\r\nBeispiel:");
Serial.println("set 28.08.2013 10:54\r\n");
for (int i = 0; i < sizeof(schaltRelais) / sizeof(schaltRelais_t); i++)
{
digitalWrite(schaltRelais[i].pin, AUS);
pinMode(schaltRelais[i].pin, OUTPUT);
}
}
void behandleSerielleBefehle()
{
char linebuf[30];
byte counter;
if (Serial.available())
{
delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
memset(linebuf, 0, sizeof(linebuf)); // Zeilenpuffer löschen
counter = 0; // Zähler auf Null
while (Serial.available())
{
linebuf[counter] = Serial.read(); // Zeichen in den Zeilenpuffer einfügen
if (counter < sizeof(linebuf) - 1) counter++; // Zeichenzähler erhöhen
}
// Ab hier ist die Zeile eingelesen
if (strstr(linebuf, "set") == linebuf) // Prüfe auf Befehl "set" zum Setzen der Zeit
{ // Alle übermittelten Zahlen im String auslesen
tage = getIntFromString (linebuf, 1);
monate = getIntFromString (linebuf, 2);
jahre = getIntFromString (linebuf, 3);
stunden = getIntFromString (linebuf, 4);
minuten = getIntFromString (linebuf, 5);
sekunden = getIntFromString (linebuf, 6);
}
else
{
Serial.println("Befehl unbekannt.");
return;
}
// Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen:
if (jahre < 2000 || monate < 1 || monate > 12 || tage < 1 || tage > 31 || (stunden + minuten) == 0)
{
Serial.println(linebuf);
Serial.println("\r\nFehlerhafte Zeitangabe im 'set' Befehl");
Serial.println("\r\nBeispiel:");
Serial.println("set 28.08.2013 10:54\r\n");
return;
}
rtcWriteTime(jahre, monate, tage, stunden, minuten, sekunden);
Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
}
}
void loop()
{
char buffer[30];
static unsigned long lastMillis;
static int lastMinute;
int stunden, minuten, sekunden, dummy;
sensorState = digitalRead(sensorPin);
if (millis() - lastMillis > 1000) // nur einmal pro Sekunde
{
lastMillis = millis();
rtcReadTime(dummy, dummy, dummy, stunden, minuten, sekunden);
if (minuten != lastMinute) // die aktuelle Minute hat gewechselt
{
lastMinute = minuten;
snprintf(buffer, sizeof(buffer), "%02d:%02d Uhr", stunden, minuten);
Serial.println(buffer);
relaisSchaltenNachZeit(stunden, minuten);
}
}
behandleSerielleBefehle();
}