Lüfter mit 2 oder mehr Temperatursensoren regeln

Hallo mal wieder,

ich stoße z.Z. wieder an ein Problem.

Ich möchte einen PWM-Ausgang für einen Lüfter mit 2 oder mehr Temperatursensoren (es sollen insgesamt 10 Stück werden) ansteuern.

Es gibt eine Besonderheit bei der Ein- und Ausschaltsequenz:

Der Lüfterausgang wir in diesem Code bei einer Temperatur von 30° Grad mit einem bestimmten PWM-Wert(0-255) angesteuert und erhöht sich dann mit steigender Temperatur bis zum max. Wert von 255.

Fällt die Temperatur und somit die Drehzahl (PWM-Wert hier 60(ca. bei 28° Grad)), dann schaltet sich der Lüfterausgang ab. Somit wird verhindert, dass sich der Lüfterausgang um die 30° Grad ständig ein- und ausschaltet (2° Grad Schaltdifferenz).
Um das zu Realisieren, setze ich einen Wert (0 oder 1) für den ‘fanOut’ damit der Arduino den Lüfterausgang als Zustand hat.

1=Lüfterausgang aus
0=Lüfterausgang an

Außerdem schalte ich den Lüfterausgang für einen kleinen Moment ‘delay(500);’ auf den max. PWM-Wert von 255, damit der Lüfter aus seiner Trägheitsposition in die relativ kleine min.Drehzahl anlaufen kann.

Das funktioniert alles soweit so gut mit einem Temperatursensor. Mit zwei Temperatursensoren funktioniert es in soweit, dass die Temperaturwerte-Werte im Monitor angezeigt werden und auch der ‘fanOut-Wert’(auch im Monitor angezeigt), um die Schalttemperaturwerte richtig gesetzt wird.

Nur die Lüftergeschwindigkeit(PWM-Ausgang) wird bei dem ‘temp’ Fühler gesetzt und geregelt.

Bei dem ‘temp1’ Fühler bleibt der Lüfterausgang auf 0(auch im Monitor), bzw. sehe ich(da es der Pin13 ist) immer die kurze Anlaufdrehzahl (255) von ‘delay(500);’. Allerdings wird der ‘fanOut-Wert’(auch im Monitor angezeigt) richtig gesetzt.

Ich bin hier seit ein paar Stunden ratlos und komme nicht auf die Lösung für das Problem. Ich bin auch allerdings nicht der Profi in Sachen Programmierung. Es beschränkt sich eher auf Basis der “Hobbythek”.

Vielleicht hat jemand hier im Forum eine zündende Idee.

Vielen Dank, schon mal :slight_smile: .

Gruß Jens

// Konstanten
const int fanPin = 13;                 // Pin für den Lüfter
// Variablen
int fanSpeed = 0;          // Variable für die Lüftergeschwindigkeit
int fanMin = 75;           // Kleinster PWM Wert für den Lüfter befor er abschaltet
int fanOut = 1;            // Variable um zu Prüfen, ob der Lüfter aus war
int tMin = 20;             // Untere Grenze des Temperaturbereichs
int tMax = 60;             // Obere Grenze des Temperaturbereichs
float temp;                // Variable für die Berechnung der temperatur nach Steinhart
float temp1;                // Variable für die Berechnung der temperatur nach Steinhart
//Bibliotheken einbinden
#define ONE_WIRE_BUS  28 
#include <OneWire.h>  
#include <DallasTemperature.h>

//Objekte initialisieren
OneWire oneWire(ONE_WIRE_BUS);                       // OneWire initialisierung
DallasTemperature sensors(&oneWire);                 // DallasTemperature initialisierung

void setup()
{
  //TCCR1B = TCCR1B & 0b11111000 | 0x01;   // Setzt Timer1 (Pin 9 und 10) auf 31300Hz
  Serial.begin(9600);             // Baudrate für die Ausgabe am Serial Monitor
  pinMode(fanPin, OUTPUT);        // Setzt den Pin des Lüfters als Ausgang
}


void loop()
{
  
    sensors.requestTemperatures();                      // Temperatur lesen
  temp = sensors.getTempCByIndex(0);           // Temperatur vom Sensor 0 auslesen  
  temp1 = sensors.getTempCByIndex(1);           // Temperatur vom Sensor 1 auslesen
  Serial.print("Temperatur: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp);    
  Serial.print("Temperatur1: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp1);    
    Serial.print("FanOut: ");                       // Werte über RS232 Port ausgeben
  Serial.println(fanOut); 
  // Lüftergeschwindigkeit über den Temperaturbereich einstellen
  // TMin->0% PWM | TMax->100% PWM
  fanSpeed = map(temp, tMin, tMax, 30, 255);    
  
  // Wenn der PWM Wert unter den van FanMin fällt, schält der Lüfter ab
  if (fanSpeed < fanMin)
  {
    fanSpeed = 0;
    fanOut = 1;
  }
  
  // Hysterese
  if (fanOut == 1)
  {
    fanSpeed = 0;
  }
  
  if((temp >= 30)||(temp1 >= 30))
  {
    if(fanOut == 1)
    {
      fanOut = 0;
      analogWrite(fanPin,255);
      delay(500); 
    }
  }
  
  // PWM Wert auf 255 begerenzen  
  if (fanSpeed > 255)
  { 
    fanSpeed = 255;
  }
  
  // Lüftergeschwindigkeit über den Seriellen Monitor ausgeben
  Serial.print("Lueftergeschwindigkeit: ");          
  Serial.println(fanSpeed);

  analogWrite(fanPin, fanSpeed);      // Den Lüfter mit dem PWM Wert ansteuern
  delay(500);  
}

du mapst nur temp nicht tem1. Was soll der Lüfter machen, wenn temp=30 und temp1=60 ist?

Wenn ich dass alles richtig verstanden habe, wuerde ich vorschlagen dass du die hoechste Wert von temp und temp1 (und alle anderen) nimmst um die Logik zu vereinfachen - denn, ist es nicht so, dass wenn nur eine der Temperatursensoren auf 30 Grad steigt dann willst du den Luefterausgang einschalten?

Wenn ALLE der Sensoren auf 28 Grad sinken dann schaltest du den Luefterausgang wieder aus?

Also, aktuelleTemp = MAX(temp1, temp2, temp3 usw).

Dann, fanSpeed = map(aktuelleTemp, tMin, tMax, 30, 255);

Habe ich dass richtig verstanden?

Hallo Ralph,

danke für die Hilfe. Du hast es genau richtig verstanden! :)

Es muss aber so lauten:

aktuelleTemp = max(temp, temp1);

Ich hatte erst das MAX so mit raus kopiert, was natürlich nicht funktioniert und in der Hysterese muss es auch noch umgestellt werden:

// Hysterese if (fanOut == 1) { fanSpeed = 0; }

if(aktuelleTemp >= 30) { if(fanOut == 1) { fanOut = 0; analogWrite(fanPin,255); delay(500); } }

Es funktioniert nun wie es soll.

[u]Nun kommt mir aber noch ein anderer Gedanke:[/u]

Lassen sich eigentlich ohne eine direkte Adresse der DS18B20 Temperaturfühler im Code anzugeben, mehr als 4 Temperaturfühler auslesen.

Ich meine irgendwo im Forum gelesen zu haben, dass sich nur max. 4 Temperaturfühler auslesen lassen?

Gruß Jens

Knippi: Es funktioniert nun wie es soll.

Prima! Gut dass ich Dir irgendwie geholfen habe.

Von dem DataSheet des DS18B20 (https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) heisst es:

Each DS18B20 has a unique 64-bit serial code, which allows multiple DS18B20s to function on the same 1-Wire bus. Thus, it is simple to use one microprocessor to control many DS18B20s distributed over a large area.

Also keine Begrenzung auf bloss 4 Temperaturfuehler? Ich glaube du musst es ausprobieren aber ich glaube schon dass es funktioniert.

Hallo Ralph,

ich habe nun 10 Temperatursensoren eingebunden und die Zeile erweitert:

aktuelleTemp = max(temp, temp1, temp2, temp3);

Dann kommt aber folgende Fehlermeldung:

‘max’ was not declared in this scope

Ich verstehe die Fehlermeldung nicht.

// Konstanten
const int fanPin = 12;                 // Pin für den Lüfter
// Variablen
int fanSpeed = 0;          // Variable für die Lüftergeschwindigkeit
int fanMin = 60;           // Kleinster PWM (110/41°C) Wert für den Lüfter befor er abschaltet
int fanOut = 1;            // Variable um zu Prüfen, ob der Lüfter aus war
int tMin = 25;             // Untere Grenze des Temperaturbereichs
int tMax = 60;             // Obere Grenze des Temperaturbereichs
float temp;                // Variable für die Berechnung der temperatur nach Steinhart
float temp1;                // Variable für die Berechnung der temperatur nach Steinhart
float temp2;                // Variable für die Berechnung der temperatur nach Steinhart
float temp3;                // Variable für die Berechnung der temperatur nach Steinhart
float temp4;                // Variable für die Berechnung der temperatur nach Steinhart
float temp5;                // Variable für die Berechnung der temperatur nach Steinhart
float temp6;                // Variable für die Berechnung der temperatur nach Steinhart
float temp7;                // Variable für die Berechnung der temperatur nach Steinhart
float temp8;                // Variable für die Berechnung der temperatur nach Steinhart
float temp9;                // Variable für die Berechnung der temperatur nach Steinhart
float aktuelleTemp;
//Bibliotheken einbinden
#define ONE_WIRE_BUS  28 
#include <OneWire.h>  
#include <DallasTemperature.h>

//Objekte initialisieren
OneWire oneWire(ONE_WIRE_BUS);                       // OneWire initialisierung
DallasTemperature sensors(&oneWire);                 // DallasTemperature initialisierung

void setup()
{
  //TCCR1B = TCCR1B & 0b11111000 | 0x01;   // Setzt Timer1 (Pin 9 und 10) auf 31300Hz
  Serial.begin(9600);             // Baudrate für die Ausgabe am Serial Monitor
  pinMode(fanPin, OUTPUT);        // Setzt den Pin des Lüfters als Ausgang
}


void loop()
{
  
   sensors.requestTemperatures();                      // Temperatur lesen
  temp = sensors.getTempCByIndex(0);           // Temperatur vom Sensor 0 auslesen  
  temp1 = sensors.getTempCByIndex(1);           // Temperatur vom Sensor 1 auslesen
  temp2 = sensors.getTempCByIndex(2);           // Temperatur vom Sensor 1 auslesen
  temp3 = sensors.getTempCByIndex(3);           // Temperatur vom Sensor 1 auslesen 
  temp4 = sensors.getTempCByIndex(4);           // Temperatur vom Sensor 1 auslesen
  temp5 = sensors.getTempCByIndex(5);           // Temperatur vom Sensor 1 auslesen
  temp6 = sensors.getTempCByIndex(6);           // Temperatur vom Sensor 1 auslesen
  temp7 = sensors.getTempCByIndex(7);           // Temperatur vom Sensor 1 auslesen
  temp8 = sensors.getTempCByIndex(8);           // Temperatur vom Sensor 1 auslesen
  temp9 = sensors.getTempCByIndex(9);           // Temperatur vom Sensor 1 auslesen  
  Serial.print("Temperatur: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp);    
  Serial.print("Temperatur1: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp1);    
  Serial.print("Temperatur2: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp2); 
  Serial.print("Temperatur3: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp3); 
  Serial.print("Temperatur4: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp4); 
  Serial.print("Temperatur5: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp5); 
  Serial.print("Temperatur6: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp6);   
  Serial.print("Temperatur7: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp7);  
  Serial.print("Temperatur8: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp8);  
  Serial.print("Temperatur9: ");                       // Werte über RS232 Port ausgeben
  Serial.println(temp9);  
  Serial.print("FanOut: ");                       // Werte über RS232 Port ausgeben
  Serial.println(fanOut); 
  aktuelleTemp = max(temp, temp1, temp2, temp3);
  // Lüftergeschwindigkeit über den Temperaturbereich einstellen
  // TMin->0% PWM | TMax->100% PWM
  fanSpeed = map(aktuelleTemp, tMin, tMax, 110, 255);    

  // Wenn der PWM Wert unter den van FanMin fällt, schält der Lüfter ab
  if (fanSpeed < fanMin)
  {
    fanSpeed = 0;
    fanOut = 1;
  }

  // Hysterese
  if (fanOut == 1)
  {
    fanSpeed = 0;
  }

  if(aktuelleTemp >= 30)
  {
    if(fanOut == 1)
    {
      fanOut = 0;
      analogWrite(fanPin,255);
      delay(500); 
    }
  }

  // PWM Wert auf 255 begerenzen  
  if (fanSpeed > 255)
  { 
    fanSpeed = 255;
  }

  // Lüftergeschwindigkeit über den Seriellen Monitor ausgeben
  Serial.print("Lueftergeschwindigkeit: ");          
  Serial.println(fanSpeed);

  analogWrite(fanPin, fanSpeed);      // Den Lüfter mit dem PWM Wert ansteuern
  delay(500);  
} 

}

Vielleicht hat einer eine Idee. :slight_smile:

Gruß Jens

Hallo,

guck dir mal die Funktion an. Fällt dir was auf? https://www.arduino.cc/en/Reference/Max

Hi Doc,

danke für die Antwort.

Wenn ich es richtig verstanden habe, dann kann ich das nur für 2 Temperatursensoren so machen. :( Gibt es denn eine Möglichkeit für alle 10 Sensoren?

Gruß Jens

Hallo,

richtig, immer nur 2 vergleichen und nun ist etwas überlegen gefragt. Wie wäre es damit ...

aktuelleTemp = max(temp, temp1);
aktuelleTemp = max(aktuelleTemp, temp2);
aktuelleTemp = max(aktuelleTemp, temp3);

Hallo,

kommt das System mit den ganzen 'aktuelleTemp' nicht durcheinander oder muss man diese Nummerieren?

Gruß Jens

Hallo,

überlege jetzt mal in Ruhe was da passiert oder teste es einfach aus ... Die Funktions Referenz kannste dir auch nochmal anschauen.

Knippi: Hallo Ralph,

ich habe nun 10 Temperatursensoren eingebunden und die Zeile erweitert:

aktuelleTemp = max(temp, temp1, temp2, temp3);

Dann kommt aber folgende Fehlermeldung:

'max' was not declared in this scope

Ich verstehe die Fehlermeldung nicht.

In C (oder c++ ??) können mehrere gleiche Funktionen existieren, deren Unterschied eine verschiedene Anzahl an übergebenen Parametern ist.

also max(temp, temp1) ist eine andere Funktion als max(temp, temp1, temp2) Und weil nur die Funktion mit 2 Parametern irgendwo definiert ist, existiert die gleichnamige Funktion mit 3 oder mehr Paramentern nicht. Darum die Fehlermeldung.

Lösung: * Die Funktion mehrfach anwenden wie schon gezeigt wurde. * Eine Funktion selbst schreiben, die das mach,t was man braucht.

Grüße Uwe

Habe verstanden :) .

Ich war der Meinung, es gibt immer nur eine definierte Funktion, die einmalig bzw. eindeutig sein muss.

Es ist im Sketch jetzt umgesetzt und funktioniert.

Vielen Dank.

Gruß Jens

Hallo Jens,

könntest Du Deinen inzwischen funktionierenden Sketch mal komplett hier posten? Ich habe etwas Ähnliches (allerdings nur mit 3 Lüftern/Sensoren) vor. Danke.

Hallo Gelegenheitsbastler,

der Sketch ist nicht komplett fertig. Es ist nur ein Teil eines Projektes, indem die Lüftersteuerung ein Teil davon ist.

Was willst du machen?

Gruß Jens