Probleme bei Sensorauswertung. nan (not a value) oder Crash vom ESP8266

Hallo,
ich habe ein kleines Problem und weis nicht wie ich es lösen könnte.
Kurz zur Beschreibung auf das Wesentliche wo das Problem steckt.
An einem ESP8266 ist ein NTC angeschlossen und wird ausgewertet. Alles soweit ok.
Wenn der Sensor nicht angeschlossen ist, soll eine Fehlermeldung kommen.
Aktuell kommt dann wenn der Sesnor nicht angeschlossen ist “nan” not a value.
Das liegt wahrscheinlich an der Umrechnung des NTC und daran das, die Variablen als Float deklariert sind.
Wenn ich die 2 Variablen

float durchschnitt = 0;
float NTCtemp;

als Int deklarie, bekomme ich als Zahl ohne Sensorr angeschlossen die - 273, die könnte ich auswerten.
Aber mit Int als Deklaration der 2 Variablen habe ich folgendes Problem.
Sobald der Sesnoer angeschlossen ist, hängt der ESP
mit Exception (0):
epc1=0x4000dce5

Also,
mit Float = Sensor angeschlossen und Werte ok , ohne Sesnor = nan
mit Int = Sesnor angeschlossen = Exception, ohne Sesnor - 273.

Den NTC frage ich wie folgt ab:

void temperaturberechnung()
  {
  for (int i=0; i < abfrageZahl; i++)     // Nimmt n Abfragen in einer Reihe
  {
  abfrage[i] = analogRead(ntc);            
  delay(10);
  }
  durchschnitt = 0;                         // Mittelt alle Abfragen
  for (int i=0; i < abfrageZahl; i++)
  {
  durchschnitt += abfrage[i];
  }
  durchschnitt  /= abfrageZahl;
  durchschnitt  = 1023 / durchschnitt - 1;      // Umwandlung des Wertes in Wiederstand
  durchschnitt  = serienWiederstand / durchschnitt;

   
  // Umrechnung aller Ergebnisse in die Temperatur mittels einer Steinhard Berechnung
  //---------------------------------------------------------------------------------
  
  NTCtemp = durchschnitt / ntcNominal;        // (R/Ro)
  NTCtemp = log(NTCtemp);                     // ln(R/Ro)
  NTCtemp /= bCoefficient;                    // 1/B * ln(R/Ro)
  NTCtemp += 1.0 / (tempNominal + 273.15);    // + (1/To)
  NTCtemp = 1.0 / NTCtemp;                    // Invertieren
  NTCtemp -= 273.15;                          // Umwandeln in °C

Ich will eigendlich nur wissen und auswerten können wenn kein Sesnor angeschlossen ist, bzw. Kabelbruch etc.
Das nan kann ich nicht auswerten und warum der ESP sich aufhängt mit Int verstehe ich nicht.

Vielleicht habt ihr eine Lösung. Grüsse

nan = not an number meinte ich

Ich habe gefunden:

float wert;
if (wert == wert)
{
   // wert ist gültig
}
else
{
  // wert ist NaN
}

Es soll wohl auch - aber vielleicht nicht überall - ein Makro isnan(wert), ggf. auch als float.isNaN(wert) geben.

Man könnte auch rauskriegen, wo das NaN herkommt.
Division durch 0 wäre ein Kandidat...

warum der ESP sich aufhängt mit Int verstehe ich nicht.

Das könnte auch eine Division durch 0 sein...

Der Verzicht auf Verwendung interner Variablen ist eher gewöhnungsbedürftig, aber deine Sache.

Hallo,wno158
Danke für deine Idee, das funktioniert einmal, im ersten Loop ist NTCtemp z.: 20 == 20 dann ist im nächsten Loop nan == nan und somit wieder ok.
also nicht ganz so optimal. klar ich könnte auf das erste mal reagieren und dann maßnhamen treffen, aber ich hätte das das nan immer zuverlässig wie eine Variable ausgewertet werden kann.
Schade, trotzdem Danke ein Idee zum versuch war es wert.

Hallo, michael_x
ich verstehe deinen Hinweis nicht so ganz
"Der Verzicht auf Verwendung interner Variablen ist eher gewöhnungsbedürftig, aber deine Sache."
Ich habe doch ein Haufen interne Variablen , oder was meinst du genau. Die NTC Auswertung habe ich auch hier aus dem Forum übernommen. Das in dieser Auswerung am schluss die NTCtemp Variable kaskadiert abgearbeitet wird fand ich auch ungewöhlich, meinst du das etwa?

Hat sonst noch einer eine Idee, wie ich es verbessern kann, oder unterscheiden kann ob die Variable NTCtemp ein Zahlenwert oder ein nan ist, besser die NTC AUswertung so gestallten, das ein nan gar nicht vorkommt, ondern der Wert -273

NTCtemp = durchschnitt / ntcNominal;        // (R/Ro)

NTCtemp = log(NTCtemp);                    // ln(R/Ro)
  NTCtemp /= bCoefficient;                    // 1/B * ln(R/Ro)
  NTCtemp += 1.0 / (tempNominal + 273.15);    // + (1/To)
  NTCtemp = 1.0 / NTCtemp;                    // Invertieren
  NTCtemp -= 273.15;                          // Umwandeln in °C

Das meine ich mit "keine internen variablen verwenden"

Sobald NTCTemp in einem der Zwischenschritte den Wert NaN hat, bleibt es NaN.
Da ich nicht mal weiß, was bei dir ntcNominal ist, kann ich auch keine weiteren Tips geben.
Aber auch log(0) wäre nicht so gesund.

Dass man bei int-Variablen kein NaN Ergebnis bekommen kann, sollte aber klar sein, oder?

Hallo,
ok ich verstehe, dann sind wir auf einem Nenner.
Wie gesagt, ich hab den NTC Teil nur wo abkopiert und fand es auch "eigenartig".
Da es aber funktioniert hat, hatte ich es so gelassen.

Also oben ist der Teil im Skript von der Auswertung.

Hier die fehleden Infos:

//..................................................................................................NTC
const int abfrageZahl = 10;           // je mehr abfragen, desto stabiler isr das Ergebnis
const int ntc = A0;                   // Pin für den NTC Wiederstand
const int ntcNominal = 10000;         // Wiederstand in OHM des NTC bei Nominaltemperatur
const int tempNominal = 25;           // Temperatur bei der der NTC den angegebenen Wiederstand hat
const int bCoefficient = 4000;        // Beta Coefficient(B25 aus Datenblatt des NTC)
const int serienWiederstand = 10000;  // Wert des Wiederstands der mit dem NTC in Serie geschalten ist
 
int     abfrage[abfrageZahl];           // Array Variable für das Mitteln der Temperatur
float   durchschnitt = 0;               // Variable für das Mitteln der Temperatur
float   NTCtemp;                        // Variable NTC
//..................................................................................................

//..................................................................................................NTC
const int abfrageZahl = 10; // je mehr abfragen, desto stabiler isr das Ergebnis
const int ntc = A0; // Pin für den NTC Wiederstand
const int ntcNominal = 10000; // Wiederstand in OHM des NTC bei Nominaltemperatur
const int tempNominal = 25; // Temperatur bei der der NTC den angegebenen Wiederstand hat
const int bCoefficient = 4000; // Beta Coefficient(B25 aus Datenblatt des NTC)
const int serienWiederstand = 10000; // Wert des Wiederstands der mit dem NTC in Serie geschalten ist

int abfrage[abfrageZahl]; // Array Variable für das Mitteln der Temperatur
float durchschnitt = 0; // Variable für das Mitteln der Temperatur
float NTCtemp; // Variable NTC
//..................................................................................................

Hi, also ich will noch kurz dazu sagen, das ich nicht so der Profi bin, ich bin eher der Anfänger
auf dem Wedg sich stetig zu verbessern, deswegen ist auch viel Trial and error.

Grüsse

Hallo nochmal,
also ich hab noch bischen gesucht und habe eine andere Quelle gefunden die fast gleich wie bei mir ist:

hmmm.... weiter bringt mich das jetzt nicht...aber ganz so falsch scheint es nicht zu sein.

Wenn du wno158s Trick

if ( NTCtemp != NTCtemp ) {
   // ein NaN ist ungleich zu allem, sogar zu sich selbst
   // Vermutlich kein Sensor dran ...
   return;
}

... nicht verwenden willst, kannst du das ja früher abfangen, eventuell schon hier:

nach der Zeile
durchschnitt  /= abfrageZahl;

funktioniert dein Code weder mit durchschnitt 0 noch 1023

Eins von beidem wird wohl analogRead(A0) "ohne Sensor" liefern.

Nachtrag:
Es ist ein Unterschied zwischen nan und inf
(Der Vergleich if(inf == inf) geht).

1.0 / 0.0 oder log(0.0) ergibt inf, nicht nan.

(Aber log(-1.0) ergibt z.B. nan).

Kannst gerne rausfinden und berichten, woran es bei dir hing.

Hallo michael_x,
vielen Dank für deine wertvollen Hinweise.
Ich habe jetzt mal zwischen jede Zeile ein Serial.println(NTCtemp) reingemacht, damit ich sehe wann es passiert.
Inspiriert durch deine Hinweise....das es ja irgendwo passieren muss :slight_smile:
Es passiert ab:

NTCtemp = log(NTCtemp); = nan
d
avor ist ein Sensorbruch oder keinSensor noch bei :

NTCtemp = durchschnitt / ntcNominal; = -1024.00

Somit habe ich auch die exakte Stelle wo ich abfragen kann, was Sesnorbruch , oder Defekt als Zahl bedeutet.
Somit ist das nan Problem gelöst , und ja dein Script hab ich auch angetestet...
Wichtig war das dein Hinweis dazu, den ich dachte nan gleich nan ist und nicht !=

ein NaN ist ungleich zu allem, ........"sogar zu sich selbst......"

Danke für Deine Hilfe ! Schöne Grüsse

Könntest dich auch fragen wie float durchschnitt überhaupt negativ werden kann.
analogRead liefert jedenfalls nur 0 .. 1023:

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