Temperatur hoch --> Relais ein --> Temp niedrig --> Relais verzögert aus

Hey Ho!

Bin ziemlicher Noob bezüglich Arduino und sketch.
Habe ein Mega2560 welches zwei DS18B20 ausliesst. Bei einer bestimmten
Temperatur (die von 3W LEDs)schaltet das Relais den Strom für die LEDS
ab. Funktioniert prima, nur schalten die Relais bei der selben Temp
wieder ein. Das ist zu kurz zum abkühlen der LEDs / Kühlkörper.
Also Beispiel: Bei >50 Grad Celsius schaltet das Relais die LEDs aus.
Sobald die Temp unter 50 Grad ist schalten die Relais gleich wieder ein,
nun dauert es nicht lange bis die LEDs wieder zu warm werden und das
Relais schaltet. Ich möchte dass sie wenigstens auf Bsp: 40 Grad
absinken....

Die LEDs bitte nicht verwechseln: Die 3Watt LEDs sind blau und grün.
deren Temp wird über je eine blaue und rote LED angezeigt...

Der Sketch im Anhang.
und hier:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>


LiquidCrystal lcd(49, 48, 39,40,41,42,43,44,45,46,47);

int blueBLED = 27;   // Temperatur für blaue LEDs ok
int blueRLED = 28;   // Temperatur für blaue LEDs zu hoch
int greenBLED = 29;  // Temperatur für grüne LEDs ok
int greenRLED = 30;  // Temperatur für grüne LEDs zu hoch

// Datenkabel der Sensoren auf Pin 9 vom Mega
#define ONE_WIRE_BUS 50

// ONEwire bus _ alle Sensoren - ein Kabel
OneWire oneWire(ONE_WIRE_BUS);

// Signal an Dallas übergeben 
DallasTemperature sensors(&oneWire);

// Adressen der Sensoren

DeviceAddress greenThermometer = { 0x28, 0xCF, 0x95, 0xCD, 0x04, 0x00, 0x00, 0xFA};
DeviceAddress blueThermometer = { 0x28, 0xF9, 0x4E, 0xCB, 0x04, 0x00, 0x00, 0x82 };

int blue = 31; // Output für Relais1 - IN1
int green = 32; // Output für Relais2 - IN2

float bluetemp = 0;
float greentemp = 0;

void setup(void)
{
  // Start Sensoren
  sensors.begin();
  // 10bit Auflösung
  sensors.setResolution(blueThermometer, 10);
  sensors.setResolution(greenThermometer, 10);
  
  
  // PINs von LEDs für Überwachung Temperatur als Ausgang setzen
  pinMode(blueBLED, OUTPUT); 
  pinMode(blueRLED, OUTPUT);
  pinMode(greenBLED, OUTPUT);
  pinMode(greenRLED, OUTPUT);
  
  // alle LEDs einschalten - Funktionstest
  digitalWrite(blueBLED, HIGH); 
  digitalWrite(blueRLED, HIGH);
  digitalWrite(greenBLED, HIGH);
  digitalWrite(greenRLED, HIGH);
  delay(2000);
  
  //Display Hintergrundbeleuchtung ein
  pinMode(38, OUTPUT);
  digitalWrite(38,HIGH);

lcd.begin(20,4); 
lcd.clear(); 
lcd.setCursor(3,0);
lcd.print("Welcome to my");
delay(2000);
lcd.setCursor(2,1);
lcd.print("infintiy mirror");
lcd.setCursor(3,2);
lcd.print("microprocessor");
lcd.setCursor(5,3);
lcd.print("controlled");
delay(8000);
lcd.clear(); 
lcd.setCursor(1,0);
lcd.print("designed and built");
lcd.setCursor(8,1);
lcd.print("by");
lcd.setCursor(5,2);
lcd.print("MichelFibs");
delay(2000);
lcd.setCursor(4,3);
lcd.print("! have fun !");
delay(8000);
lcd.clear();

// PINS für Relais-Schalten als Ausgang setzen
pinMode(blue, OUTPUT); 
pinMode(green, OUTPUT);

}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  float t1tempC = sensors.getTempC(blueThermometer);
  float t2tempC = sensors.getTempC(greenThermometer);
  if (tempC == -127.00) {
lcd.print("000");
} else {
// lcd.print(tempC);
// lcd.print("/");
bluetemp = (t1tempC);
greentemp = (t2tempC);
lcd.print(tempC);
  }
}

void loop(void)
{ 
  delay(2000);

  sensors.requestTemperatures();
  
// Ausgabe Display  
lcd.setCursor(0,0);
lcd.print("LED  blue: ");
printTemperature(blueThermometer);
lcd.print(" 'C");

lcd.setCursor(0,1);
lcd.print("LED green: ");
printTemperature(greenThermometer);
lcd.print(" 'C");

lcd.setCursor(0,2);
lcd.print("Relais  1:");

lcd.setCursor(0,3);
lcd.print("Relais  2:");

// Schalten der Relais bei Übertemperatur
if (bluetemp >= 10 && bluetemp <= 30.9)

{
  digitalWrite(blue, HIGH);
  digitalWrite(blueRLED, LOW);
  digitalWrite(blueBLED, HIGH);
  lcd.setCursor(11,2);
  lcd.print("on ");
}

if (bluetemp >= 31)
{
  digitalWrite(blue, LOW);
  digitalWrite(blueRLED, HIGH);
  digitalWrite(blueBLED, LOW);
  lcd.setCursor(11,2);
  lcd.print("off");
}


if (greentemp >= 10 && greentemp <= 30.9)

{
  digitalWrite(green, HIGH);
  digitalWrite(greenRLED, LOW);
  digitalWrite(greenBLED, HIGH);
  lcd.setCursor(11,3);
  lcd.print("on ");
}

if (greentemp >= 31)
{
  digitalWrite(green, LOW);
  digitalWrite(greenRLED, HIGH);
  digitalWrite(greenBLED, LOW);
  lcd.setCursor(11,3);
  lcd.print("off");
}

}

Bitte um Hilfe! Habe nix vergleichbares über SUFU gefunden.

Danke

Projekt01.txt (3.53 KB)

Die Hysterese ist mit 0.1C viel zu gering!

In der if-Abfrage der gewünschten Arbeitstemperatur solltest du eine weitere Bedingung einbauen.
if(bluetemp >= 10 && blueTemp <= 30.9 && highTemp == false)

Das setzt voraus, dass du ausserhalb der Arbeitstemperaturen von >= 31, die Variable highTemp = true setzen musst.

Nun kommt im loop noch eine weitere Abfrage hinzu.

if(highTemp == true && bluetemp < 25) highTemp = false; // Schaltet highTemp erst zurück, wenn Temp wieder unter 25°C gefallen ist.

P.S.: Bzgl. SuFu. Die Schlagworte wären hierbei z.B. "Heizung" + "Hysterese"

Das ganze nennt man "Hysterese" : du brauchst einen Bereich in dem alles so bleibt wie es ist.
Kalt ( <30.9 ): ein
Heiss ( > 31.0 ) : aus
dazwischen nichts machen: ein bleibt ein, aus bleibt aus.

Das hast du alles schon, nur ist der Bereich zwischen 30.9 und 31.0 bei dir etwas klein.

(Stefan war schneller)

Vielen Dank Euch...
Das mit der Hysterese habe ich so nicht bedacht, da das Thema für mich neu ist....

Wäre perfekt... Dann probiere ich das mal so....
Diese 31 grad waren nur Test für "handwarm einschalten"
Später denke ich das ab 50 Grad das Relais schaltet und bei 35 vllt wieder aus....

Habe es jetzt folgendermaßen:
Hoffe alles richtig.....

// Schalten der Relais bei Übertemperatur

if (bluetemp <=35)
{
  digitalWrite(blue, HIGH);  //Relais an, blaue LED haben Strom
  digitalWrite(blueRLED, LOW); //Anzeige Hochtemperatur aus
  digitalWrite(blueBLED, HIGH); // Anzeige Normaltemperatur an
  lcd.setCursor(11,2);
  lcd.print("on "); 

if (bluetemp >= 35,1 && bluetemp <= 50)

{
  // Relais hier rausgenommen
  digitalWrite(blueRLED, LOW); // Anzeige Hochtemp aus
  digitalWrite(blueBLED, HIGH); //Anzeige Normaltemp an
 
}

if (bluetemp >= 50,1)
{
  digitalWrite(blue, LOW); //Relais aus, blaue LED ohne Strom
  digitalWrite(blueRLED, HIGH); // Anzeige Hochtemperatur an
  digitalWrite(blueBLED, LOW); // Anzeige Normaltemperatur aus
  lcd.setCursor(11,2);
  lcd.print("off");
}

Das Gleiche dann für die Steuerung der grünen LEDs.

Schon mal daran gedacht die LEDs zu dimmen könnte ja die LEDs anfangen zu dimmen wenn die Temperaturen zu hoch werden einem gewissen Rahmen ist das auch gut vertretbar bezüglich helligkeit.
Gruß
Der Dani

Die LEDs sollen bei gleichbleibender Helligkeit mehrere Seitenlichtfasern beleuchten. Darum brauche ich volle Leistung. Angeschlossen sind sie an eine Konstantstromquelle deren 230V-Zugang vom besagten Relais gesteuert wird....

Habe schon einen Trockenlauf durch. Nach 6h Dauerstrom konnte ich die Kühlkörper gerade noch anfassen. Diese Steuerung dient dazu im Notfall bei zu hoher Temperatur die LEDs abzuschalten, da alles versteckt verbaut wird und ich einen Hitzestau oder ähnliches nicht mitbekomme. Die Umgebungstemperatur wird evtl auch noch gemessen....

Wird dann nur etwas aufwendiger die ganze Sache anzusteuern (einfacher als ein Relais last anzuklemmen kenn ich nicht ;))

Wäre aber defenitv mal ein Gedanke für die nächste Version. -> Arduino IRLZ44

Seitenlichtfasern werden auch bei einem PWM Wert von ~200 gut ausgeleuchet. Hast du bedenken, dass du überhaupt die MaxTemps anfahren kannst, oder geht es hier um eine reine Sicherheitsmaßnahme?

Was meinst du mit AUFWENDIGER???

Ja nur eine Sicherheit bezüglich der Überhitzung, das Relais soll nicht wirklich die LEDs immerzu ein oder ausschalten. Nur im Notfall da ich an die Kühlkörper und LEDs nicht mehr rankomme wenn alles verbaut ist....

Habt ihr euch den neuen Code mal angesehen? Ist der bezüglich Hysterese und entsprechender Relaisschaltung so okay?

Ne, ist falsch. Und es muss für eine Fließkommzahl ein "." sein, NICHT "," Den Lösungsweg habe ich ganz oben bereits beschrieben, dahingehend hast du es falsch beisammen geschrieben.

P.S.: Der Mega ist vermutlich sowas von überladen für das Projekt.

Hallo,
"Nach 6h Dauerstrom konnte ich die Kühlkörper gerade noch anfassen."

Dann wird der Kühlkörper so um die 40 bis 60° haben. Das ist kein Problem.
Du mußt nur dafür Sorge tragen, das die warme Luft abgeführt wird. Dann kommt
es auch zu keinem Wärmestau.
Du kannst ja mal einen Deiner Sensoren an den Kühlkörper klemmen (Wäscheklammer)
und die Temperatur messen.
Dann wäre ein Blick in Datenblatt nicht schlecht. Es ist gut möglich, das Du
durch Deine "an/aus schalterei" Deinen LED´s eine zu kurze Lebenszeit gönnst.
Die haben eine ganz bestimmte Spezifikation was die Wärme- und das Schalten angeht… Ich kann mit nicht vorstellen, das es gut ist, die LED´s auf Betriebs-
temperatur zu bringen- um sie dann wieder abkühlen zu lassen- um sie wieder
auzuheizen.
Gruß und Spaß dabei
Andreas

klar ein Punkt. Sorry...

Und ohne Kommastelle? Funktioniert das?:

// Schalten der Relais bei Übertemperatur

if (bluetemp <35)
{
  digitalWrite(blue, HIGH);  //Relais an, blaue LED haben Strom
  digitalWrite(blueRLED, LOW); //Anzeige Hochtemperatur aus
  digitalWrite(blueBLED, HIGH); // Anzeige Normaltemperatur an
  lcd.setCursor(11,2);
  lcd.print("on "); 

if (bluetemp >= 35 && bluetemp <= 50)

{
  // Relais hier rausgenommen
  digitalWrite(blueRLED, LOW); // Anzeige Hochtemp aus
  digitalWrite(blueBLED, HIGH); //Anzeige Normaltemp an
 
}

if (bluetemp > 50)
{
  digitalWrite(blue, LOW); //Relais aus, blaue LED ohne Strom
  digitalWrite(blueRLED, HIGH); // Anzeige Hochtemperatur an
  digitalWrite(blueBLED, LOW); // Anzeige Normaltemperatur aus
  lcd.setCursor(11,2);
  lcd.print("off");
}

Wie würde der Code bezüglich HighTemp (true & false) aussehen? bin da gerade nicht klar im Kopf...
Und HighTemp muss ich doch dann noch freigeben, oder? Also ich meine: float HighTemp = 0

SkobyMobil:
Dann wird der Kühlkörper so um die 40 bis 60° haben. Das ist kein Problem.
Du mußt nur dafür Sorge tragen, das die warme Luft abgeführt wird. Dann kommt
es auch zu keinem Wärmestau.

Soll ja nicht Sinn sein die LEDs immer zu schalten. Wie erwähnt, nur eine Sicherheit. Die Wärme wird von vornherein über Lüfter abgeführt. Und ich denke schon dass nix zu heiss wird allgemein. Will nur auf Nummer sichererer gehen...

sschultewolter:
Ne, ist falsch. Und es muss für eine Fließkommzahl ein "." sein, NICHT "," Den Lösungsweg habe ich ganz oben bereits beschrieben, dahingehend hast du es falsch beisammen geschrieben.

P.S.: Der Mega ist vermutlich sowas von überladen für das Projekt.

Würdest du mir helfen bezüglich des Codes und der "HighTemp" - Setzung in true und false?

Der Mega überladen bezüglich Strom? Nun ja, Strom für die Relais welche insgesamt sogar fünf werden kommt von extern. Der Mega versorgt nur die Optokoppler und er versorgt das LCD. Mehr nicht.... Was bisher auch gut funktioniert hat in den Tests.

Ja, es geht ohne Kommastellen. Sind im Sketch völlig unnötig.

Edit: Ich meine nicht strommäßig überladen. Das ist soweit schon in Ordnung mit den Optokopplern und der eigenen Masse.
Die Aufgaben, die hier dein Arduino leisten muss, ist mehr als Ausreichend für den Uno. Pins solltest du selbst bei dem Uno noch genug freihaben. Ansonsten an das LCD Panel eine I2C-Backplatine anschließen. Dann brauchste auf dem UNO nur noch 2 Datenpins für das Display.

Ansonsten solltest du den Sketch noch ordentlich ausarbeiten. Vermeide delays() im späteren Aufbau und lasse mit Hilfe von dem Tutorial "Blink Without Delay" (millis() Funktion), die Werte jede Sekunde wieder neu aufs Display schreiben, oder besser noch, erst dann, wenn sich hier ein Wert geändert hat.

/* Globale Variabeln */
boolean blueTempHigh = true; // Nach einem Neustart muss die Temperatur einmal unter 35°C sein
/* Ende Globale Variablen */


/* loop */
//[...]
// Schalten der Relais bei Übertemperatur
if (bluetemp < 35)
  // Sicherer Bereich, Rücksetzbedingung für einwandfreie Led-Temperatur
{
  digitalWrite(blue, HIGH);  //Relais an, blaue LED haben Strom
  digitalWrite(blueRLED, LOW); //Anzeige Hochtemperatur aus
  digitalWrite(blueBLED, HIGH); // Anzeige Normaltemperatur an
  lcd.setCursor(11, 2);
  lcd.print("on ");
  blueTempHigh = false; // Wenn die Temperatur < 35°C beträgt, wird die Bedingung zurückgesetzt
}
else if (bluetemp >= 35 && bluetemp < 50 && blueTempHigh == false)
  // Wird nur ausgeführt, wenn die Temperatur noch nicht 50+ °C gestiegen ist,
  // falls doch, wird erst bei einer Temperatur von < 35°C wieder eingeschaltet
{
  // Relais hier rausgenommen
  digitalWrite(blueRLED, LOW); // Anzeige Hochtemp aus
  digitalWrite(blueBLED, HIGH); //Anzeige Normaltemp an
}
else
  // Temperatur zu hoch. Merker wird gesetzt, solange Temperatur nicht unter <35°C fällt
{
  digitalWrite(blue, LOW); //Relais aus, blaue LED ohne Strom
  digitalWrite(blueRLED, HIGH); // Anzeige Hochtemperatur an
  digitalWrite(blueBLED, LOW); // Anzeige Normaltemperatur aus
  lcd.setCursor(11, 2);
  lcd.print("off");
  blueTempHigh == true
}
//[...]

/* Ende loop() */

Habe mir aufgrund der vielen Pins und der Möglichkeit von größerem Sketch vom Mega diesen extra geholt und gegen den UNO eingetauscht. Die Sache mit I2C Display ist gut, danke. Werde ich überlegen.

Danke für den Code... werde es entsprechend ausbauen...

So einfach kommste nicht an die Sketchgrößenbegrenzung heran, solange du keine grafischen Displays anstatt der Charakterdisplays nutzt. Habe bislang erst ein Projekt, bei dem ich vom Flash/RAM nicht mehr mit dem Uno fahren kann. Dabei sind es aber ein ganzer Haufen an Seiten auf einem grafischen Display dargestellt, sowie Lichtersteuerung (WS2812B), Flugsensorik, Serielle Schnittstelle (XBee RF Module mit ~1,2km Reichweite) uvm.

okay.... ja, stimmt auch, hatte einiges mit 'nem Grafikdisplay experimentiert, da waren fix 40Kbyte voll.
War auch der Meinung das der Mega2560 v3 bissl fixer ist, darum wollte ich diesen Controller lieber haben...