Hallo Zusammen
Ich bin in einer Gruppe welche ein Gewächshaus 10 x 30 Meter betreibt und suchte vor einigen Monaten nach einer Gewächshaussteuerung mit Windmesser, für die Schliessung der Seitenwände bei Sturm. Kam dann auf den Arduino UNO R und kaufte mir ein Starterset. Ich kannte da die Programmiersprache C noch nicht, bin somit totaler Anfänger, seit gnädig mit eurer Kritik!
Habe das Programm so mit Kommentaren versehen, dass möglichst auch ein Laie aus unserer Gruppe die Befehle verstehen könnte.
Jetzt möchte ich von euch Experten wissen, ob mein Programm auch in der Praxis funktionieren würde.
Im Testaufbau funktioniert es und macht was ich möchte.
Den Temperaturfühler würde für den Einsatz noch geändert werden (DS18B20 Wasserdichte Version) mit einem 1,8kOhm für die Kabellänge von ca. 20 Meter.
Was würdet Ihr mir empfehlen, mit welchem Bord soll ich die Steuerung fertigen? Arduino Uno R, ESP32 oder ein anderes?
Kurze Auflistung von den Einstellmöglichkeiten über die Taster im Display:
minTemp: Ab wann Seitenwand schliessen
maxTemp: Ab wann Seitenwand öffnen
maximaler Wind: ab wann schliessen bei Sturm
SturmPause: Wie lange die Pause nach Sturmalarm sein soll in Minuten
Motorenlaufzeit: Wie lange die Motoren laufen sollen, bis die Seitenwand-Position erreicht ist, um dann den Temperaturausgleich zu starten (Intervall)
Intervall: Wie lange die Pause für den Temperaturausgleich sein soll, bis die Seitenwände die Position wieder ändern
Sicherheit Überspannung bei Arduino Steuerung:
Relais 1-4 sind Schliesser Relais (Stromdurchlass, wenn Relais Strom erhält)
Relais 5 & 6 sind Öffner Relais (Stromdurchlass wird unterbrochen, wenn Relais Strom erhält)
Damit der Strom, Seitenwand schliessen und Seitenwand öffnen nicht gleichzeitig zu den Motoren fliessen kann, werden die L1 und L2 von Seitenwand öffnen durch Relais 5 und 6 geleitet. So wird der Stromdurchfluss bei Relais 5 und 6 unterbrochen, wenn Seitenwand schliessen aktiv ist.
Motoren Drehrichtung (400V)
Bei Seitenwand öffnen wird L1 und L2 vertauscht, um die Drehrichtung der Motoren zu ändern.
Ich habe einen nicht sehr professionellen Schaltplan erstellt, mit manueller Schaltung und automatischer Steuerung durch Arduino Uno R, ich werde versuchen, dass pdf hochzuladen.
Originalprogramm war von draeger-it.blog/arduino-temperaturueberwachung-relais-per-schwellwert-tastersteuerung-mit-lcd-anzeige/) (vielen Dank dafür) dieses habe ich dann abgeändert.
#include <LCDI2C_Latin.h> // Bibliothek für das Display
// Library von Adafruit (benötigt auch Adafruit Unified Sensor Library)
// Bibliotheken für den Temperatursensor
#include "DHT.h"
#include <DHT_U.h>
#include <Adafruit_Sensor.h>
// Bibliothek zum Speichern & Lesen von Daten
// aus dem internen Speicher
#include <EEPROM.h>
// Bibliothek zum Entprellen eines Tasters
#include <Bounce2.h>
// Bibliotheken, um mit dem LCD-Display zu kommunizieren
#include <Wire.h>
#define DHTPIN 3 // Digitaler Pin 3 wird dem DHT-Sensor zugewiesen
#define DHTTYPE DHT11 // Bibliothek für Temperatursensor DHT 11
DHT dht1(DHTPIN, DHTTYPE); // Initialisiere den DHT-Sensor.
// Das Relais ist am digitalen Pin D4 angeschlossen.
//#define pin 4, OUTPUT
unsigned long TimelineIntervalTemperaturmesser; // Variable Speicher für Zeitlinie Temperaturmessung.
int StatusSeitenwandOeffnen = LOW;
int StatusSeitenwandSchliessen = LOW;
unsigned long TimelineRelais;
unsigned long TimelineInterval; // Variable Speicher für Systemzeit.
// Taster "select" am digitalen Pin D12 angeschlossen.
#define tasterSelect 12
// Taster "hoch" am digitalen Pin D11 angeschlossen.
#define tasterHoch 11
// Taster "runter" am digitalen Pin D10 angeschlossen.
#define tasterRunter 10
#define relais4 4 // Relais 4 ist an Pin D4
#define relais5 5 // Relais 5 ist an Pin D5
#define relais6 6 // Relais 6 ist an Pin D6
#define relais7 7 // Relais 7 ist an Pin D7
#define relais8 8 // Relais 8 ist an Pin D8
#define relais9 9 // Relais 9 ist an Pin D9
// Initialisieren des LCD-Displays mit der I2C-Adresse 0x27
LCDI2C_Latin lcd(0x27, 20, 4);
// Minimale Temperatur Speicherort
int minTemp = 0;
// Maximale Temperatur Speicherort
int maxTemp = 0;
// Maximaler Wind Speicherort
int maxWind = 0;
// Aktuelle Temperatur Speicherort
int aktuelleTemp = 0;
// Aktueller Wind km/h Speicherort
int aktuellerWind = 0;
// Sturmpause Speicherort
int SturmPause = 0;
// Motorlaufzeit Speicherort
int Motorlaufzeit = 0; // Wie lange der Motor läuft, um die Lüftungsposition zu erreichen
// Lüftungsintervall Speicherort
int Lueftungsintervall = 0; // Pause zwischen Seitenwandpositionierung.
// Bounce2-Objekte für die Taster
Bounce btnSelect = Bounce();
Bounce btnUp = Bounce();
Bounce btnDown = Bounce();
// Intervall für das Entprellen der Taster
const int BTN_INTERVALL = 25;
// Auswahl für Cursor auf Display
// 0 - min. Temperatur
// 1 - max. Temperatur
// 2 - aktuelle Temperatur
int auswahl = 0; // > min Temp
// Feld zum Speichern des Zeitstempels der letzten Aktualisierung.
unsigned long lastUpdate = 0UL;
int ADRESSE_MINTEMP = 0; // Speicherort für Mintemp
int ADRESSE_MAXTEMP = 2; // Speicherort für Maxtemp
int ADRESSE_MAXWIND = 4; // Speicherort für Maxwind
int ADRESSE_STURMPAUSE = 6; // Speicherort für Sturmpause
int ADRESSE_MOTORLAUFZEIT = 8; // Speicherort für Motorlaufzeit
int ADRESSE_LUEFTUNGSINTERVALL = 10; // Speicherort für Lüftungsintervall
// NEU: Signatur zur Erkennung eines leeren EEPROMs
int ADRESSE_SIGNATUR = 12; // Neue freie Adresse nutzen
const int EEPROM_SIGNATUR = 22; // Beliebige Zahl als "Erkennungsmerkmal"
unsigned long lastDebounceTime = 0; // Das letzte Mal, als der Ausgangspin umgeschaltet wurde
unsigned long debounceDelay = 3000; //3000 ist die Messdauer für Windmessung
int pinInterrupt = 2; // Eingang für Windmesser
unsigned long TimelineWind = millis(); // Speicherort für Zeitlinie TimelineWind
int Count = 0; // Speicherplatz für Windmesser Impulszählung
int WindStatus = LOW; // Windstatus am Start LOW
// Windmesser Impuls
void onChange() {
if (digitalRead(pinInterrupt) == LOW) // Ist der pinInterrupt LOW, beginne die Impulszählung des Windmessers
Count++; // Immer pro Impuls +1 dazuzählen
}
//___________________________________________________________________________________________
// SETUP WIRD NUR EINMAL BEIM START DURCHGEFÜHRT
void setup() {
WindStatus = LOW; // Windstatus auf LOW setzen
pinMode(pinInterrupt, INPUT_PULLUP); // Einstellung Interrupt-Pin
// Aktivieren
attachInterrupt(digitalPinToInterrupt(pinInterrupt), onChange, FALLING);
// Den Pin der Relais als Ausgang definieren
pinMode(relais4, OUTPUT);
pinMode(relais5, OUTPUT);
pinMode(relais6, OUTPUT);
pinMode(relais7, OUTPUT);
pinMode(relais8, OUTPUT);
Serial.begin(9600); // Starte den seriellen Monitor am PC
// Beginn der Kommunikation mit dem Sensor DHT11
dht1.begin();
// Beginn der Kommunikation mit dem LCD-Display
lcd.init(); // LCD initialisieren
lcd.backlight(); // Backlight einschalten
// Initialisieren der Taster
// Die Taster sind über den internen 10 kOhm Widerstand verbunden
btnSelect.attach(tasterSelect, INPUT_PULLUP); // Select-Taster
btnSelect.interval(BTN_INTERVALL);
btnUp.attach(tasterHoch, INPUT_PULLUP); // Hoch-Taster
btnUp.interval(BTN_INTERVALL);
btnDown.attach(tasterRunter, INPUT_PULLUP); // Ab-Taster
btnDown.interval(BTN_INTERVALL);
// Beschreiben des EEPROM-Speichers beim Start
int gespeicherteSignatur = readFromEEPROM(ADRESSE_SIGNATUR); // Prüfen, ob die Signatur bereits im Speicher existiert
if (gespeicherteSignatur != EEPROM_SIGNATUR) { // Weicht der Wert(!) von gespeicherteSignatur ab, dann EEPROM-Signatur schreiben
// EEPROM IST LEER -> Standardwerte definieren
minTemp = 22; // Gewünschten Standardwert eintragen
maxTemp = 25; // Gewünschten Standardwert eintragen
maxWind = 45; // Gewünschten Standardwert eintragen
SturmPause = 20; // Gewünschten Standardwert eintragen
Motorlaufzeit = 30; // Gewünschten Standardwert eintragen
Lueftungsintervall = 60; // Gewünschten Standardwert eintragen
// Werte einmalig in das leere EEPROM schreiben
writeToEEPROM(ADRESSE_MINTEMP, minTemp);
writeToEEPROM(ADRESSE_MAXTEMP, maxTemp);
writeToEEPROM(ADRESSE_MAXWIND, maxWind);
writeToEEPROM(ADRESSE_STURMPAUSE, SturmPause);
writeToEEPROM(ADRESSE_MOTORLAUFZEIT, Motorlaufzeit);
writeToEEPROM(ADRESSE_LUEFTUNGSINTERVALL, Lueftungsintervall);
// Signatur setzen, damit dieser Block nie wieder ausgeführt wird
writeToEEPROM(ADRESSE_SIGNATUR, EEPROM_SIGNATUR);
Serial.println("EEPROM war leer. Standardwerte wurden initialisiert."); // Serieller Monitor Ausdruck
} else { // Sonst
// EEPROM ENTHÄLT GÜLTIGE DATEN -> Normal auslesen
minTemp = readFromEEPROM(ADRESSE_MINTEMP);
maxTemp = readFromEEPROM(ADRESSE_MAXTEMP);
maxWind = readFromEEPROM(ADRESSE_MAXWIND);
SturmPause = readFromEEPROM(ADRESSE_STURMPAUSE);
Motorlaufzeit = readFromEEPROM(ADRESSE_MOTORLAUFZEIT);
Lueftungsintervall = readFromEEPROM(ADRESSE_LUEFTUNGSINTERVALL);
Serial.println("Daten erfolgreich aus EEPROM geladen.");
}
writeLcdDisplay(); // Befehl für das Beschreiben des Displays im Setup
}
void writeToEEPROM(int adresse, int wert) {
// EEPROM.update spart Schreibzyklen, indem es Werte vor dem Schreiben vergleicht
int aktuellerWert;
EEPROM.get(adresse, aktuellerWert);
if (aktuellerWert != wert) {
EEPROM.put(adresse, wert);
}
}
int readFromEEPROM(int adresse) { //
int gelesenerWert = 0; // Speicherort wird definiert und auf 0 gesetzt, dann..
EEPROM.get(adresse, gelesenerWert); // werden Daten aus dem EEPROM-Speicher eingelesen
return gelesenerWert; // Gelesener Wert wird zurückgesendet
}
// Schreibt eine Zeile auf das Display
void printTextAt(int lineNumber, int column, String text) { // Speicherort für: lineNumber (0, 0) / column (auswahl == 0 ? ">") / String Text " ");
lcd.setCursor(column, lineNumber); // Setze Cursor auf Zeilennummer
lcd.print(text); // Schreibe Text auf LCD
}
// Beschreibt das Display mit Text in Abhängigkeit von der
// aktuellen Auswahl.
void writeLcdDisplay() { // Befehl für das Beschreiben des LCD-Displays (Wird in LOOP aufgerufen)
lcd.clear(); // LCD löschen
if (auswahl < 3) { // Ist die Auswahl kleiner als 3, dann druckt es diesen Abschnitt (minTemp, maxTemp und maxWind)
printTextAt(0, 0, auswahl == 0 ? ">" : " "); // 0 ist die erste Zeile
printTextAt(1, 0, auswahl == 1 ? ">" : " "); // 1 ist die zweite Zeile / 0 ist die Position zum Schreiben auf dem Display / Auswahl ist 1 (max Temp)
printTextAt(2, 0, auswahl == 2 ? ">" : " ");
printTextAt(0, 1, "min. Temp.:" + String(minTemp, DEC)); // + String(minTemp): Es wird der minTemp-Wert abgerufen und an...
printTextAt(1, 1, "max. Temp.:" + String(maxTemp, DEC)); // DEC: Das erzwingt die Darstellung als Dezimalzahl (was bei int der Standard ist).
printTextAt(2, 1, "max Wind: " + String(maxWind, DEC));
printTextAt(3, 0, " akt.T." + String(aktuelleTemp, DEC)); // Beschreibe Zeile 4 mit aktT & Wert
printTextAt(3, 9, ""); // Zeichen für °C
printTextAt(3, 11, " Wind." + String(aktuellerWind)); // Ab Spalte 10 druckt es Wind. & Wert
} else { // Sonst druckt es diesen Abschnitt (Sturmpause, Motorlaufzeit, Lüftungsintervall)
printTextAt(0, 0, auswahl == 3 ? ">" : " ");
printTextAt(1, 0, auswahl == 4 ? ">" : " ");
printTextAt(2, 0, auswahl == 5 ? ">" : " ");
printTextAt(0, 1, "Sturm Pause: " + String(SturmPause, DEC));
printTextAt(1, 1, "Motorlaufzeit: " + String(Motorlaufzeit, DEC));
printTextAt(2, 1, "Lueft. Int.:" + String(Lueftungsintervall, DEC));
printTextAt(3, 0, " akt.T." + String(aktuelleTemp, DEC));
printTextAt(3, 9, " Wind." + String(aktuellerWind));
// Schreibe Werte in den internen EEPROM-Speicher
writeToEEPROM(ADRESSE_MINTEMP, minTemp);
writeToEEPROM(ADRESSE_MAXTEMP, maxTemp);
writeToEEPROM(ADRESSE_MAXWIND, maxWind);
writeToEEPROM(ADRESSE_STURMPAUSE, SturmPause);
writeToEEPROM(ADRESSE_MOTORLAUFZEIT, Motorlaufzeit);
writeToEEPROM(ADRESSE_LUEFTUNGSINTERVALL, Lueftungsintervall);
}
}
void SeitenwandOeffnen() { // Wenn im LOOP dieser Befehl steht, wird das ausgeführt:
// Zur Sicherheit werden alle Relais zum Schließen auf LOW gesetzt
digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais5, LOW); // L1 und L2 Berg Schließen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais8, LOW); // L1 und L2 Tal Schließen
StatusSeitenwandSchliessen = LOW;
// Alle Relais zum Öffnen werden auf HIGH gesetzt
digitalWrite(relais4, HIGH); // Nuller Berg
digitalWrite(relais6, HIGH); // L1 und L2 Berg Öffnen
digitalWrite(relais7, HIGH); // Nuller Tal
digitalWrite(relais9, HIGH); // L1 und L2 Tal Öffnen
StatusSeitenwandOeffnen = HIGH;
Serial.println("Seitenwand wird geöffnet");
Serial.println("________________________");
}
void SeitenwandOeffnenBeenden() {
// Zur Sicherheit werden alle Relais zum Schließen auf LOW gesetzt
digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais5, LOW); // L1 und L2 Berg Schließen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais8, LOW); // L1 und L2 Tal Schließen
StatusSeitenwandSchliessen = LOW;
// Alle Relais zum Öffnen werden auf LOW gesetzt
digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais6, LOW); // L1 und L2 Berg Öffnen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais9, LOW); // L1 und L2 Tal Öffnen
StatusSeitenwandOeffnen = LOW;
Serial.println("Seitenwand öffnen beendet");
Serial.println("________________________");
}
void SeitenwandSchliessen() {
// Zur Sicherheit werden alle Öffnen-Relais auf LOW gesetzt
//digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais6, LOW); // L1 und L2 Berg Öffnen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais9, LOW); // L1 und L2 Tal Öffnen
StatusSeitenwandOeffnen = LOW;
// Alle Relais zum Schließen werden auf HIGH gesetzt
digitalWrite(relais4, HIGH); // Nuller Berg
digitalWrite(relais5, HIGH); // L1 und L2 Berg Schließen
digitalWrite(relais7, HIGH); // Nuller Tal
digitalWrite(relais8, HIGH); // L1 und L2 Tal Schließen
StatusSeitenwandSchliessen = HIGH; // Status auf HIGH setzen
Serial.println("Seitenwand wird geschlossen (Relais)");
Serial.println("________________________");
}
void SeitenwandSchliessenBeenden() {
// Zur Sicherheit werden alle Öffnen-Relais auf LOW gesetzt
digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais6, LOW); // L1 und L2 Berg Öffnen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais9, LOW); // L1 und L2 Tal Öffnen
StatusSeitenwandOeffnen = LOW;
// Alle Relais zum Schließen werden auf LOW gesetzt
digitalWrite(relais4, LOW); // Nuller Berg
digitalWrite(relais5, LOW); // L1 und L2 Berg Schließen
digitalWrite(relais7, LOW); // Nuller Tal
digitalWrite(relais8, LOW); // L1 und L2 Tal Schließen
StatusSeitenwandSchliessen = LOW; // Status auf LOW setzen
Serial.println("Seitenwand schliessen beenden"); // Drucken Seitenwand...
Serial.println("________________________");
}
//_________________________________________________________________________________________________________
// LOOP WIRD IMMER WIEDER WIEDERHOLT
void loop() {
if (aktuellerWind > maxWind) { // Aktueller Wind ist höher als die eingestellte maximale Windgeschwindigkeit
WindStatus = HIGH; // Windstatus auf HIGH setzen
TimelineWind = millis(); // Starten der TimelineWind-Zeitlinie neu
SeitenwandSchliessen(); // Befehl für die Ansteuerung der Relais
Serial.println("Windalarm! Seitenwand schliessen"); // Seriellen Monitor bedrucken...
}
if (WindStatus == HIGH && aktuelleTemp <= maxTemp) { // Ist der WindStatus HIGH und aktuelleTemp tiefer als maxTemp, dann:
if (millis() - TimelineWind > SturmPause * 60000L) { // Sturmpause ist die Zeitpause nach einem Windalarm. Auf dem Display einstellbar in Minuten (millis x 60000 = Min.)
SeitenwandSchliessenBeenden(); // Befehl für die Ansteuerung der Relais
WindStatus = LOW; // Bereit für den nächsten Alarm, wenn der Wind wieder okay war
Serial.println("Windalarm beendet"); // Seriellen Monitor bedrucken: Windalarm beendet
TimelineWind = millis(); // Starten der TimelineWind-Zeitlinie neu
}
}
if (WindStatus == HIGH && aktuelleTemp > maxTemp && StatusSeitenwandOeffnen == LOW) { // Ist der WindStatus HIGH, aktuelleTemp höher als maxTemp und StatusSeitenwandOeffnen LOW, dann:
if (millis() - TimelineWind > SturmPause * 60000L) { // Sturmpause ist die Zeitpause nach einem Windalarm. Auf dem Display einstellbar in Minuten (millis x 60000 = Min.)
SeitenwandSchliessenBeenden(); // Befehl für die Ansteuerung der Relais
delay(1000); // Pause für Relais bei Umschaltung von Schließen auf Öffnen
SeitenwandOeffnen(); // Befehl für die Ansteuerung der Relais
StatusSeitenwandOeffnen = HIGH; // Dieses unlogische HIGH wird für die nächste if-Abfrage gebraucht, um die Bedingung zu erfüllen.
Serial.println("Seitenwand wird nach Windalarm wieder geöffnet"); // Serieller Monitor druckt: Seitenwand wird nach Windalarm wieder geöffnet
TimelineWind = millis(); // Starten der TimelineWind-Zeitlinie neu
}
}
if (WindStatus == HIGH && StatusSeitenwandOeffnen == HIGH) { // Ist der WindStatus HIGH und StatusSeitenwandOeffnen HIGH, dann:
if (millis() - TimelineWind > 15000) { // Zeitdauer für das vollständige Öffnen der Seitenwand nach dem Windalarm bei Temperaturen höher als MaxTemp
Serial.println("Seitenwand nach Windalarm wieder offen"); // Serieller Monitor druckt: Seitenwand nach Windalarm wieder offen
SeitenwandOeffnenBeenden(); // Befehl für die Ansteuerung der Relais
WindStatus = LOW; // Bereit für den nächsten Alarm, wenn der Wind wieder okay war
TimelineWind = millis(); // Starten der TimelineWind-Zeitlinie neu
}
}
{
if ((millis() - lastDebounceTime) > debounceDelay) { // Ist millis minus lastDebounceTime größer als debounceDelay. Eingestellter unsigned long Wert (oberster Abschnitt) für die Messdauer der Windmessung
lastDebounceTime = millis(); // Starten der lastDebounceTime-Zeitlinie neu
aktuellerWind = ((Count / (debounceDelay / 1000)) * 10); // Formel für die Berechnung der Windgeschwindigkeit; je nach Windmesser. Stimmt jetzt noch nicht!!!
// Ausdrucken auf dem seriellen Monitor, wie die Werte im EEPROM-Speicher sind:
Serial.print(aktuelleTemp);
Serial.println(" aktuelle Temperatur");
Serial.print(minTemp);
Serial.println(" minTemp");
Serial.print(maxTemp);
Serial.println(" maxTemp");
Serial.print(aktuellerWind);
Serial.println(" km/h Aktueller Wind");
Serial.print(SturmPause);
Serial.println(" Minuten Sturm Pause");
Serial.print(Motorlaufzeit);
Serial.println(" Sekunden für Motorlaufzeit");
Serial.print(Lueftungsintervall);
Serial.println(" Sekunden für Lueftungsintervall");
Serial.println(" ");
Count = 0; // Count wieder auf 0 zurücksetzen
}
delay(1); // Pause 1 Millisekunde, wird für die Messung der Windgeschwindigkeit benötigt
}
// Aktualisieren der Taster
btnSelect.update(); // Taster für die Auswahl, welche Zeile
btnUp.update(); // Taster für Wert erhöhen
btnDown.update(); // Taster für Wert senken
// Wenn der Taster "select" gedrückt wurde, dann...
if (btnSelect.fell()) {
if (auswahl < 5) { // Wenn die Auswahl kleiner als 5 ist, dann...
auswahl += 1; // Auswahl um 1 erhöhen
} else { // Sonst...
auswahl = 0; // Auf Auswahl 0 springen
}
writeLcdDisplay(); // Beschreiben des Displays. Befehl im Setup
}
// Wenn der Taster "hoch" gedrückt wurde, dann...
if (btnUp.fell()) {
if (auswahl == 0) { // Ist die Auswahl 0 (Zeile 1 min Temp), dann...
minTemp += 1; // Erhöhe den Wert bei minTemp um 1
} else if (auswahl == 1) { // Ist die Auswahl 1 (Zeile 2 max Temp), dann...
maxTemp += 1; // Erhöhe den Wert bei maxTemp um 1
} else if (auswahl == 2) { // Ist die Auswahl 2 (Zeile 3 maximaler Wind), dann...
maxWind += 1; // Erhöhe den Wert bei maxWind um 1
} else if (auswahl == 3) { // Ist die Auswahl 3 (Zeile 3 Sturmpause), dann...
SturmPause += 1; // Erhöhe den Wert bei Sturmpause um 1
} else if (auswahl == 4) { // Ist die Auswahl 4 (Zeile 4 Motorlaufzeit), dann...
Motorlaufzeit += 1; // Erhöhe den Wert bei Motorlaufzeit um 1
} else if (auswahl == 5) { // Ist die Auswahl 5 (Zeile 5 Lüftungsintervall), dann...
Lueftungsintervall += 1; // Erhöhe den Wert bei Lüftungsintervall um 1
}
writeLcdDisplay(); // Beschreiben des Displays. Befehl im Setup
SeitenwandOeffnenBeenden(); // Wird gemacht, damit das Programm keinen Hänger hat
}
// Wenn der Taster "runter" gedrückt wurde, dann...
if (btnDown.fell()) {
if (auswahl == 0) { // Ist die Auswahl 0 (Zeile 1 min Temp), dann...
minTemp -= 1; // Senke den Wert bei minTemp um 1
} else if (auswahl == 1) { // Ist die Auswahl 1 (Zeile 2 max Temp), dann...
maxTemp -= 1; // Senke den Wert bei maxTemp um 1
} else if (auswahl == 2) { // Ist die Auswahl 2 (Zeile 3 maximaler Wind), dann...
maxWind -= 1; // Senke den Wert bei maxWind um 1
} else if (auswahl == 3) { // Ist die Auswahl 3 (Zeile 3 Sturmpause), dann...
SturmPause -= 1; // Senke den Wert bei Sturmpause um 1
} else if (auswahl == 4) { // Ist die Auswahl 4 (Zeile 4 Motorlaufzeit), dann...
Motorlaufzeit -= 1; // Senke den Wert bei Motorlaufzeit um 1
} else if (auswahl == 5) { // Ist die Auswahl 5 (Zeile 5 Lüftungsintervall), dann...
Lueftungsintervall -= 1; // Senke den Wert bei Lüftungsintervall um 1
}
writeLcdDisplay(); // Beschreiben des Displays. Befehl im Setup
SeitenwandOeffnenBeenden(); // Wird gemacht, damit das Programm keinen Hänger hat
}
// Wenn der Zeitpunkt der letzten Ausführung plus dem Wert
// des Intervalls größer als die aktuellen Millisekunden sind, dann...
if (millis() - TimelineIntervalTemperaturmesser > 5000) { // Temperaturwert wird alle 5 Sekunden (5000 Millisekunden) ausgelesen
// Anfordern der Temperaturwerte
float t = dht1.readTemperature();
aktuelleTemp = dht1.readTemperature();
TimelineIntervalTemperaturmesser = millis();
writeLcdDisplay();
// Überschreiben des Wertes für die letzte Ausführung
}
// STEUERUNG DER SEITENWÄNDE / LÜFTUNG
{
if (WindStatus == LOW) { // Nur ausführen, wenn der Windstatus LOW ist
if ((aktuelleTemp <= (minTemp - 2.0)) || (aktuelleTemp >= (maxTemp + 2.0))) // Springt zurück (return), wenn die Temperatur 2 Grad Differenz zu min Temp oder max Temp hat.
// Das wird gemacht, um die Relais zu schonen und nicht unnötig Strom zu verbrauchen.
return; // Befehl, um den Loop neu zu beginnen.
// Wenn die gelesene Temperatur größer als der Wert der Konstante MAX_TEMP ist, dann soll die Lüftung öffnen.
if (aktuelleTemp >= maxTemp) {
if (StatusSeitenwandOeffnen == LOW) { // Ist der Status LOW, dann...
if (millis() - TimelineRelais > Motorlaufzeit * 1000L) { // Motorlaufzeit x 1000 = Sekunden
SeitenwandOeffnen(); // Im Setup oben der Befehl für die Ansteuerung der Relais
Serial.println("Seitenwand wird jetzt geöffnet");
TimelineRelais = millis(); // TimelineRelais neu starten
}
}
if (StatusSeitenwandOeffnen == HIGH) { // Wenn HIGH, dann...
if (millis() - TimelineRelais > Lueftungsintervall * 1000L) { // Lueftungsintervall x 1000 = Sekunden
SeitenwandOeffnenBeenden(); // Im Setup oben der Befehl für die Ansteuerung der Relais
Serial.println("Seitenwand öffnen wurde beendet");
TimelineRelais = millis(); // TimelineRelais neu starten
}
}
}
// Wenn die gelesene Temperatur kleiner als der Wert der Konstante MIN_TEMP ist,
// dann soll die Lüftung schließen.
if (aktuelleTemp <= minTemp) {
if (StatusSeitenwandSchliessen == LOW) { // Wenn LOW, dann...
if (millis() - TimelineRelais > Motorlaufzeit * 1000L) { // Motorlaufzeit x 1000 = Sekunden
SeitenwandSchliessen(); // Im Setup oben der Befehl für die Ansteuerung der Relais
Serial.println("Seitenwand wird geschlossen");
TimelineRelais = millis(); // TimelineRelais neu starten
}
}
if (StatusSeitenwandSchliessen == HIGH) { // Wenn HIGH, dann...
if (millis() - TimelineRelais > Lueftungsintervall * 1000L) { // Lueftungsintervall x 1000 = Sekunden
SeitenwandSchliessenBeenden(); // Im Setup oben der Befehl für die Ansteuerung der Relais
Serial.println("Seitenwand schliessen beendet");
TimelineRelais = millis(); // TimelineRelais neu starten
}
}
}
}
}
}
