Liebe communitiy,
Ich habe mir diesen Temperaturregler gebaut. Damit lässt sich z.B. die Temperatur im Inneren einer Kiste mit einer Heizmatte regeln. Die Minimum- Temperatur, ab der die Heizmatte eingeschaltet wird und die Maximal- Temperatur, ab der die Heizmatte ausgeschaltet wird lässt sich im Sketch festlegen.
WICHTIG: Der Verbraucher (in dem Falle eine Heizmatte) muss mit dem Relais abgestimmt sein. In meinem Falle wird eine Heizmatte mit 80 Watt / 230 VAC geschaltet und kann von dem verwendeten Relais geschaltet werden.
Durch das Hinzufügen eines weiteren Relais und einer weiteren Steckdose in den Schaltplan, könnte mit dem Gerät auch noch die Luftfeuchtigkeit reguliert werden. Diese Option ist in dem Sketch mit angelegt, aber ausgeklammert, weil ich nur die Temperatur regeln will.

Hier ist der Schaltplan:
Und jetzt zu meinem Problem:
Ohne das Einbeziehen des Tasters zum An- und Ausschalten des Displays funktioniert das Gerät mit diesem Sketch:
// Watchdog
#include <avr/wdt.h> // geht mit Arduino Uno, nicht mit Arduino Nano!
//Bibliotheken und Definieren von DHT22
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 7 //==> Der DHT22 Sensor wird an Pin 3 angeschlossen
#define DHTTYPE DHT22 //==> Es handelt sich um einen DHT22 Sensor
DHT dht(DHTPIN, DHTTYPE); // Der Sensor wird ab jetzt mit "dht" angesprochen
// Bibliotheken und Definieren von LCD1602
#include <Wire.h> // Bibliothek für 1602 LCD Display
#include <LiquidCrystal_I2C.h> // LiquidCrystal Bibliothek laden für LCD Display
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // so wenn ein 1602 display genutzt wird
// Regelkreise für Temperatursteuerung
const bool stDseAn = LOW; // Wenn Steckdose falsch schaltet Logik tauschen
const bool stDseAus = !stDseAn;
enum { temp,
hygro };
const byte kreise = 2;
const byte steckdose[kreise] = { 4, 5 }; // Anzahl der Regelkreise (1x temp, 1x hygro)
const byte minimalWert[kreise] = { 19, 85 }; // Austernseitling (Pleurotus ostreatus): Idealer Wert Myzelwachstum/ Box 1: 25 Grad // Idealer Wert Myzelwachstum nach mycelio/ Box 2: 20 Grad // minimale Temperatur/ Fruchtung: 10 Grad // LF- Einstellung wie von Pilzwunder
const byte maximalWert[kreise] = { 21, 92 };
int16_t sensorWert[kreise] = { 0 }; // Temp, Hygro // alle Werte für Kreise auf 0 setzen
int16_t altSensorWert[kreise] = { 0 }; // alle Werte für Kreise auf 0 setzen
void setup() {
Serial.begin(9600); // seriellen Monitor starten
// Sensoren und LCD starten
dht.begin(); //DHT22 Sensor starten
lcd.init(); // für den LCD- Monitor // initialisiert den LCD-Monitor, d.h. sie sorgt dafür, dass der Monitor richtig konfiguriert ist und bereit ist, Daten anzuzeigen
lcd.backlight(); // für den LCD- Monitor // schaltet die Hintergrundbeleuchtung des LCD-Monitors ein, so dass die Anzeige lesbar wird. Ohne diese Zeile wäre die Anzeige dunkel und es wäre schwierig, die darauf angezeigten Informationen abzulesen.
//Pins deklarieren und Anfangszustand deklarieren (Alle Steckdosen einschalten am Anfang!!!)
for (byte b = 0; b < kreise; b++) {
pinMode(steckdose[b], OUTPUT); // Regelkreise
digitalWrite(steckdose[b], stDseAn); // Ausgangszustand für alle Steckdosen ist LOW, die SSR- Relais von Steckdose 2,3,4 werden mit LOW angeschaltet
}
pinMode(LED_BUILTIN, OUTPUT); // KANN EIGENTLICH WEG?
// Watchdog aktivieren
wdt_reset();
wdt_enable(WDTO_8S); // Auslösen nach Zeit _8S (8sekunden)
getSensors(); // alle Sensoren werden in der void- funktion getSensors gelesen und in Variablen gespeichert
if (sensorWert[hygro] < maximalWert[hygro]) {
digitalWrite(steckdose[hygro], stDseAn); // Wasservernebler anschalten
}
wdt_reset();
}
void loop() {
getSensors();
setTempSwitch();
// setHumiSwitch(); // ausgeklammert, weil es im Kühlschrankinkubator keine Rolle spielt
setDisplay();
wdt_reset(); // WatchdogTimer neu starten
}
void getSensors() {
sensorWert[temp] = dht.readTemperature();
sensorWert[hygro] = dht.readHumidity();
}
void setTempSwitch() {
for (byte b = 0; b < hygro; b++) {
if (sensorWert[b] >= maximalWert[b]) // Wenn die Temperatur gleich oder höher des festgelegten Maximums...
{
digitalWrite(steckdose[b], stDseAus); // Heizung stoppen
} else if (sensorWert[b] <= minimalWert[b]) // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
{
digitalWrite(steckdose[b], stDseAn); // Heizung starten
}
}
}
void setHumiSwitch() {
if (sensorWert[hygro] <= minimalWert[hygro]) { // HygroWert unter Grenzwert
digitalWrite(steckdose[hygro], stDseAn); // Wasservernebler anschalten
} else if (sensorWert[hygro] <= minimalWert[hygro]) // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
{
digitalWrite(steckdose[hygro], stDseAn); // Heizung starten
}
}
void setDisplay() {
bool isNew = false;
for (byte b = 0; b < kreise; b++) {
if (altSensorWert[b] != sensorWert[b]) {
isNew = true;
altSensorWert[b] = sensorWert[b];
}
}
if (isNew) {
lcd.setCursor(0, 0);
lcd.print("Temp.: ");
for (byte b = 0; b < hygro; b++) {
if (sensorWert[b] < 10) {
lcd.print(' ');
}
lcd.print(sensorWert[b]); // Temperatur anzeigen
lcd.print("\337C "); // Grad und dahinter Leerzeichen
}
lcd.setCursor(0, 1);
lcd.print("LF.: ");
if (sensorWert[hygro] < 10) {
lcd.print(' ');
}
lcd.print(sensorWert[hygro]); // LF von Fruchtung anzeigen
lcd.print(" %"); //
for (byte b = 0; b < kreise; b++) {
switch (b) {
case 0:
lcd.setCursor(12, 0);
break;
case 1:
lcd.setCursor(12, 1);
break;
}
if (digitalRead(steckdose[b]) == HIGH) {
lcd.print(' '); // das w überschreiben
} else {
lcd.print('w');
}
}
}
}
Ich will den Display aber mit dem Taster ein- und ausschalten können. Dafür habe ich den Sketch angepasst. Leider geht der LCD nicht an und auch wenn ich den Taster drücke leuchtet der LCD nicht. Kann mir bitte jemand helfen das Problem zu lösen? ![]()
// Watchdog
#include <avr/wdt.h> // geht mit Arduino Uno, nicht mit Arduino Nano!
//Bibliotheken und Definieren von DHT22
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 7 //==> Der DHT22 Sensor wird an Pin 3 angeschlossen
#define DHTTYPE DHT22 //==> Es handelt sich um einen DHT22 Sensor
DHT dht(DHTPIN, DHTTYPE); // Der Sensor wird ab jetzt mit "dht" angesprochen
// Bibliotheken und Definieren von LCD1602
#include <Wire.h> // Bibliothek für 1602 LCD Display
#include <LiquidCrystal_I2C.h> // LiquidCrystal Bibliothek laden für LCD Display
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // so wenn ein 1602 display genutzt wird
#define button_Pin 4 // Pin für den Taster
bool lcdBacklightOn = true;
// Regelkreise für Temperatursteuerung
const bool stDseAn = LOW; // Wenn Steckdose falsch schaltet Logik tauschen
const bool stDseAus = !stDseAn;
enum { temp,
hygro };
const byte kreise = 2;
const byte steckdose[kreise] = { 4, 5 }; // Anzahl der Regelkreise (1x temp, 1x hygro)
const byte minimalWert[kreise] = { 19, 85 }; // Austernseitling (Pleurotus ostreatus): Idealer Wert Myzelwachstum/ Box 1: 25 Grad // Idealer Wert Myzelwachstum nach mycelio/ Box 2: 20 Grad // minimale Temperatur/ Fruchtung: 10 Grad // LF- Einstellung wie von Pilzwunder
const byte maximalWert[kreise] = { 21, 92 };
int16_t sensorWert[kreise] = { 0 }; // Temp, Hygro // alle Werte für Kreise auf 0 setzen
int16_t altSensorWert[kreise] = { 0 }; // alle Werte für Kreise auf 0 setzen
void setup() {
Serial.begin(9600); // seriellen Monitor starten
// Sensoren und LCD starten
dht.begin(); //DHT22 Sensor starten
lcd.init(); // für den LCD- Monitor // initialisiert den LCD-Monitor, d.h. sie sorgt dafür, dass der Monitor richtig konfiguriert ist und bereit ist, Daten anzuzeigen
pinMode(button_Pin, INPUT_PULLUP);
//Pins deklarieren und Anfangszustand deklarieren (Alle Steckdosen einschalten am Anfang!!!)
for (byte b = 0; b < kreise; b++) {
pinMode(steckdose[b], OUTPUT); // Regelkreise
digitalWrite(steckdose[b], stDseAn); // Ausgangszustand für alle Steckdosen ist LOW, die SSR- Relais von Steckdose 2,3,4 werden mit LOW angeschaltet
}
pinMode(LED_BUILTIN, OUTPUT); // KANN EIGENTLICH WEG?
// Watchdog aktivieren
wdt_reset();
wdt_enable(WDTO_8S); // Auslösen nach Zeit _8S (8sekunden)
getSensors(); // alle Sensoren werden in der void- funktion getSensors gelesen und in Variablen gespeichert
if (sensorWert[hygro] < maximalWert[hygro]) {
digitalWrite(steckdose[hygro], stDseAn); // Wasservernebler anschalten
}
wdt_reset();
}
void loop() {
getSensors();
setTempSwitch();
// setHumiSwitch(); // ausgeklammert, weil es im Kühlschrankinkubator keine Rolle spielt
setDisplayOnOff();
if (lcdBacklightOn) {
lcd.backlight(); // für den LCD- Monitor // schaltet die Hintergrundbeleuchtung des LCD-Monitors ein, so dass die Anzeige lesbar wird. Ohne diese Zeile wäre die Anzeige dunkel und es wäre schwierig, die darauf angezeigten Informationen abzulesen.
setDisplay();
} else {
lcd.noBacklight();
}
wdt_reset(); // WatchdogTimer neu starten
}
void getSensors() {
sensorWert[temp] = dht.readTemperature();
sensorWert[hygro] = dht.readHumidity();
}
void setTempSwitch() {
for (byte b = 0; b < hygro; b++) {
if (sensorWert[b] >= maximalWert[b]) // Wenn die Temperatur gleich oder höher des festgelegten Maximums...
{
digitalWrite(steckdose[b], stDseAus); // Heizung stoppen
} else if (sensorWert[b] <= minimalWert[b]) // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
{
digitalWrite(steckdose[b], stDseAn); // Heizung starten
}
}
}
void setHumiSwitch() {
if (sensorWert[hygro] <= minimalWert[hygro]) { // HygroWert unter Grenzwert
digitalWrite(steckdose[hygro], stDseAn); // Wasservernebler anschalten
} else if (sensorWert[hygro] <= minimalWert[hygro]) // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
{
digitalWrite(steckdose[hygro], stDseAn); // Heizung starten
}
}
void setDisplayOnOff() {
static bool buttonState = digitalRead(button_Pin); // Tasterstatus lesen
static bool buttonPressed = false; // Status des Tasters
if (buttonState == LOW && !buttonPressed) { // Wenn der Taster gedrückt wird und zuvor nicht gedrückt war
lcdBacklightOn = !lcdBacklightOn; // Status der LCD Hintergrundbeleuchtung umkehren
buttonPressed = true; // Tasterstatus auf gedrückt setzen
} else if (buttonState == HIGH) {
buttonPressed = false; // Tasterstatus auf nicht gedrückt setzen
}
}
void setDisplay() {
bool isNew = false;
for (byte b = 0; b < kreise; b++) {
if (altSensorWert[b] != sensorWert[b]) {
isNew = true;
altSensorWert[b] = sensorWert[b];
}
}
if (isNew) {
lcd.setCursor(0, 0);
lcd.print("Temp.: ");
for (byte b = 0; b < hygro; b++) {
if (sensorWert[b] < 10) {
lcd.print(' ');
}
lcd.print(sensorWert[b]); // Temperatur anzeigen
lcd.print("\337C "); // Grad und dahinter Leerzeichen
}
lcd.setCursor(0, 1);
lcd.print("LF.: ");
if (sensorWert[hygro] < 10) {
lcd.print(' ');
}
lcd.print(sensorWert[hygro]); // LF von Fruchtung anzeigen
lcd.print(" %"); //
for (byte b = 0; b < kreise; b++) {
switch (b) {
case 0:
lcd.setCursor(12, 0);
break;
case 1:
lcd.setCursor(12, 1);
break;
}
if (digitalRead(steckdose[b]) == HIGH) {
lcd.print(' '); // das w überschreiben
} else {
lcd.print('w');
}
}
}
}
