Smart Aquarium mit Temperatur-, PH-Wert- und Wasserstand- Regelung

Computer sind dazu da einem wiederkehrende schematische Arbeiten abzunehmen. Und als leidenschaftlicher Programmier habe ich mit jetzt einen hotstring "nodefine" programmiert der Autohotkey schreiben lässt

Die Nachteile von #define sind:
-nicht typsicher,
-keine namespaces,
-nicht als const-reference benutzbar,
-schlechtere Optimierung vom Compiler,
-nichtsaussagende Fehlermeldungen,
-tausende Fehlerquellen mit Addition ohne Klammern.
Deshalb Konstante "Variablen" definieren.

Das macht man durch hinzufügen des Wortes "const" vor dem Variablentyp.

Beispiel:

const byte relaisHeizung_Pin = 7;

Durch das Wort const weiß der Compiler, dass diese "Variable" ihren Wert nicht ändern darf.

Sollte man in seinem Programm ausversehen

relaisHeizung_Pin = 8;

programmieren, dann bringt der Compiler eine Fehlermeldung.

und wo wir schon mal beim selbsterklärende Namen vergeben sind gleich noch

const byte temp_start   = 20; 
const byte temp_min     = 15;
const byte temp_max     = 35;

hier das ganze Programm

/*
  Titel: Temperaturregelung Aquarium
  Datum: 29.06.2021
  Autor: ribaribi
  Hardware: Temperatursensor, 2x Relais, LCD Display, Taster, Arduino Mega
*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

const byte DS18B20_DATA = 2; //Daten-Pin für TemperaturSensor DS18B20
const byte Heizung_PIN  = 7; 
const byte Kuehlung_PIN = 6; 
const byte Knopf_PIN    = 3; 
const byte temp_start   = 20; 
const byte temp_min     = 15;
const byte temp_max     = 35;

// angenommen wenn man den IO-pin LOW schaltet wird das Relais 
//so geschaltet das der Kontakt geschlossen = HEIZUNG EINgeschaltet ist

const byte EIN = LOW;
const byte AUS = HIGH;

OneWire oneWire(DS18B20_DATA);
DallasTemperature sensors(&oneWire);
int knopf;
int soll_Temp;

void setup() {
  Serial.begin(115200); // im seriellen Monitor als Baudrate auch 115200 einstellen
  Serial.println( F("Setup-Start") );
  lcd.init();
  lcd.backlight();
  sensors.begin();
  pinMode(Heizung_PIN, OUTPUT);
  pinMode(Kuehlung_PIN, OUTPUT);
  digitalWrite(Heizung_PIN, AUS);
  digitalWrite(Kuehlung_PIN, AUS);
  pinMode(Knopf_PIN, INPUT_PULLUP);
}

void loop() {
  if (soll_Temp == 0) {
    soll_Temp = temp_start;
  }
  
  knopf = digitalRead(Knopf_PIN);
  if (knopf == 0) {
    soll_Temp = soll_Temp + 1;
  }
  
  if (soll_Temp > temp_max) {
    soll_Temp = temp_min;
  }
  
  sensors.requestTemperatures();
  float temp (sensors.getTempCByIndex(0));
  lcd.setCursor(0, 0);
  lcd.print("Temperatur Aquarium");
  lcd.setCursor(0, 1);
  lcd.print("Aktuell:   ");
  lcd.print(String(temp, 1));
  lcd.print("\337C ");
  lcd.setCursor(0, 2);
  lcd.print("Soll:      ");
  lcd.print(soll_Temp);
  lcd.print(".0\337C ");

  Serial.print( F("temp=") ); // name der Variable auasgeben
  Serial.print(temp); // Inhalt der Variable ausgeben

  Serial.print( F("  soll_Temp - 2") ); 
  Serial.print(soll_Temp - 2); // Ergebnis der Berechnung soll_Temp - 2 ausgeben
  Serial.println(); // println  print-line in die nächste Zeile springen
  
  Serial.print( F("temp=") ); // name der Variable auasgeben
  Serial.print(temp); // Inhalt der Variable ausgeben

  Serial.print( F("  soll_Temp + 2") ); 
  Serial.print(soll_Temp + 2); // Ergebnis der Berechnung soll_Temp + 2 ausgeben
  Serial.println(); // println  print-line in die nächste Zeile springen

  if (temp <= soll_Temp - 2) {
    Serial.println( F("Bedingung (temp <= soll_Temp - 2) ist TRUE") );
    Serial.println( F("Kühlung aus, Heizung ein") );
    lcd.setCursor(0, 3);
    lcd.print("Heizung    EIN");
    digitalWrite(Heizung_PIN, EIN);
    digitalWrite(Kuehlung_PIN, AUS);
  }

  if (temp >= soll_Temp + 2) {
    Serial.println( F("Bedingung (temp >= soll_Temp + 2) ist TRUE") );
    Serial.println( F("Kühlung ein, Heizung aus") );
    lcd.setCursor(0, 3);
    lcd.print("Kuehlung   EIN");
    digitalWrite(Kuehlung_PIN, EIN);
    digitalWrite(Heizung_PIN, AUS);
  }
  
  if (temp == soll_Temp) {
    Serial.println( F("Bedingung (temp == soll_Temp) ist TRUE") );
    Serial.println( F("Heizung und Kühlung aus") );
    digitalWrite(Heizung_PIN, AUS);
    digitalWrite(Kuehlung_PIN, AUS);
  }
  
  if (!digitalRead(Heizung_PIN) && !digitalRead(Kuehlung_PIN))
  {
    Serial.println( F("Bedingung (!digitalRead(Heizung_PIN) && !digitalRead(Kuehlung_PIN) ist TRUE") );
    lcd.setCursor(0, 3);
    lcd.print("Temperatur OK ");
  }
  
  delay(500);
}

vgs

halte ich für nicht zielführend.
Warum wird nicht initialisiert?

Im Übrigen:

aber:

Und die Nutzung des F-Macro auch nicht konsequent umgesetzt.

Wow.... Ihr seid ja unglaublich. danke für die vielen Inputs. Ich habe vieles nun einfliessen lassen. Das mit beiden Relais gleichzeitig ist Tatsache obwohl die eigentlich verriegelt sein sollten.
Das mit Low-Aktive Relais habe ich nicht ganz verstanden wie dies zu lösen ist im Allgemeinen.... Ich muss mal all die Informationen für mich und im Programm verarbeiten und dann schauen wie es aussieht... :slight_smile:

Das ist ganz einfach.
Aber erstmal zurück auf Deinen Post in #26.
Dann nimm den Code:

if (temp <= soll_Temp - 2) {
  lcd.print("Heizung    EIN");
  digitalWrite(Heizung_PIN, false);
  digitalWrite(Kuehlung_PIN, true);
}
if (temp >= soll_Temp + 2) {
  lcd.print("Kuehlung   EIN");
  digitalWrite(Kuehlung_PIN, false);
  digitalWrite(Heizung_PIN, true);
}
if (temp == soll_Temp)
{
  digitalWrite(Heizung_PIN, true);
  digitalWrite(Kuehlung_PIN, true);
}

if (!digitalRead(Heizung_Pin) && {!digitalRead(Kuehlung_Pin))
{
lcd.print("Temperatur OK");
}

Ergebnis?

Was heisst das jetzt genau du hast vieles einfliessen lassen?

Hast du das Testprogramm auf den Arduino geladen und wirklich herausgefunden ob deine Relais nun mit
digitalWrite(Heizung_Pin, false)
oder eben besser geschrieben als
digitalWrite(Heizung_Pin, LOW)

die Heizung EIN-schaltet?

Hast du meine Programmversion aus Post #42 mit dem seriellen output auf den Arduino geladen und dir die Ausgabe im seriellen Monitor angeschaut?

Wenn du noch nicht weißt wie man das mit dem seriellen Monitor macht. Einfach Bescheid sagen.
vgs
(insider-Anmerkung: Ob die "Antwort" des Computers aus dem Post 42 wohl gefallen wird?"

Noch eine grundsätzliche Anmerkung:
Du arbeitest an einem Informatik-Projekt. Und in einem Informatik-Projekt ist das wichtigste Information.

Du musst deine potentiellen Helfer schon ausführlich informieren was du getestet bzw. geändert hast.

Das heisst jedesmal wenn du eine Programmänderung gemacht hast die komplette neue Programmversion posten.

Wenn es serielle Ausgaben gibt die serielle Ausgabe auch als code-section posten.

Genau angeben was du gemacht hast
Beispiel: ich habe die Programversion aus post nummer 42 auf den Arduino geladen und dann folgende serielle Ausgabe bekommen.....

Jetzt versuche mal folgende unpräzise Anweisung in Programm umzusetzen.

"Wenn das nicht funktioniert dann musst du invertieren"

Da geht es dir so damit:
Hä was bitte?
Was meinst du mit "das"? wo soll etwas invertiert werden??
vgs

Wenn ich das tausche dann ist alles verkehrt, sprich auch die Anzeige stimmt dann nicht mehr. Irgendwas mit den Relais wird sein.

Hm...
Logisch.
Da ist die Anzeige ja noch anzupassen:

if (digitalRead(Heizung_Pin) && {digitalRead(Kuehlung_Pin))
{
lcd.print("Temperatur OK");
}

Schreib doch mal, was Du an Relaismodulen hast - dann spart man sich das raten.

Ich habe eine Bitte:
Hör mal auf irgendetwas zu vermuten und lade die Programversion aus post 42 auf deinen Arduino. Das ist 1 zu 1 DEIN Programm nur durch seriellen Output ergänzt.
Der serielle output redet Klartext. Damit siehst du dann ganz genau was dein Programm tatsächlich macht.
vgs

Ich habe mein Programm so ergänzt und geladen. im Serial Monitor geöffnet mit der korrekten Baudrate. Da wechselt der Zustand vom Kühlen nicht sobald er soll. Und wenn, dann direkt zum Heizen aber verspätet.... ich werde das wahrscheinlich nochmal von anfang an betrachten müssen. Es sah anfangs so simpel aus und nun verwirrt es mich mehr. X)

DEBO RELAIS 16CH

16 Kanal von reichelt.ch Schaltspannung 230V bis 10A, geschaltet mit 12V, angesteuert 5V

OK jetzt kann man analysieren...

Kleiner Formatierungsfehler von mir.

Die letzten beiden Ziffern hinter
"soll_Temp + 229" sind die Temperatur als integerwert
Da müsste noch ein Leerzeichen dazwischen

"soll_Temp + 2: 29"

So formatiert wäre es besser lesbar. Poste gleich eine neue Programmversion...

Ich habe zwei Konstanten definiert

const byte EIN = LOW;
const byte AUS = HIGH;

digitalWrite(Heizung_Pin,AUS)

macht
digitalWrite(Heizung_Pin,HIGH)
was auch
digitalWrite(Heizung_Pin,true)

entspricht

Das wäre für active-Low-Relais richtig.
Vielleicht hast du aber auch tatsächlich active-high-relais.
Poste mal auch ein Foto von deinen Relais

Wenn die LED leuchtet ist dann das Relais in dem Schaltzustand dass die Heizung eingeschaltet ist?

Die Frage stellt sich nicht.

Aber dazu müsste man das Datenblatt lesen.