Hallo,
ich verwende einen Arduino in Kombination mit einem MAX31855 (fertiges
Board von AdaFruit), um die Temperatur eines Thermo-Elements Typ K
auszulesen. Das Thermo-Element misst die Temperatur eines Ofens, im
Bereich 20-1000°C. Es ist mit ca. 1m geschirmter Leitung per Klemme mit
dem MAX31855 verbunden. Habe alles mal einen Tag laufen lassen im
gesamten Temperaturbereich und es klappt ganz gut. Der Messwert
entspricht der Wirklichkeit, ist schön stabil und schwankt nicht.
Mein Problem ist Folgendes: Wenn der Ofen bspw. 200°C hat und ich
schalte alles aus und danach wieder ein, wird immer eine Temperatur von
0° ausgelesen. Der MAX31855 gibt auch keine Fehlermeldung, sondern immer
nur 0°. Als ob der IC nicht reagieren würde. Sinkt die Temperatur nun
unter 30°, wird auch die korrekte Temperatur ausgelesen. Wenn jetzt
geheizt wird, funktioniert alles wie gehabt.
Beim Hochlauf des ICs muss das Thermo-Element anscheinend inetwa
Raumtemperatur haben. Vorher reagiert er nicht. Liegt das vielleicht an
der Kaltstellenkompensation des Chips? Kann man dieses Verhalten
irgendwie ändern? Ich hoffe ihr könnt mir helfen :)
Grüße
Fabian schrieb:> Liegt das vielleicht an> der Kaltstellenkompensation des Chips? Kann man dieses Verhalten> irgendwie ändern? Ich hoffe ihr könnt mir helfen :)
Das verstehe ich nicht. Der MAX31855 führt selber doch keine
Kaltstellenkompensation durch, sondern überträgt lediglich die
Messerwerte von Thermoelement und internem Temperatursensor. Die
Kompensation sollte Deine Software durchführen. Ob sie das richtig
macht, solltest Du den Programmierer fragen, also Dich selbst.
> (...) Der Messwert> entspricht der Wirklichkeit, ist schön stabil und schwankt nicht.
Kann es sein, dass Deine Software die Messwerte glättet bzw. filtert?
Dann würde ich den Fehler dort vermuten.
Grüßle,
Volker
Lothar M. schrieb:> Sind irgendwelche Fehlerbits gesetzt?
Keins gesetzt, die sind alle drei auf 0. Das meinte ich mit "keine
Fehlermeldung".
Volker B. schrieb:> Der MAX31855 führt selber doch keine Kaltstellenkompensation durch
Also laut Datenblatt macht er das: "The MAX31855 performs cold-junction
compensation
and digitizes the signal from a K-, J-, N-, T-, S-, R-, or
E-type thermocouple." Was er nicht macht ist den Messwert zu
linearisieren. Die Widerstandskurve ist ja nicht ganz linear, aber in
meinem Messbereich ist der Fehler klein genug. Ich brenne ja nur Keramik
;)
Volker B. schrieb:> Kann es sein, dass Deine Software die Messwerte glättet bzw. filtert?
Ich lese alle 2s per Interrupt 5 Messwerte ein, frage die Fehlerbits ab
und nehme den Mittelwert.
Das Seltsame ist, dass das Messen der Temperatur grundsätzlich
funktioniert (auch stundenlang), aber beim Einschalten muss das
Thermo-Element kalt sein. Wenn es warm oder heiß ist, dann gibt's nur
0°C.
Fabian schrieb:> Also laut Datenblatt macht er das: "The MAX31855 performs cold-junction> compensation> and digitizes the signal from a K-, J-, N-, T-, S-, R-, or> E-type thermocouple."
OK, Du verwendest also einen MAX31855K. Das depperte Datenblatt hätte ja
auch darauf hinweisen können, dass jeder Thermoelement-Typ eine
spezielle Version des MAX31855x benötigt...
> Ich lese alle 2s per Interrupt 5 Messwerte ein, frage die Fehlerbits ab> und nehme den Mittelwert.
...und da läuft auch nichts über?
...und der Datenaustausch zwischen main() und Irpt-Handler erfolgt über
eine volatile-Variable?
> Das Seltsame ist, dass das Messen der Temperatur grundsätzlich> funktioniert (auch stundenlang), aber beim Einschalten muss das> Thermo-Element kalt sein. Wenn es warm oder heiß ist, dann gibt's nur> 0°C.
Ich würde behaupten, dass der MAX genau das macht was er soll und der
Fehler mal wieder in dem Teil liegt, der nicht gezeigt wird -- wie so
oft in diesem Forum.
Grüßle,
Volker
Dann rück' ich mal ein paar mehr Info's raus. Ich hatte gehofft, dass
jemand schonmal genau das Gleiche gehabt hat.
Ich verwende die Adafruit_MAX31855 Library. Die ist von Tausenden
getestet und da steht auch nicht besonders viel drin. Ich würde den
Fehler eher bei mir vermuten.
Hier ist das Initialisieren:
sample_count ist uint8_t = 5 und temp_offset ist double = 0. Ich könnte
am Wochenende ggf. ein Testprojekt fertig machen in dem nur das Nötigste
steht um den Fehler zu reproduzieren. Die Variablen sind im Übrigen
nicht als volatile gekennzeichnet -> wird geändert. Aber wie gesagt: Es
funktioniert ja grundsätzlich. Ich habe letzten Freitag erfolgreich ein
14h Brennprogramm abgefahren.
Der Fehler kommt nur in dieser Situation:
Gerät ein >> Ofen aufheizen >> Gerät aus >> Gerät ein >> 0° (Funktion
weg) >> Ofen etwas abkühlen lassen >> 30° >> 29° >> 28°... (Funktion
wieder da)
Fabian schrieb:> Dann rück' ich mal ein paar mehr Info's raus.
und hier tauchen merkwürdigerweise genau die magischen 30°C auf:
> if (abs(actual_temp - t) > 30) // Temparatur innerhalb von 2s mehr als> 30° gestiegen -> ignorieren> error_count++;> else
...aber Schuld ist natürlich der IC :-)
Grüßle,
Volker
Fabian schrieb:> Ich würde den Fehler eher bei mir vermuten.
;)
Verdammt. Ich hab so lange drauf geguckt - Ich hab's einfach nicht
gesehen. Grrr. So ein blöder Fehler. Vielen Dank Volker!
Grüße
Fabian schrieb:> Verdammt. Ich hab so lange drauf geguckt - Ich hab's einfach nicht> gesehen.
Das kenne ich nur zu gut! Bei umfangreichen Programmen drucke ich mir
gern' das Listing aus und verziehe mich an einen Ort, wo es keine
Ablenkung gibt und die einzige (sinnvolle) Beschäftigung das Lesen des
Listings ist. Du glaubst nicht, wie viele logische Fehler ich dabei
jedes Mal in meinem Code gefunden habe...
Manchmal reicht es auch, eine Runde auf dem Fahrrad zu drehen, möglichst
auf ruhigen Feld- und Waldwegen. Oft kommt mir dann eine "Eingebung" wo
der logische Fehler zu suchen ist.
Grüßle,
Volker
Volker B. schrieb:> Fabian schrieb:>> Dann rück' ich mal ein paar mehr Info's raus.>> und hier tauchen merkwürdigerweise genau die magischen 30°C auf:Volker B. schrieb:> Fabian schrieb:>> Verdammt. Ich hab so lange drauf geguckt - Ich hab's einfach nicht>> gesehen.>> Das kenne ich nur zu gut!
Das ist die berühmt-berüchtigte "Betriebsblindheit" und auch nur allzu
menschlich :)