Arduino Nano hängt sich im Dauerbetrieb auf

Hallo Arduinofreunde,
Für ein Projekt benötige ich einen Arduino, der mit 24/7 die Luftfeuchte in einem Raum steuert. Dafür habe ich einen Arduino Nano, sowie ein zwei Relais genommen, von denen eines den Befeuchter und eines den Trockner steuert. Die Feuchte und Temperatur misst ein DHT 22. Den aktuellen Status zeigt ein 16x2 I2C Display.
Das Ganze funktioniert auch echt super, allerdings hat sich der Arduino bis jetzt immer nach 2-8 Stunden aufgehängt. Das Display zeigte dann "Trockn" bzw. einmal "Haltenung", was mich darauf schließen lässt, dass sich der Arduino irgendwie beim Schreiben auf das LCD aufgehängt hat. Die Relais blieben dann jeweils auch in dem zuvor eingestellten Zustand bis ich den Ausfall bemerkte.

Ich habe hier schon ein wenig gesucht, aber nichts gefunden, was mich groß weiter gebracht hätte... Vielleicht hatte ja schon einmal jemand einen ähnlichen Fall und kann mir einen Tipp geben, wie ich das lösen kann?

Beste Grüße und vielen Dank!
Moritz


#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHTPIN 2        //Pin vom Feuchtesensor
#define DHTTYPE DHT22   // DHT 22  (AM2302)

int Befeuchtung = 6;         //BEfeuchtung an PIN  6
int Trocknung = 7;          //Trocknung an Pin 7
int Zielfeuchte = 50;       //Zielfeuchte in %
int Toleranz = 2;           //Hysterese der Feuchte in %
unsigned long Wartezeit = 60;         //Zeit zwischen Messungen in Sekunden
unsigned long Zyklus1 = 250;
unsigned long Zyklus2 = 750;
float h;
float t;


DHT dht = DHT(DHTPIN, DHTTYPE);  //Feuchtesensor Konfigurieren


void setup() {
pinMode(Befeuchtung,OUTPUT);          //PINs für die Befeuchtung und Trocknung als Output definieren
pinMode(Trocknung,OUTPUT);
pinMode(LED_BUILTIN,OUTPUT);



  // Begin serial communication at a baud rate of 9600:
  Serial.begin(9600);
  // Setup sensor:
  dht.begin();


  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Initialisierung...");
}

void loop() {
  

  lcd.setCursor(0,0);
  // Read the humidity in %:
  float h = dht.readHumidity();
  // Read the temperature as Celsius:
  float t = dht.readTemperature();
  
  delay(Wartezeit*Zyklus1);
    
  lcd.print(t);                           //Feucht- und temperaturanzeige im Display
  lcd.print(" ");
  lcd.print("C");
  lcd.print(" - ");
  lcd.print(h);
  lcd.print("%");
    


  
  if (isnan(h) || isnan(t)) {
    lcd.setCursor(0,0);
    lcd.println("Messfehler!");           //Falls kein Wert vom Feuchtesensor kommt neue Messung und Alle Pins low
    digitalWrite(Befeuchtung, LOW);
    digitalWrite(Trocknung, LOW);
    return;
  }

  
  lcd.setCursor(0,1);

  if(h < (Zielfeuchte-Toleranz)){         //Befeuchtung
    digitalWrite(Befeuchtung, HIGH);
    digitalWrite(Trocknung, LOW);
    lcd.print("Befeuchtung");
  }

if(h >= (Zielfeuchte-Toleranz)&& h <= (Zielfeuchte+Toleranz)){       //HAlten
  digitalWrite(Befeuchtung, LOW);
  digitalWrite(Trocknung, LOW);
  lcd.print("Halten     ");
}

  
  if(h > (Zielfeuchte+Toleranz)){             //Trocknung
    digitalWrite(Trocknung, HIGH);
    digitalWrite(Befeuchtung, LOW);
    lcd.print("Trocknung     ");
  }

delay(Wartezeit*Zyklus2); 
 
  
 
}```
  • Verkabelung richtigstellen, I2C Grenzen einhalten.
  • Code richtigstellen

Wenn du mehr Tipps braucht es:

  • Schaltplan
  • Links zu den Komponenten die du verbaut hast
  • Echtbilder vom Aufbau worauf JEDE Komponente und dessen Verkabelung ersichtlich ist
  • Vollständiger Code - oder ein minimaler kompilierbarer Code der den Fehler zeigt. STRG-T drücken in der IDE könnte und Leerzeilen maßvoll einsetzen könnte auch helfen

Was genau schaltest du mit den Relais ?
Ich vermute, dass du da Störungen produzierst, die den Absturz auslösen.

Danke schonmal für die Antworten.
Bilder und einen Schaltplan versuche ich morgen zu machen.
Den Code übersichtlicher zu machen muss ich mir für die Zukunft merken. Das mit dem STRG+T wusste ich noch gar nicht. Danke für den Tipp.
Die Kabel sind alle in einem wasserdichten Gehäuse und alle Kabel vom Arduino sind 0,14 mm² Kupferleitungen. Die Längen sind sehr gering, ich vermutete daher bis jetzt dass es für das I2C kein Problem sein sollte.
Das mit den Störungen könnte allerdings tatsächlich ein Problem sein. Durch die Bauweise in der Box sind die Netzkabel schon zum Teil dicht an den Kabeln am Arduino. Das ist vermutlich problematisch. Nach dem, was auf dem Display zu lesen ist nach dem einfrieren liegt auch nahe, dass der Ausfall immer gerade im Moment des schaltens eines Relais passiert.
Aktuell ist nur ein Luftentfeuchter in Verwendung:

Aus dem Datenblatt des DHT22: https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf :
Accuracy humidity: +-2%RH(Max +-5%RH); at temperature <+-0.5Celsius
Repeatability humidity: +-1%RH; at temperature +-0.2Celsius
Humidity hysteresis: +-0.3%RH
Long-term Stability: +-0.5%RH/year

Und mit so einem Sensor willst Du eine Luftfeuchtigkeit mit einer Hysterese von 4% RH zusammenbekommen???
Dazu ist die Messung der Luftfeuchtigkeit viel zu ungenau.

Das sind dann nicht Sekunden sondern Millisekunden. Also 15000 Millisekunden aka 15 Sekunden.

Also bei h < 48,0 % Befeuchten.

Also bei h > 52,0% Trocknen

also bei h >= 48,0% und <= 52,0 % Trockner und Befeuchter ausschalten.

Das ist eine Schalthysterese con 0,1%HR :
52,1%RH Trockner ein, 52,0%RH Trockner aus
47,9%RH Befeuchter ein, 48,0%RH Befeuchter aus.

Was hat dieses doppelte delay im loop() für einen Sinn?

also mal 15 Sekunden und dann 45 Sekunden.

Ich würde die Luftfeuchtigkeit viel öfter messen und einen Durchschnitt über mehrere Minuten errechen und diese für die Steuerung verwenden.
Ich weiß jetzt nicht nach welchen Prinzip der Luftentfeuchter funktioniert. Kann der jede zweite Minute aus und wieder Eingeschaltet werden? oder müssen da Totzeiten Eingehalten werden damit dieser nicht vorzeitg Kaputtgeht?

DIe Logik bzw Funktionsweises dieses Sketches ist einfach falsch.

Grüße Uwe

Hallo Uwe,
Vielen Dank für die ausführliche Beschäftigung mit dem Sketch und die vielen Hinweise.
In der Tat ist die Regelung mit der Genauigkeit des DHT wohl ambitioniert. Wie genau der Absolute Messwert ist konnte ich in einer kalibrierten Klimakammer vorab prüfen, die Abweichung lag bei etwa +2% RH. Das muss man natürlich einrechnen in den Zielwert.
Für die Regelung ist meines Erachtens aber eher wichtig, wie weit zwei aufeinander folgende Messungen voneinander Abweichen und das scheint zumindest bei meinem Sensor ganz akzeptabel zu sein. Ich habe parallel einen Luftfeuchtelogger mitlaufen lassen und im Ergebnis sieht die Regelung, wenn sie funktioniert, ganz gut aus. Ich kann morgen ein Bild des Feuchteverlaufes posten.

Das ganze war so gedacht, dass man die Zeit oben benutzerfreundlich in Sekunden eingibt und sie im Folgenden entsprechend in Millisekunden umgerechnet wird.

Der Sinn war, dass ich ein Delay natürlich brauche um die Länge eines Regelzyklus einzustellen, allerdings brauche ich auch ein delay, da der Sensor fehlerhafte Werte oder keine Werte ausgibt, wenn zu oft abgefragt. Zweiteres Delay hatte ich erst zu kurz gewählt, daher ist es jetzt auf 1/4 des Regelzyklus verlängert, da die genaue Dauer meines erachtens nach da unerheblich ist.

Ansonsten ist das so wie du es geschrieben hast. Über die Schalthysterese habe ich bis jetzt nicht wirklich nachgedacht aber es stimmt natürlich, dass 0,1% da knapp sein könnte. Die Gefahr wäre ja, dass viel zu viel geregelt wird, wenn man sich an der Grenze bewegt. Das war bis jetzt allerdings noch nicht der Fall. Ich muss da aber ein Auge drauf haben.

Das ist eine sehr gute Idee, das werde ich versuchen, umzusetzen. Ich glaube allerdings, dass das Problem des Einfrierens dadurch nicht gelöst wird, wohl aber andere Probleme.

Der Entfeuchter sollte das häufige Ein- und Ausschalten hoffentlich aushalten, jedenfalls hat der Händler das behauptet.

Beste Grüße
Moritz

Da gebe ich Dir vollkommen recht. Auch ich glaube daß es Störungen sind die von den Relais kommen, die den Arduino abstürzen lassen.

Grüße Uwe

Genau hier liegt dein Problem des Absturzes.

Das ganz sicher nicht.
Du wirst Störstrahlungen deiner 230V-Verbraucher haben und musst die 230-Volt-Verkabelung konsequent von deinem Aufbau (Controller und Messung) trennen.

Moin,
vielen Dank für eure Hilfe. Das Problem ist wirklich die Störung durch die 230V Verkabelung. Konkret wird scheinbar die I2C Verbindung gestört.
Ich konnte das Problem vorerst lösen, indem jetzt zuerst das Display beschrieben wird und anschließend nach einem kurzen Delay erst das jeweilige Relais geschaltet wird. Seit 48 Stunden läuft es nun, hoffentlich bleibt das auch so. Sollte es nochmal Probleme geben, werde ich die 230V Kabel von den anderen Kabeln trennen.

Beste Grüße
Moritz

In der Digitaltechnik ist das ein schlechter Weg, zu hoffen, dass sich nichts ändert.
Besser ist es, von Anfang an, die Fehlerquellen zu beseitigen.
Bei dir braucht sich nur ein Parameter zu ändern und dein Problem ist wieder präsent.
Dann bist du ewig nur am nachbessern.

Ich möchte nicht wissen, was Du da hast, aber rein vorsorglich: Es gibt Regeln, wie so Drähte und Kabel zu trennen sind...