Code für Fehlermeldung unterbrechen

Guten Tag,
ich bastel im moment an einer art Wetterstation, aktuell mit Temperatur und Luftfeuchtesensoren.
Nun möchte ich eine kleine Funktion einbauen, welche eine Fehlermeldung ausgibt sobald ein Sensor kein Signal liefert.

Das wollte ich hiermit bewerkstelligen:

void Fehlermeldung()
{
    if (isnan(h)) {
    display.fillScreen(BLACK);
    display.setTextColor(CYAN, BLACK);  
    display.setTextSize(1);
    display.setCursor(0,0);
    display.println("Feuchtesensor");
    display.println("konnte nicht");
    display.println("gefunden werden");
    return;
  }

Theoretisch sollte das Programm so lange in der Schleife festsitzen bis der Sensor wieder Zahlenwerte liefert.
Jedoch überschreiben sich die Fehlermeldung und die normale Anzeige (Temperatur und Luftfeuchtigkeit) mit jedem Durchgang.

Hier der ganze Code:

#define sclk 13
#define mosi 11
#define cs   10
#define rst  9
#define dc   8


// Displayfarben
#define	BLACK           0x0000
#define	BLUE            0x001F
#define	RED             0xF800
#define	GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

// Temperatur Datenport
#define ONE_WIRE_BUS 2 
// Luftfeuchtigkeit Datenport
#define DHTPIN 3
#define DHTTYPE DHT22

// LIBS
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
#include <OneWire.h> 
#include <DallasTemperature.h>
#include "DHT.h"


Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);  
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);
DHT dht(DHTPIN, DHTTYPE);

long previousMillis1 = 0;  // Zeit merken Temperaturabfrage
long previousMillis2 = 0;  // Zeit merken Display
long previousMillis3 = 0;  // Zeit merken Luftfeuchtigkeitsmessung
long interval1 = 1000; // Temperaturabfrage
long interval2 = 1000; // Displayfrequenz  
long interval3 = 2000; // Frequenz Luftfeuchtigkeit

float h = 0; // Luftfeuchtigkeit
float t = 0; // Temperatur


void setup(void) {
  Serial.begin(9600);
  display.begin();
  sensors.begin(); 
  dht.begin(); // DHT22 Lib
  uint16_t time = millis();
  display.fillScreen(BLACK);
  time = millis() - time;

  
 }



void loop() {
unsigned long currentMillis = millis();

      Fehlermeldung();   // <-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-
     
      if(currentMillis - previousMillis1 > interval1) {
        TempAbfragen ();
        previousMillis1 = currentMillis;
      }

        if(currentMillis - previousMillis2 > interval2) {
        TemperaturOLED();
        previousMillis2 = currentMillis;
      }

        if(currentMillis - previousMillis3 > interval3) {
        Luftfeuchtigkeit();
        previousMillis3 = currentMillis;
      }
    
}




/*************************************************************/
/* ****************** F U N K T I O N E N ****************** */  
/*************************************************************/

void TemperaturOLED()
{
/*~~~~~~~~~~~~~~~~~~~  Temperatur  ~~~~~~~~~~~~~~~~~~~~~*/
  display.setTextColor(GREEN, BLACK);  
  display.setTextSize(1);
  display.setCursor(2,2);
  display.print("Temperatur:");
  
  display.setTextColor(RED, BLACK);  
  display.setTextSize(2);
  display.setCursor(2,12);
  display.print(t);
  display.print((char)247);
  display.print("C");

/*~~~~~~~~~~~~~~~~  Luftfeuchtigkeit  ~~~~~~~~~~~~~~~~~~*/
  display.setTextColor(GREEN, BLACK);  
  display.setTextSize(1);
  display.setCursor(2,36);
  display.print("Luftfeuchte:");
  
  display.setTextColor(RED, BLACK);  
  display.setTextSize(2);
  display.setCursor(2,46);
  display.print(h);
  display.print("%");
}
   

void TempAbfragen ()
{
  sensors.requestTemperatures(); 
  t = (sensors.getTempCByIndex(0));
  Serial.println(t);
}

void Luftfeuchtigkeit()
{
  h = dht.readHumidity();
  Serial.println(h);
}

void Fehlermeldung()  // <-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-
{
    if (isnan(h)) {
    display.fillScreen(BLACK);
    display.setTextColor(CYAN, BLACK);  
    display.setTextSize(1);
    display.setCursor(0,0);
    display.println("Feuchtesensor");
    display.println("konnte nicht");
    display.println("gefunden werden");
    return;
  }
}

Was muss ich nun anders machen um eine unterbrechung bewerkstelligen zu können?
Ich vermute mal das das mit den millis() zusammenhängt das das so nicht klappt?

Mit freundlichen Grüßen
Troxan

Hallo,

was ist denn

if (isnan(h)) {

?

was liefert das zurück? Alles was größer 0 ist wird true.

Schau doch einfach in die Doku:
http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga468be9ed380771eca5a18e812b2470d4

Dass NaN für "Not A Number" steht ist wieder mal Grundwissen. Und wenn man Leuten sagt dass sie mit Divisionen durch 0 aufpassen sollen, dann sollte man auch sagen wie man solche Fehler abfangen kann. Aber hier ist eher wahrscheinlich dass gemeckert wird weil jemand isnan() verwendet.

Ich sehe da rein gar nichts von "Festsitzen" in irgendeiner Schleife. Die Funktion kehrt immer wieder zurück und wird ständig aufgerufen

Das Programm soll so lange in der Funktion Fehlermeldung() bleiben, bis der Sensor wieder Zahlen liefert.

Die Funktion Fehlermeldung(); ist die erste Funktion in der loop Schleife und beinhaltet wie oben erwähnt folgenden Code:

void Fehlermeldung()
{
    if (isnan(h)) {
    display.fillScreen(BLACK);
    display.setTextColor(CYAN, BLACK); 
    display.setTextSize(1);
    display.setCursor(0,0);
    display.println("Feuchtesensor");
    display.println("konnte nicht");
    display.println("gefunden werden");
    return;
  }

Wenn der Sensor keine Zahlenwerte zurück gibt (wird über isnan erkannt) wird die If-Bedingung ausgeführt.
Anschließend soll die If-Bedingung über den return Befehl erneut abgefragt werden.
Eben so lange bis Zahlenwerte geliefert werden, dann erst soll die Fehlermeldung() Funktion verlassen werden.

Gruß
Troxan

Anschließend soll die If-Bedingung über den return Befehl erneut abgefragt werden.

Hä? return verlässt die Funktion

Hallo,

das war kein Gemecker, dass war eine Frage. Woher soll ich wissen was "isnan" sein soll.
Ich glaube auch kam das jeder alle möglichen Funktionen sämtlicher Libs im Kopf hat.

Serenifly:
Hä? return verlässt die Funktion

Hoppla, dann kann das ja nicht funktionieren :smiley:
Gibt es denn eine halbwegs elegante Lösung um wider an den Anfang der If-Bedingung zu kommen?

eine while-Schleife. Wobei du auch nicht unbedingt ständig auf das Display schreiben musst. Vielleicht merken ob die Fehlermeldung schon geschrieben wurde. So dass es im Fehlerfall nur einmal gemacht wird, während ansonsten nur die Schleifenbedingung abgefragt wird

Danke erstmal für die Hilfe :slight_smile:
Ich habe es jetzt soweit hinbekommen das die Fehlermeldung nicht mehr überschrieben wird und das die Fehlermeldung nur ein mal aufgerufen wird.
Jedoch habe ich probleme die Schleife zu verlassen.

error01 ist eine Hilfsvariable damit die Meldung nur einmal ausgegeben wird.
Sie hat zunächst den Wert 0 und wird über eine if-Bedingung auf 1 geändert nachdem sie auf dem Display ausgegeben wurde.
Die While-Schleife ist solange aktiv wie isnan(h) den Wert "TRUE" ausgibt (so war zumindest der Plan)
Leider klappt der letzte Punkt nicht, ich komme in die Schleife rein aber nicht mehr raus.

void Fehlermeldung()
{
    int error01 = 0;
    
    while (isnan(h) == TRUE)
    {
      if (error01 == 0)
      {
        display.fillScreen(BLACK);
        display.setTextColor(CYAN, BLACK);  
        display.setTextSize(1);
        display.setCursor(0,0);
        display.println("Feuchtesensor");
        display.println("konnte nicht");
        display.println("gefunden werden");
        error01 = 1;
      }
    }
}

Oh ja. Man muss natürlich h neu schreiben. Also auch den Sensor ständig auslesen. Sonst ist das immer NaN

Am besten ist es wahrscheinlich man verwendet loop() für diese Schleife und macht keine extra while-Schleife:

void loop()
{
   h = ...

   if(isnan(h))
   {
      //Fehler
   }
   else
   {
      error01 = 0;

      //Normal
   }
}

Danke sehr :slight_smile:
Ich habe nun eine Lösung.
Es geht bestimmt eleganter aber es funktioniert :smiley:

Man muss natürlich h neu schreiben.

Ich habe nun die Funktion Luftfeuchtigkeit(); in die Schleife eingefügt.
Luftfeuchtigkeit(); schreibt bloß die Luftfeuchtigkeit in h,
außerdem habe ich noch eine weitere If-Bedingung eingefügt um den Bildschirm schwarz zu färben nachdem die Fehlermeldung beendet wurde, damit die Temeratur und Luftfeuchtigkeit nicht einfach über die Fehlermeldung geschrieben werden.

void Fehlermeldung()
{
    int error01 = 0;
    
    while (isnan(h) == TRUE)
    {
        Luftfeuchtigkeit();
        
        if (error01 == 0)
        {
            display.fillScreen(BLACK);
            display.setTextColor(CYAN, BLACK);  
            display.setTextSize(1);
            display.setCursor(0,0);
            display.println("Feuchtesensor");
            display.println("konnte nicht");
            display.println("gefunden werden");
            error01 = 1;
        }
        
    } 
    if (error01 == 1){display.fillScreen(BLACK);}  
}

Gruß
Troxan