Temperatursteuerung mit 2 DS18B20

Hallo zusammen,

Ich plane seit längerem ein kleines Projekt bei uns zuhause, undzwar geht es darum, im Keller einen Lüfter zu steuern, der von außen Kalte Luft einzieht, um den Raum zu kühlen. Der Lüfter soll dazu über ein Relais geschalten werden.
Nämlich immer dann, wenn die Temperatur außen geringer ist, als die im Kellerraum. Und das gaze so lange, bis eine Temperatur im Keller von 7°C oder so erreicht ist, ab dann soll der Lüfter nichts machen.
Dazu habe ich zwei DS18B20 Temeratursensoren, aber leider nicht viel Ahnung vom Programmieren mit dem arduino. Mein Wissen beschränkt sich aktuell noch auf recht einfache Sachen.
Es wäre super, wenn mir jemand helfen könnte!

Folgendes habe ich gefunden, was in die Richtung geht:

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

#define DS18B20_DATA 2

#define Knopf_Plus_PIN 3

#define Knopf_Minus_PIN 4

#define Relais_PIN 5

#define start

OneWire oneWire(DS18B20_DATA);
DallasTemperature sensors(&oneWire);
float soll_Temp;

void setup(){
lcd.init();
lcd.backlight();
sensors.begin();
pinMode(Relais_PIN, OUTPUT);
digitalWrite(Relais_PIN,HIGH);
pinMode(Knopf_Plus_PIN,INPUT_PULLUP);
pinMode(Knopf_Minus_PIN,INPUT_PULLUP);
}

void loop(){
if (soll_Temp == 0){
soll_Temp = start;
}
while (digitalRead(Knopf_Plus_PIN) == 0){
soll_Temp = soll_Temp + 0.1;
lcd.setCursor(0,1);
lcd.print("Soll: ");
lcd.print(String(soll_Temp,1));
lcd.print("\337C ");
delay(500);
int knopf_lang_plus = knopf_lang_plus + 1;
while (digitalRead(Knopf_Plus_PIN) == 0 && knopf_lang_plus == 3){
soll_Temp = soll_Temp + 0.1;
lcd.setCursor(0,1);
lcd.print("Soll: ");
lcd.print(String(soll_Temp,1));
lcd.print("\337C ");
delay(100);
}
}
while (digitalRead(Knopf_Minus_PIN) == 0){
soll_Temp = soll_Temp - 0.1;
lcd.setCursor(0,1);
lcd.print("Soll: ");
lcd.print(String(soll_Temp,1));
lcd.print("\337C ");
delay(500);
int knopf_lang_minus = knopf_lang_minus + 1;
while (digitalRead(Knopf_Minus_PIN) == 0 && knopf_lang_minus == 3){
soll_Temp = soll_Temp - 0.1;
lcd.setCursor(0,1);
lcd.print("Soll: ");
lcd.print(String(soll_Temp,1));
lcd.print("\337C ");
delay(100);
}
}
sensors.requestTemperatures();
float temp (sensors.getTempCByIndex(0));
lcd.setCursor(0,0);
lcd.print("Aktuell: ");
lcd.print(String(temp,1));
lcd.print("\337C ");
lcd.setCursor(0,1);
lcd.print("Soll: ");
lcd.print(String(soll_Temp,1));
lcd.print("\337C ");
if(temp >= soll_Temp){
lcd.setCursor(0,3);
lcd.print("Status:aus");
digitalWrite(Relais_PIN,HIGH);
}else{
lcd.setCursor(0,3);
lcd.print("Status:an");
digitalWrite(Relais_PIN,LOW);
}
}
"

Stele dein Sketch in Code Tags, oder in der IDE unter Bearbeiten -> Für Forum Kopieren
und hier einfügen.
Mit Bleistift Symbol kannst du das andern, editieren

Davon abgesehen, das ich die Idee in der vorliegenden Anforderung für gefährlich für die Bausubstanz halte, mal das ganze runtergekürzt.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte DS18B20_DATA = 2;
// const byte Knopf_Plus_PIN = 3;
// const byte Knopf_Minus_PIN = 4;
const byte Relais_PIN = 5;

OneWire oneWire(DS18B20_DATA);
DallasTemperature sensors(&oneWire);

const bool an = LOW;

int aussenTemp;
int innenTemp;
int schwellTemp = 7;
const int hystereseTemp = 1;


void setup()
{
  lcd.init();
  lcd.backlight();
  sensors.begin();
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
  pinMode(Relais_PIN, OUTPUT);
  digitalWrite(Relais_PIN, !an);
//  pinMode(Knopf_Plus_PIN, INPUT_PULLUP);
//  pinMode(Knopf_Minus_PIN, INPUT_PULLUP);
}

void loop()
{
  getSensors();
  setActor();
  displayInfo();
}
//
void getSensors()
{
  static uint32_t lastReadTime = 0;
  if (millis() - lastReadTime > 1000)
  {
    aussenTemp = sensors.getTempCByIndex(0);
    innenTemp = sensors.getTempCByIndex(1);
    sensors.requestTemperatures();
    lastReadTime = millis();
  }
}
//
void setActor()
{
  if (aussenTemp < innenTemp - hystereseTemp &&   // Aussen ist < drinnen UND
      innenTemp > schwellTemp)                          // drinnen > auslösetemperatur
  {
    digitalWrite(Relais_PIN, an);                             // auslösen
  }
  else                                                        //  sonst
  {
    digitalWrite(Relais_PIN, !an);                             // nicht auslösen
  }
}
//
void displayInfo()
{
  static int lastInnenTemp = 1000;
  static int lastAussenTemp = 1000;
  static bool lastRelaisState = !digitalRead(Relais_PIN);
  if (lastInnenTemp != innenTemp ||
      lastAussenTemp != aussenTemp ||
      lastRelaisState != digitalRead(Relais_PIN))
  {
    lcd.clear();
    lcd.print(F("Innen: "));
    lcd.print(innenTemp);
    lcd.print("\337C ");
    lcd.setCursor(0, 1);
    lcd.print(F("Aussen: "));
    lcd.print(aussenTemp);
    lcd.print("\337C ");
    lcd.setCursor(0, 2);
    lcd.print(F("Relais: "));
    lcd.print(digitalRead(Relais_PIN) == an ? "EIN" : "AUS");
    lastInnenTemp = innenTemp;
    lastAussenTemp = aussenTemp;
    lastRelaisState = !lastRelaisState;
  }
}
2 Likes

Hallo,
ich hab jetzt nur mal kurz drübergesehen.
ich mach Dir jetzt mal einen Vorschlag. Zunächst mal lass den Kram mit dem Display komplett weg und befasst Dich nur mit dem einlesen der beiden Temperaturen für innen und aussen. Dann überlegst Du die beiden Werte Deinen Wünschen entsprechend zu verrechnen und damit einen Ausgang für das Relais zu schalten. Das Kannst Du auch erst mal mit einer LED testen. Dazu ist ein gedanklicher Ablaufplan, auch gerne in einfacher "Textform" untereinander geschrieben hilfreich. Versuche das in Funktionsblöcke aufzuteilen. Wenn Du das vernünftig machst kannst später aus fast jeder Textzeile eine Codezeile machen. Wenn dann die Funktion so weit funktioniert baust Du das Display und die beiden Buttons für die Werteänderung dazu. Zu Verarbeitung der Buttons mit (kurz-lang- doppel click) kann ich Dir die OneButton Lib empfehlen. Allerdings sehe ich da noch keinen Grund zu, so wie ich das sehe willst Du ja nur einen Wert mit plus/minus verändern.

z.B folgende Funktions- Blöcke
messen
verarbeiten
Relais ausgeben
Werte ändern
Display anzeigen

der Block verarbeiten könnte dann im einfachsten Fall so aussehen
Temperatur Differenz bilden
wenn Differenz > 2 Grad dann Lüfter ein.
ansonsten Lüfter aus

Damit erhälst Du kleine Teilaufgaben, behälst den Überblick und vermeidest Spagetti Code.
Wenn möglich verzichte auf while Schleifen, die führen schnell dazu das Du in einer Schleife bist und nicht anderes mehr machen kannst. Dafür ist eine if.. Abfrage oder ein swich.. case Kunstrukt besser geeignet. Auf delay() solltest du letztlich auch verzichten und besser ein millis() Konstrukt einsetzen. Dazu gibts das Beispiel BlinkWithoutDelay und die Nachtwächter-Erklärung

Heinz

Nachtrag
@my_xy_projekt war schneller und hat gleich eine Lösung mitgeliefert :slight_smile:

1 Like

Sorry, ich konnte nicht widerstehen :wink:

1 Like

Danke euch zwei, hat echt sehr geholfen :slightly_smiling_face:
Frohe Weihnachten und einen guten Rutsch wünsche ich

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