Temperatursteuerung

Hallo zusammen,

ich habe für unseren Wintergarten eine Temperatursteuerung gebaut. Ich hatte dafür schon einige Hilfe aus diesem Forum, da es jetzt aber um andere Probleme geht, beginne ich einen neuen Post. Der Weg hierher ist hier dokumentiert.

Meine Schaltung sieht wie folgt aus:

Hier noch einige Bilder vom Bau, bis zum fertigen Gehäuse:

Mein Sketch sieht momentan wie folgt aus:

/*
=====================================================================================================
Temperatursteuerung mit Arduino Nano, HD44780 20x4, DS18S20 Tempertursensor, zwei Buttons und Relais
=====================================================================================================

Code erstellt nach folgenden Tutorials:

https://deloarts.wordpress.com/2016/03/14/get-temperature-via-ds18b20/
https://www.arduino.cc/en/Tutorial/InputPullupSerial
https://www.arduino.cc/en/Tutorial/LiquidCrystalDisplay
https://forum.arduino.cc/index.php?topic=423688.0

=====================================================================================================
*/

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

LiquidCrystal lcd(7,8,9,10,11,12);

#define ONEWIRE_BUS 4

OneWire oneWire(ONEWIRE_BUS);
DallasTemperature oneWireSensors(&oneWire);

//Gehört zur Temperatur messung
int ActualTemp;
byte Devices = 0;
byte Address[8];

// Konstanten für Buttons
const int TempUp = 3;        // Pin für TempUp Button
const int TempDown = 2;     // Pin für TempDown Button
const int maxTemp = 25;     // SetTemp max Limit
int SetTemp = 18;         // Standard SetTemp
int interval = 1;        //  Erhöhungs intervall für SetTemp

const int relaisPin = 13;     // Pin für Relais

unsigned long temp_timestore;   // Variable Speicher für Systemzeit.


 
void setup()
{
//Display initialisieren

    lcd.begin(20,4);  

// Button Pins initialisieren

    pinMode(TempUp, INPUT_PULLUP);
    pinMode(TempDown, INPUT_PULLUP);
    
// One wire Module finden

      oneWireSensors.begin();
    while(oneWire.search(Address)) 
        Devices++;
    for (byte i = 0; i < 40; i++)




// Statischer Text  

    lcd.clear();
    
    lcd.setCursor(0,0);
    lcd.print(String("Temperature control"));
   
    lcd.setCursor(0,2);
    lcd.print(String("SetTemp   : " + String(SetTemp) + (char)223 + "C"));
    
    lcd.setCursor(0,3);
    lcd.print(String("    Initializing"));
}



void loop()
{

 //##################### Temp auslesen #######################################

 // Temperatur Sensor auslesen; getTempCByIndex(0) => Index 0 entspricht erstem gefundenem Sensor


  if (millis() - temp_timestore> 10000 ) {       //Interval für Temp auslesen
    
  
    oneWireSensors.requestTemperatures();
    ActualTemp = oneWireSensors.getTempCByIndex(0);

// ActualTemp auf Display ausgeben

    lcd.setCursor(0,1);
    lcd.print(String("ActualTemp: " + String(ActualTemp) + (char)223 + "C"));


//########################## Relais schalten ###############################################

     if (SetTemp > ActualTemp){
        digitalWrite(relaisPin, LOW);
        
            lcd.setCursor(0,3);
    lcd.print(String("      Heating      "));
      }
      
      if (SetTemp < ActualTemp){
        digitalWrite(relaisPin, HIGH);

            lcd.setCursor(0,3);
    lcd.print(String("Temperature reached"));
    


    temp_timestore = millis();   //Aktuelle Systemzeit speichern für nächsten Interval

  }


//######################  Buttons überwachen  ######################################


// Wenn der TempUp Button gedrückt wird, erhöhe die SetTemp um 1

      if (digitalRead(TempUp) == LOW && SetTemp < maxTemp){ 
        SetTemp = SetTemp + interval; 

        lcd.setCursor(0,2);
        lcd.print(String("SetTemp   : " + String(SetTemp) + (char)223 + "C"));
      

      }
// Wenn der TempDown Button gedrückt wird, erniedrige die SetTemp um 1

       if (digitalRead(TempDown) == LOW && SetTemp > 0){
         SetTemp = SetTemp - interval;
      
         lcd.setCursor(0,2);
         lcd.print(String("SetTemp   : " + String(SetTemp) + (char)223 + "C"));
      
      }
      
//Verzögerung stellt empfindlichkeit der Buttons ein. Zu keiner Wert hat zu doppelklicks geführt

    delay(300);  


  }     
}

Nun aber zu meinem Problem. Wenn ich die Steuerung einschalte, läuft sie so wie es mir vorstelle. Nach kurzer Initialisierung, startet die Messung und die Temperatur wird über das Relais und eine elektrische Heizung gesteuert.
Aber dann passiert es, nach kurzer Zeit, dass das Relais unkontrolliert schaltet, das Display zeigt die aktuelle Temperatur nicht mehr an, oder auch gar nichts mehr... Ich habe dann auch keinen Zugriff mehr auf den Nano. Ein uploaden ist dann nicht mehr möglich. Nach einigen Stunden, ohne Strom, geht es dann aber wieder! Der Fehler passiert, ob ich den Nano über USB versorge, oder über den 5V pin gleichermassen.
Dieses Verhalten irritiert mich, da es so unreproduzierbar ist. Ich weiss einfach nicht wo ich da mit Fehlersuche ansetzen soll. Ich frage mich halt, ob ich in dem Sketch einen Fehler habe, der dies erklären würde, finde aber nichts...

Ich habe, wie ihr seht, den Nano direkt auf eine Platine gelötet. Kann es sein, dass ich ihn dabei "gegrillt" habe? Die Lötstellen habe ich alle durchgemessen, es liegt kein Kurzschluss vor.

Ich hoffe euch fällt etwas auf. Wenn es hilft, kann ich auch mal ein Video machen.

Grüße,
Torsten

drdrhase:
... Aber dann passiert es, nach kurzer Zeit, ...

... unreproduzierbar ...

Deine Beschreibung klingt für mich eher nach „reproduzierbar“, aber Du schreibst, dass das Fehlverhalten nicht reproduzierbar sei.

Wie isses denn nu?

Wenn es nicht reproduzierbar ist: Ach du Scheiße, sowas liebe ich ja ...

Als einen Schuss ins Blaue würde ich den Nano auslöten und sockeln, dann mit unterschiedlichen Temperaturen (Kältespray, Fön) probieren, ob sich das Fehlverhalten provozieren lässt.

Gruß

Gregor

Der Nano liefert nicht genung Strom und überhitzt. Ist also alles reproduzierbar. Nach der Stunde ohne Strom ist der abgekühlt und funktioniert ne zeitlang wieder.
Entweder das Display dimmen (Widerstand davor) oder extra Versorgung fürs Display.

Ich stimme meinen Vorredner zu, vermutlich wird der Regler im Arduino überlastet.
Leider lässt sich deine Verkabelung nicht richtig verfolgen, um das zu bestätigen.

Allerdings solltest du für einen Festeinbau keine Jumperkabel zur Verbindung einzelner Module verwenden.

Diese billigen Steckverbinder sind sehr anfällig und danken es dir mit schlechten Kontakten.
Also alle Kabelverbindungen sauber löten oder mit richtigen Steckverbinder arbeiten.

Dann werden die Probleme weniger.

Mir ist unwohl wie nah bei dir 230V-Teil und Niederspannungsteil ganz speziell im Bereich der Lüsterklemme zusammen liegen. Was ist das so ein rotes Käbelchen an der Lüsterklemme? Falls nicht gemacht, sollten Kabelhülsen in den Klemmen verwendet werden. Ist die Zugentlastung ausreichend?

Es sollte möglichst Phase (Braun) geschaltet werden. Wenn du den Neutralleiter schaltest, liegen die Geräte abgeschaltet auf Netzpotential. Wenn das Gerät an einer Steckdose betrieben wird, sollte zweiphasig geschaltet werden.

Auch noch als Fehlerursache wären Störungen durch Impulse beim Schalten des 230V-Verbrauchers denkbar. Teilweise berühren sich ja 230V und Signalleitungen. Die langen Leiterbahnen auf der Streifenrasterplatine könnten als Antennen wirken. Passieren die Ausfälle auch, wenn das Gerät vom Netz getrennt betrieben wird?

Nachtrag: Das eine Platinchen in der Mitte ist wohl ein USB-Netzteil. Wie viel Strom kann es liefern? Wenn du einfach ein Usb-Kabel in den Nano steckst, hast du eine Doppelversorgung, die weder dem USB-Netzteil als auch dem Computer am USB-Anschluss gut tut. Die Doppelversorgung muss vermieden werden.

Erst mal ausschliessen was es nicht sein kann:

Der Arduino Spannungsregler kann NICHT überhitzen. Du versorgst den Nano direkt mit 5V, der Spannungsregler des Nano wird also garnicht verwendet.

Ein IRLZ44N ist KEINE Alternative für ein Relais, wenn du 230V AC schaltest.

Was kann sein:
Überlastung des 5V Reglers.
Softwareproblem: vielleicht ein Speicherüberlauf?
HW-Störungen: Abschaltpulse des Relais oder der Heizung, die den Arduino stören.

Was du prüfen solltest:

  • Ist das Verhalten abhängig vom Aufbau, also im Gehäuse oder extern. Falls ja, könnten es Störungen sein. Abhilfe: sauberes trennen der Leitungen, ggf abschirmen.
  • Wird irgendetwas warm? (Heiss) Zuviel Strom bzw. zu wenig Leistung. ggf Kurzschluss
  • über Serial.print Speicherverbrauch ausgeben lassen.

Was du unbedingt ändern solltest:
Nimm ein 2-poliges Relais und schalte zweiphasig ab.
Wenn du nur ein Kabel abschaltest hast du, je nach dem, wie rum der Stecker in der Steckdose steckt, auch im abgeschaltenen Zustand die 230V anliegen. Als Lebenserhaltende Massnahme empfehle ich dir dringend, beide Drähte (braun und blau) über je ein Relais zu schalten.

Noch was zum code:

   for (byte i = 0; i < 40; i++)




// Statischer Text 

    lcd.clear();

Hier löscht du 40mal die Anzeige. ??????

Du schaltest immer mit dem Vergleich SetTemp zu ActualTemp, ohne Hysterese. Da wird dazu führen, dass alle 10sek geschalten wird. Baue eine Hystere ein.

Die Button Abfrage steht in der 10sek Schleife mit drin. Du fragst also nur alle 10sek die Buttons ab.

gregorss:
Deine Beschreibung klingt für mich eher nach „reproduzierbar“, aber Du schreibst, dass das Fehlverhalten nicht reproduzierbar sei.

Wie isses denn nu?

Wenn es nicht reproduzierbar ist: Ach du Scheiße, sowas liebe ich ja ...

Als einen Schuss ins Blaue würde ich den Nano auslöten und sockeln, dann mit unterschiedlichen Temperaturen (Kältespray, Fön) probieren, ob sich das Fehlverhalten provozieren lässt.

Gruß

Gregor

Es ist so, das dies nicht immer in der gleichen Reihenfolge passiert. Manchmal reagiert es auch nur nicht mehr auf die Buttons. Daher habe ich unreproduzierbar geschrieben.

skorpi08:
Der Nano liefert nicht genung Strom und überhitzt. Ist also alles reproduzierbar. Nach der Stunde ohne Strom ist der abgekühlt und funktioniert ne zeitlang wieder.
Entweder das Display dimmen (Widerstand davor) oder extra Versorgung fürs Display.

So etwas in der Richtung hatte ich überlegt. Aber ich habe das USB Netzteil, mit der Platine verlötet. Und zwar so, dass ich alle 5V Verbraucher, also Nano, Display und Relais davon direkt gespeist werden. Tangiert den Nano das dann überhaupt?

kulturbereicherer:
Warum kein I2C Modul am LCD? Dann sind es total nur noch 4 Kabel

Messe doch mal wie viel mA die externen Sachen ziehen und ob das Netzteil und vor allem der kleine Arduino das wirklich liefern können. Gerade die Relay Sachen sollten extern extra Strom erhalten.

Als Relayalternative ist vielleicht ein IRLZ44N was für dich. Da gibt es dann auch Codebeispiele wo bei den Lüftern auch die Drehzahl berücksichtigt wird.

Dein Code ist nicht identisch mit den Fotos. Wollte schon anmerken warum Deutsch und Englisch vermischt, aber Temperatursteuerung und Wintergarten tauchen im Code nicht auf.

Ich hatte das Display schon vor gut 15 Jahren gekauft. Da wusste ich noch nichts von I2C...

Messen ist ne gute Idee, interessiert mich jetzt auch, was die verbrauchen. Hätte halt nicht erwartet das es so viel ist.

Das mit dem IRLZ44N verstehe ich nicht. Der kann doch keine 230V AC schalten, oder verstehe ich da was falsch?

HotSystems:
Ich stimme meinen Vorredner zu, vermutlich wird der Regler im Arduino überlastet.
Leider lässt sich deine Verkabelung nicht richtig verfolgen, um das zu bestätigen.

Allerdings solltest du für einen Festeinbau keine Jumperkabel zur Verbindung einzelner Module verwenden.

Diese billigen Steckverbinder sind sehr anfällig und danken es dir mit schlechten Kontakten.
Also alle Kabelverbindungen sauber löten oder mit richtigen Steckverbinder arbeiten.

Dann werden die Probleme weniger.

Da hast Du wahrscheinlich recht, mit den Kabeln. Ich hatte halt im Kopf, das Display irgendwann mal einfacher wieder zu verwerten.

Theseus:
Mir ist unwohl wie nah bei dir 230V-Teil und Niederspannungsteil ganz speziell im Bereich der Lüsterklemme zusammen liegen. Was ist das so ein rotes Käbelchen an der Lüsterklemme? Falls nicht gemacht, sollten Kabelhülsen in den Klemmen verwendet werden. Ist die Zugentlastung ausreichend?

Es sollte möglichst Phase (Braun) geschaltet werden. Wenn du den Neutralleiter schaltest, liegen die Geräte abgeschaltet auf Netzpotential. Wenn das Gerät an einer Steckdose betrieben wird, sollte zweiphasig geschaltet werden.

Auch noch als Fehlerursache wären Störungen durch Impulse beim Schalten des 230V-Verbrauchers denkbar. Teilweise berühren sich ja 230V und Signalleitungen. Die langen Leiterbahnen auf der Streifenrasterplatine könnten als Antennen wirken. Passieren die Ausfälle auch, wenn das Gerät vom Netz getrennt betrieben wird?

Und ich wollte erst einen kleineren Kasten kaufen. Hätte nicht gedacht, dass ich so viel Platz brauche... So kann man sich irren. Mir fehlt da ganz klar die Erfahrung.
Das "rote Käbelchen" leitet die 230V an das USB Netzteil weiter. Das kam mir auch arg dünn vor, aber es ist vom gleichen Querschnitt wie das original Kabel des Netzteils.
Die Zugentlastung habe ich mit Heißkleber realisiert. (Nicht unbedingt eine Endlösung ich weiß...)

Das mit dem Schalten der Phase, da hast Du natürlich recht. Das werde ich noch ändern.

Die Antennen Therory finde ich auch interessant, aber wie Du schon hinterfragt hast, es passiert auch wenn ich keine 230V angeschlossen habe.

Theseus:
Nachtrag: Das eine Platinchen in der Mitte ist wohl ein USB-Netzteil. Wie viel Strom kann es liefern? Wenn du einfach ein Usb-Kabel in den Nano steckst, hast du eine Doppelversorgung, die weder dem USB-Netzteil als auch dem Computer am USB-Anschluss gut tut. Die Doppelversorgung muss vermieden werden.

Ich habe ehrlich gesagt nicht überprüft wie viel das Netzteil leisten kann. Ich bin da wohl etwas blauäugig ran gegangen.
Wenn ich meinen PC abgeschlossen habe, habe ich aber immer den 230V Stecker gezogen, das USB Netzteil lief also nicht.

guntherb:
Erst mal ausschliessen was es nicht sein kann:

Der Arduino Spannungsregler kann NICHT überhitzen. Du versorgst den Nano direkt mit 5V, der Spannungsregler des Nano wird also garnicht verwendet.

Ein IRLZ44N ist KEINE Alternative für ein Relais, wenn du 230V AC schaltest.

Was kann sein:
Überlastung des 5V Reglers.
Softwareproblem: vielleicht ein Speicherüberlauf?
HW-Störungen: Abschaltpulse des Relais oder der Heizung, die den Arduino stören.

Was du prüfen solltest:

  • Ist das Verhalten abhängig vom Aufbau, also im Gehäuse oder extern. Falls ja, könnten es Störungen sein. Abhilfe: sauberes trennen der Leitungen, ggf abschirmen.
  • Wird irgendetwas warm? (Heiss) Zuviel Strom bzw. zu wenig Leistung. ggf Kurzschluss
  • über Serial.print Speicherverbrauch ausgeben lassen.

Was du unbedingt ändern solltest:
Nimm ein 2-poliges Relais und schalte zweiphasig ab.
Wenn du nur ein Kabel abschaltest hast du, je nach dem, wie rum der Stecker in der Steckdose steckt, auch im abgeschaltenen Zustand die 230V anliegen. Als Lebenserhaltende Massnahme empfehle ich dir dringend, beide Drähte (braun und blau) über je ein Relais zu schalten.

Noch was zum code:

   for (byte i = 0; i < 40; i++)

// Statischer Text

lcd.clear();



Hier löscht du 40mal die Anzeige. ??????

Du schaltest immer mit dem Vergleich SetTemp zu ActualTemp, ohne Hysterese. Da wird dazu führen, dass alle 10sek geschalten wird. Baue eine Hystere ein.

Die Button Abfrage steht in der 10sek Schleife mit drin. Du fragst also nur alle 10sek die Buttons ab.

Danke für deine Tips, ich werde alles durchgehen. Vorab eine (blöde) Frage: Was ist bitte ist eine "Hysterese"?

Hysterese: Unterschied zwischen Ein- und Abschalttemperatur. Als Ein z.B. bei 15°C, Aus 16°C. Ohne Hysterese kann es zu Flattern des Relais kommen, wenn die Temperatur zwischen 14,9 und 15°C wackelt. Hier ist es nicht so dramatisch, da du eine Zwangspause von 10s hast. Da die Temperatur integer ist und du bei den Abfragen kleiner und größer ohne gleich abfragst, hast du zufällig eine Hysterese drin.

drdrhase:
Vorab eine (blöde) Frage: Was ist bitte ist eine "Hysterese"?

Und hier nachlesen. :wink:
Hysterese

Alles verlöten ist im Fehlerfall unpraktisch. Nutze wenige, aber stabile Steckverbindungen: Beispiel. Auch der Nano sollte gesockelt werden. Dafür gibt es Buchsenleisten. Ich tippe auf Wackelkontakte bei den seltsamen Fehlern. Wenn du die Schaltung extern versorgst, solltest du das interne USB-Kabel ziehen, damit nicht Teile des Netzteils mitversorgt werden.

Das Netzteil würde ich im originalen Gehäuse lassen und in eine Euro-Kupplung einstecken. Notfalls ein Euro-Verlängerungskabel zerteilen

Theseus:
Hysterese: Unterschied zwischen Ein- und Abschalttemperatur. Als Ein z.B. bei 15°C, Aus 16°C. Ohne Hysterese kann es zu Flattern des Relais kommen, wenn die Temperatur zwischen 14,9 und 15°C wackelt. Hier ist es nicht so dramatisch, da du eine Zwangspause von 10s hast. Da die Temperatur integer ist und du bei den Abfragen kleiner und größer ohne gleich abfragst, hast du zufällig eine Hysterese drin.

Das Problem mit dem "Flattern" hatte ich mir auch schon überlegt. Aber habe, wie Du schon schriebst, die 10s Pause eingebaut und das "=" vermieden. Ich dachte das wäre gut so...

for (byte i = 0; i < 40; i++)

// Statischer Text

lcd.clear();




Hier löscht du 40mal die Anzeige. ??????

Das verstehe ich ehrlich gesagt auch nicht. Wiso wirkt sich denn die Adress suche auf den nächsten Befehl aus? Fehlt da ein Simicolon hinter [...] i++)?

Und was ich mich gefragt habe ist:

Warum weiss das Programm das ich mit "const int TempUp = 3;" einen PIN des Nanos meine, aber mit "int interval = 1;" der Variable "interval" den Wert 1 zuordne?

drdrhase:
Das Problem mit dem "Flattern" hatte ich mir auch schon überlegt. Aber habe, wie Du schon schriebst, die 10s Pause eingebaut und das "=" vermieden. Ich dachte das wäre gut so...

alle 10s ein Relais mit einer hohen Last schalten geht stark auf die Lebensdauer.

drdrhase:
Das verstehe ich ehrlich gesagt auch nicht. Wiso wirkt sich denn die Adress suche auf den nächsten Befehl aus? Fehlt da ein Simicolon hinter [...] i++)?

Nur weil du da einen grossen Abstand dazwischen hast, ändert das nichts an der Zuordnung.
die Sytax lautet: for (bedingung) doAnweisung
Und nach der for-Schleife ist die nächste anweisung eben Lcd.clear.
deine for-schleife hat mir der Adresssuche oben drüber nichts zu tun.

drdrhase:
Und was ich mich gefragt habe ist:

Warum weiss das Programm das ich mit "const int TempUp = 3;" einen PIN des Nanos meine, aber mit "int interval = 1;" der Variable "interval" den Wert 1 zuordne?

Das Programm weiß erst, dass es ein Pin ist, wenn du schreibst: pinMode(TempUp, INPUT_PULLUP);

Hysterese:

if (SetTemp > ActualTemp + Hyst){
...
if (SetTemp < ActualTemp -Hyst){

mit SetTemp = 20 und Hyst = 2 schaltet er bei 18°C ein und bei 22°C wieder aus.[/quote]

drdrhase:
Manchmal reagiert es auch nur nicht mehr auf die Buttons. Daher habe ich unreproduzierbar geschrieben.

Das könnte daran liegen, dass du die Buttons nur alle 10sek abfragst.
man muss halt unter Umständen 10sek lang drücken, damit was passiert.

guntherb:
Das könnte daran liegen, dass du die Buttons nur alle 10sek abfragst.
man muss halt unter Umständen 10sek lang drücken, damit was passiert.

Aber ich habe doch die Buttons extra aus dem 10s Rhythmus raus genommen...

    temp_timestore = millis();   //Aktuelle Systemzeit speichern für nächsten Interval

  }

Beendet dieser Befehl nicht den 10s Teil?

guntherb:
Das könnte daran liegen, dass du die Buttons nur alle 10sek abfragst.
man muss halt unter Umständen 10sek lang drücken, damit was passiert.

Tatsächlich, da sind geschweifte Klammern falsch gesetzt. Die Vorletzte in der Loop sollte weg. Sie schließt den 10s-Rythmus ab.
Dafür fehlt eine vor temp_timestore = millis();  //Aktuelle Systemzeit speichern für nächsten Interval

Dadurch werden die Tasten nur alle 10s abgefragt, sobald die Temperatur ein Grad höher als die eingestellte ist. Ist sie geringer, scheint alles richtig zu laufen.

Tip1:
mit der Tastenkombination Strg + T wird dein Sketch automatisch formatiert, und man kann besser erkennen, welche Klammer wohin gehört.

Tip2:
wenn du den Cursor VOR eine öffnende geschweifte Klammer { setzt, oder HINTER eine Schliessende }, so wird die jeweils korrespondierende Klammer umrahmt.
Zwischenablage01.jpg

Tip3:
bei längeren Sketches hat es sich bewährt, hinter eine schliessende geschweifte Klammer } einen Kommentar zu schreiben, was gerade geschlossen wird.

guntherb:
Tip1:
mit der Tastenkombination Strg + T wird dein Sketch automatisch formatiert, und man kann besser erkennen, welche Klammer wohin gehört.

Tip2:
wenn du den Cursor VOR eine öffnende geschweifte Klammer { setzt, oder HINTER eine Schliessende }, so wird die jeweils korrespondierende Klammer umrahmt.

Tip3:
bei längeren Sketches hat es sich bewährt, hinter eine schliessende geschweifte Klammer } einen Kommentar zu schreiben, was gerade geschlossen wird.

Super, bin für Tips sehr dankbar!

Wäre es dann so richtig?

while(oneWire.search(Address)) {
        Devices++;
    for (byte i = 0; i < 40; i++)

}   //End oneWire search loop

was willst du denn in der for-Schleife machen?
Was soll 40 mal ausgeführt werden?
Das muss hinter die for Schleife.

Das mit dem Kommentar hinter der "}" meinte ich genau so! :slight_smile: