Temperaturregler, Feuchtigkeitsregler, DHT22, LCD 1602, Problem mit Ein- und Ausschalten des Displays GELÖST!

Die Steckdose für die Heizmatte ist auf Pin2 so wie in post#1 auf dem Schaltplan :smiley:

Jetzt funktioniert alles wie gewünscht :slight_smile: .

//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
const byte button_Pin = 4;                                   // Pin für den Taster

// Regelkreise für Temperatursteuerung
const bool stDseAn = LOW;  // Wenn Steckdose falsch schaltet Logik tauschen
const bool stDseAus = !stDseAn;

enum { temp, hygro };
const byte kreise = 1;
const byte steckdose[kreise] = { 2 };      // Anzahl der Regelkreise (1x temp, 1x hygro)
const byte minimalWert[kreise] = { 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] = { 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
  }
  lcd.noBacklight();
}

void loop()
{
  //getSensors();
  //setTempSwitch();
  // setHumiSwitch(); // ausgeklammert, weil es im Kühlschrankinkubator keine Rolle spielt
  setDisplayOnOff();
  //setDisplay();
}

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 uint32_t lastSwitch = 0;            // Merker für auslösen der Taste
  static bool isOn = false;                  // Merker für Zustand des Backlight
  static bool buttonPressed = false;                              // Status des Tasters                            // Wenn die Variable in verschiedenen Funktionen des Sketches verwendet wird, muss sie als globale Variable deklariert werden.
  if (!digitalRead(button_Pin))              // Taster gedrückt?
  {
    if (!buttonPressed)                      // vorher nicht gedrückt?
    {
      Serial.println(F("Button gedrückt"));
      buttonPressed = true;                  // Tasterstatus auf gedrückt setzen
      isOn = !isOn;                          // Toogle der Variablen für das Backlight
      lastSwitch = millis();                 // Auslösezeit merken
    }
  }
  else                                       // Taster nicht (mehr) gedrückt?
  {
    if (millis() - lastSwitch > 100)         // entprellzeit ist abgelaufen
    { buttonPressed = false; }               // Tasterstatus auf nicht gedrückt setzen
  }
  isOn ? lcd.backlight() : lcd.noBacklight();
  // lcd.setBacklight(isOn);                    // Das Backlight mit dem Cariablenwert 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++)
    {
      lcd.setCursor(12, b);
      if (digitalRead(steckdose[b]) == HIGH)
      {
        lcd.print(' ');  // das w überschreiben
      }
      else
      {
        lcd.print('w');
      }
    }
  }
}

Nochmal ne kurze Frage: Mir ist schon öfter aufgefallen, dass die Fritzing Schaltpläne immer derbe unscharf sind wenn ich sie hier hochlade, gibts da irgendeinen Trick, das zu verhindern?

Dann mach das zu - Ich kann das Elend der 60 Posts nicht mehr ansehen ....

PS: Achte drauf, das Du gerade irgendwas anfängst zu kochen:

Nee, passt doch wenn man ranzoomt ;). Habe es gerade nochmal überprüft. Das ist kein Vorwurf :smiley: mir ist nur selber aufgefallen beim drüberfliegen mit den Augen, dass es sehr unscharf ist und man die Pins nur schwer lesen kann auf Anhieb, aber passt doch schon;)

Dann mach das zu - Ich kann das Elend der 60 Posts nicht mehr ansehen ....

mach ich :wink:

PS: Achte drauf, das Du gerade irgendwas anfängst zu kochen:

Okay, stelle ich nochmal um :wink:

Steckdose auf Pin 2, Taster auf Pin 4, dht auf Pin 7 und lcd auf Pin A4 und A5 - das wars. Wieso?

Wegen der zwei Regelkreise; Es wären ja noch weitere Pins frei - aber ich hab das jetzt so verstanden, das Du den alten Sketch nur mit dem Temperatursensor weiterverwenden willst und dann auch nur mit einer Heizung.

Da Du hygro nicht mehr hast (Dir fehlt ja jetzt der Pin/Kreis) nimm mal das hygro aus dem enum.
Dann merkst Du, wo es noch klemmt...
Wenn Du nur einen Kreis hast, musst Du aufräumen.

Also ich will folgendes machen: Temperatur und Hygro auf dem LCD anzeigen aber nur die Temperatur per Steckdose regeln. Am liebsten würde ich die Hygro- Regelung- Option ausgeklammert im Sketch lassen, sodass man sie bei Bedarf noch in den Schaltplan basteln kann.

So hier ist jetzt der neue Sketch (ohne Regelkreise) mit optionaler ausgeklammerter Hygro- Regulierung (setHumiSwitch()) und er funktioniert:

//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
const byte button_Pin = 4;                               // Pin für den Taster

// Regelkreise für Temperatursteuerung
const bool stDseAn = LOW;  // Wenn Steckdose falsch schaltet Logik tauschen
const bool stDseAus = !stDseAn;

const byte steckdoseTemp = 2;
const byte minimalWertTemp = 19;  // 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 maximalWertTemp = 21;
int16_t sensorWertTemp = 0;     // Temp, Hygro // alle Werte für Kreise auf 0 setzen
int16_t altSensorWertTemp = 0;  // alle Werte für Kreise auf 0 setzen

const byte steckdoseHygro = 3;
const byte minimalWertHygro = 85;
const byte maximalWertHygro = 92;
int16_t sensorWertHygro = 0;     // Temp, Hygro // alle Werte für Kreise auf 0 setzen
int16_t altSensorWertHygro = 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!!!)
  pinMode(steckdoseTemp, OUTPUT);
  pinMode(steckdoseHygro, OUTPUT);
  digitalWrite(steckdoseTemp, stDseAn);   // Ausgangszustand für alle Steckdosen ist LOW, die SSR- Relais von Steckdose 2,3,4 werden mit LOW angeschaltet
  digitalWrite(steckdoseHygro, stDseAn);  // Ausgangszustand für alle Steckdosen ist LOW, die SSR- Relais von Steckdose 2,3,4 werden mit LOW angeschaltet
  lcd.noBacklight();                      // am Anfang den LCD ausschalten
}

void loop() {
  getSensors();
  setTempSwitch();
  // setHumiSwitch(); // ausgeklammert, weil es im Kühlschrankinkubator keine Rolle spielt // wenn ich das Gerät auch als Feuchtigkeitsregler verwenden will, muss ich die Regelkreise erweitern, wie in dem Pilzzucht- Sketch;)
  setDisplayOnOff();
  setDisplay();
}

void getSensors() {
  sensorWertTemp = dht.readTemperature();
  sensorWertHygro = dht.readHumidity();
}

void setTempSwitch() {
  if (sensorWertTemp >= maximalWertTemp)  // Wenn die Temperatur gleich oder höher des festgelegten Maximums...
  {
    digitalWrite(steckdoseTemp, stDseAus);       // Heizung stoppen
  } else if (sensorWertTemp <= minimalWertTemp)  // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
  {
    digitalWrite(steckdoseTemp, stDseAn);  // Heizung starten
  }
}

void setHumiSwitch() {
  if (sensorWertHygro <= minimalWertHygro)  // HygroWert unter Grenzwert
  {
    digitalWrite(steckdoseHygro, stDseAn);         // Wasservernebler anschalten
  } else if (sensorWertHygro <= minimalWertHygro)  // Wenn die Temperatur gleich oder kleiner des festgelegten Minimus...
  {
    digitalWrite(steckdoseHygro, stDseAn);  // Heizung starten
  }
}

void setDisplayOnOff() {
  static uint32_t lastSwitch = 0;     // Merker für auslösen der Taste
  static bool isOn = false;           // Merker für Zustand des Backlight
  static bool buttonPressed = false;  // Status des Tasters                            // Wenn die Variable in verschiedenen Funktionen des Sketches verwendet wird, muss sie als globale Variable deklariert werden.
  if (!digitalRead(button_Pin))       // Taster gedrückt?
  {
    if (!buttonPressed)  // vorher nicht gedrückt?
    {
      Serial.println(F("Button gedrückt"));
      buttonPressed = true;   // Tasterstatus auf gedrückt setzen
      isOn = !isOn;           // Toggle der Variablen für das Backlight // also umkehren, negieren der Variable
      lastSwitch = millis();  // Auslösezeit merken
    }
  } else  // Taster nicht (mehr) gedrückt? // also wenn der Taster HIGH ist...
  {
    if (millis() - lastSwitch > 100)  // entprellzeit ist abgelaufen
    { buttonPressed = false; }        // Tasterstatus auf nicht gedrückt setzen
  }
  isOn ? lcd.backlight() : lcd.noBacklight();  //ternärer Operator, eine kompakte Schreibweise für: if (isOn == true){lcd.backlight();}else{lcd.noBacklight()}
}

void setDisplay() {
  bool TempisNew = false;
  bool HygroisNew = false;

  if (altSensorWertTemp != sensorWertTemp) {
    TempisNew = true;
    altSensorWertTemp = sensorWertTemp;
  }

  if (altSensorWertHygro != sensorWertHygro) {
    HygroisNew = true;
    altSensorWertHygro = sensorWertHygro;
  }

  if (TempisNew) {
    lcd.setCursor(0, 0);
    lcd.print("Temp.: ");
    if (sensorWertTemp < 10) {
      lcd.print(' ');
    }
    lcd.print(sensorWertTemp);  // Temperatur  anzeigen
    lcd.print("\337C ");        // Grad und dahinter Leerzeichen
    lcd.setCursor(12, 0);
    if (digitalRead(steckdoseTemp) == HIGH) {
      lcd.print(' ');  // das w überschreiben
    } else {
      lcd.print('w');
    }
  }

  if (HygroisNew) {
    lcd.setCursor(0, 1);
    lcd.print("LF.:   ");
    if (sensorWertHygro < 10) {
      lcd.print(' ');
    }
    lcd.print(sensorWertHygro);  // LF von Fruchtung anzeigen
    lcd.print(" %");
    lcd.setCursor(12, 1);
    if (digitalRead(steckdoseHygro) == HIGH) {
      lcd.print(' ');  // das w überschreiben
    } else {
      lcd.print('w');
    }
  }
}

Das was Du hier ausgeklammert hattest, habe ich rausgeschmissen, braucht man nicht, oder?

Vielen Dank an Alle für Eure Hilfe beim Finden des (saudummen) Fehlers :slight_smile: !

Das ist die zweite Variante, wie man das Backlight schalten kann.
Ich hätte diese vorgezogen. Aber das ist in Deinem Fall Geschmackssache..
Stell den endlich auf gelöst.

:+1:Danke

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.