Code hängt sich auf, wird nicht mehr ausgeführt

Hallo Kollegen,

nutze einen Arduino Nano mit einem DHT22 um die Luftfeuchtigkeit auszulesen und darüber dann ein Relais zu steuern. Habe die abfrage aktuell auf 3s gestellt. Zu beginn intialisiere ich den Filter und fülle diesen sofort mit 40 neu gemessenen Werten, danach frage ich erst 3sec ab, sonst habe ich zu beginn eine hohe ungenauigkeit und ggf auch schaltzyklen, welche ich dadurch vermeiden wollte. Ich glätte das Feuchtigkeitssignal über einen Eponentialfilter, damit ich sauberere Werte erhalte

Problem ist, dass nach einigen sekunden einfach nichts mehr passiert, also im SerialMonitor keine Änderung mehr erfolgt (verbindung ist noch vorhanden)


#include "DHT.h"
#define DHTTYPE DHT22
#define DHT22_PIN 2
#define RelaisPIN 3
#include "Filter.h"
boolean DEBUG = true;
unsigned long getHumidityOld = millis();
int readrate = 10000;
int HumidityOld = 0;
boolean HumidityChanged = false;
int SmoothHumidity = 0;
int initcount = 40;
boolean m_init = false;
boolean error = false;

//--------------------------------------------------------------------
//             USER DEFINITION

int HumidityOn  = 60;
int HumidityOff = 45;

//--------------------------------------------------------------------

DHT dht(DHT22_PIN, DHTTYPE);
float humidity, temperature;

ExponentialFilter<float> ExpFilter(initcount, 0);

void setup() {
  Serial.begin(115200);
  dht.begin();
  delay(500);
  pinMode(RelaisPIN, OUTPUT);

}

void loop() {

  if (initcount == 0 && m_init == false) {
    m_init = true;
    if (DEBUG == true) {
      Serial.println("Init abgeschlossen");
    }
  }

  if (((millis() - getHumidityOld) >= readrate) || m_init == false) {

    humidity = dht.readHumidity();
    temperature = dht.readTemperature();
    error = false;
    if (isnan(humidity) || isnan(temperature)) {
      Serial.println("DHT NOT WORKING");
      error = true;
      delay(500);
    }
    if (!error) {

      if (m_init == false) {
        initcount--;
      }

      ExpFilter.Filter(humidity);
      SmoothHumidity = (int)(ExpFilter.Current() + .5);

      if (DEBUG == true) {
        Serial.print("Luftfeuchte: ");
        Serial.print(humidity);
        Serial.print("%, ");
        Serial.print("SmoothHumidity: ");
        Serial.print(SmoothHumidity);
        Serial.print("%, ");
        Serial.print("Temperatur: ");
        Serial.print(temperature);
        Serial.println("°C");
        if (m_init == false) {
          Serial.print("Init Count: ");
          Serial.println(initcount);
        }
      }


      if (HumidityOld != SmoothHumidity) {
        if (m_init == true) {
          HumidityChanged = true;
        }
        if (DEBUG == true) {
          Serial.println("Luftfeuchtigkeit geändert");
          Serial.print("SmoothHumidity: ");
          Serial.print(SmoothHumidity);
          Serial.print("%, ");
          Serial.print("HumidityOld: ");
          Serial.print(HumidityOld);
          Serial.println("%, ");
        }
        HumidityOld = SmoothHumidity;
      }

      getHumidityOld = millis();
    }
  }
  if (HumidityChanged == true && m_init == true) {
    if (DEBUG == true) {
      Serial.println("Relais Status überprüfen");
    }
    if (SmoothHumidity > HumidityOn && digitalRead(RelaisPIN) == false) {
      digitalWrite(RelaisPIN, HIGH);
      if (DEBUG == true) {
        Serial.println("Relais high");
      }
    }
    if (SmoothHumidity < HumidityOff && digitalRead(RelaisPIN) == true) {
      digitalWrite(RelaisPIN, LOW);
      if (DEBUG == true) {
        Serial.println("Relais low");
      }
    }

    HumidityChanged = false;
  }
}

Da fehlt doch ein & oder?

da ist ein Leerzeichen drinnen, was nicht sein sollte
aber &! bedeutet doch, bedingung a und nicht bedingung b, oder?

Zeilen später:

Du willst hier:

prüfen ob der LOW ist? Richtig?

Ja richtig, ich möchte wenn er off ist und schwellwert erreich auf true:

      if (SmoothHumidity > HumidityOn && digitalRead(RelaisPIN) == false) {
        digitalWrite(RelaisPIN, HIGH);

, bzw wenn on und anderer schwellwert, dann auf false:

      if (SmoothHumidity < HumidityOff && digitalRead(RelaisPIN) == true) {
        digitalWrite(RelaisPIN, LOW);

habe aber den code oben nochmal etwas angepasst, dass das ganze leichter verständlich ist - hat aber leider an der Problematik nichts geändert

:slight_smile: Klassiker:

Da passt aber nach etwas mehr als 30 Sekunden nichts mehr rein...
Und wenn Du Dich fragst, warum Du die 30 sekunden ggfls. nicht mal erreichst:
Das hier ist dann der Auslöser:

Ja stimmt, daran hatte ich nicht gedacht, hab es auf unsigned long ausgebessert, jzt läuft er schon mal länger, aber was mach ich wenn "millis" in nen overflow läuft (nach 50 tagen) dann geht ja folgenden überprüfung nicht auf

getHumidityOld + readrate < millis()
1 Like

Richtig!
Deswegen ist die Additions Methode ja auch Mist.

Idee war, dass ich es so löse, aber irgendwie springt er jzt immer rein:

  if ((millis() - getHumidityOld >= 0) || m_init == false) {
      getHumidityOld = millis() + readrate;```

Na supi - bekommst nen ++ ersten Fehler gelöst und schon festgestellt, das es so nicht geht...
Dann bau das doch um.
Das soll doch ein Vergleich auf readrate werden oder?

Kannst Du mal erklären, was da passieren soll? Mit Worten - nicht mit Variablen.
Denn die

ist genauso unterdimensioniert.

Eine vorzeichenlose Zahl ist IMMER größer oder gleich Null.
IMMER.

Ja aber der "getHumidityOld" war ein höherer Wert bei der vorherigen Calc als der millis
daher hätte es etwas dauern müssen bis er positiv wird

nach dem Beitrag geht es nun

Ja danke, ich hatte selbst etwas gegoogelt aber leider nichts brauchbares gefunden, durch deinen Link hatte es nun funktioniert, vielen dank!

HumidityOld kann nicht unterdimensioniert sein, weil von "SmoothHumidity" drauf geschrieben wird, welcher ebenfalls ein "int" ist. Dieser wird über den Filter zwar mit einer float beschrieben, aber dieser wird doch eh konvertiert (abgesehen davon erwarte ich mir vom Sensor keine entsprechend große Zahl)

Das glaube ich nicht.
Zum einen hast Du ein delay da noch drin, da ist millis schon ganz weit weg.
Und ich hab über Deinen Code einfach mit STRG-T eine schicke Ansicht gemacht:

void loop()
{
  if (initcount == 0 && m_init == false)
  {
    m_init = true;
    if (DEBUG == true)
    {
      Serial.println("Init abgeschlossen");
    }
  }
  if (getHumidityOld + readrate < millis() || m_init == false)
  {
    humidity = dht.readHumidity();
    temperature = dht.readTemperature();
    error = false;
    if (isnan(humidity) || isnan(temperature))
    {
      Serial.println("DHT NOT WORKING");
      error = true;
      delay(500);
    }
    if (!error)
    {
      if (m_init == false)
      {
        initcount--;
      }
      ExpFilter.Filter(humidity);
      SmoothHumidity = (int)(ExpFilter.Current() + .5);
      if (DEBUG == true)
      {
        Serial.print("Luftfeuchte: ");
        Serial.print(humidity);
        Serial.print("%, ");
        Serial.print("SmoothHumidity: ");
        Serial.print(SmoothHumidity);
        Serial.print("%, ");
        Serial.print("Temperatur: ");
        Serial.print(temperature);
        Serial.println("°C");
        if (m_init == false)
        {
          Serial.print("Init Count: ");
          Serial.println(initcount);
        }
      }
      if (HumidityOld != SmoothHumidity)
      {
        if (m_init == true)
        {
          HumidityChanged = true;
        }
        if (DEBUG == true)
        {
          Serial.println("Luftfeuchtigkeit geändert");
          Serial.print("SmoothHumidity: ");
          Serial.print(SmoothHumidity);
          Serial.print("%, ");
          Serial.print("HumidityOld: ");
          Serial.print(HumidityOld);
          Serial.println("%, ");
        }
        HumidityOld = SmoothHumidity;
      }
      getHumidityOld = millis();
    }
    if (HumidityChanged == true && m_init == true)
    {
      if (DEBUG == true)
      {
        Serial.println("Relais Status überprüfen");
      }
      if (SmoothHumidity > HumidityOn && digitalRead(RelaisPIN) == false)
      {
        digitalWrite(RelaisPIN, HIGH);
        if (DEBUG == true)
        {
          Serial.println("Relais high");
        }
      }
      if (SmoothHumidity < HumidityOff && digitalRead(RelaisPIN) == true)
      {
        digitalWrite(RelaisPIN, LOW);
        if (DEBUG == true)
        {
          Serial.println("Relais low");
        }
      }
      HumidityChanged = false;
    }
  }
}

Bist Du sicher, das die Schachtelungen passen?
Wenn das nicht erfüllt ist:

  if (getHumidityOld + readrate < millis() || m_init == false)

wirst Du das

if (HumidityChanged == true && m_init == true)

Nie erreichen....
Na denn...

Ja vielen Dank, da hatte ich wirklich beim ändern eine Klammer falsch gesetzt

das delay ist nur dazu da, dass falls er keine connection findet, sich ein bisschen zeit lässt, und da er sowieso nichts anderes ausführen sollte, dachte ich, ich kann es auch mittels delay lösen - warum ist das ein Problem?

getHumidityOld + readrate < millis()
Herrjeh...

Genau gesagt, Die Zahl paßt nicht mehr als ganzes hinein, es wird aber dennoch was hineingespeichert. Genau gesagt es werden die untersten 15 bit in den Int übernommen.

Grüße Uwe

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