Einleitung
Nach dem Datenblatt von MAX31855 berechnet dieser Chip die Temperatur aus der thermoelektromotorischen Kraft $E$ unter Annahme der folgenden Beziehung: $$\begin{align} E = C (t_\mathrm{R} - t_\mathrm{AMB}) \; , \end{align}$$ wobei $C$ ist eine vom Typ des Thermoelements abhängige Konstante (Empfindlichkeit, sensitivity), $t_\mathrm{R}$ ist die Temperatur des Messstellentemperatur (remote) und $t_\mathrm{AMB}$ ist die Temperatur des Chips (Umgebung, ambient). In der Realität gibt es jedoch keine solche lineare Beziehung zwischen der thermoelektromotorischen Kraft und Temperaturdifferenz, und es kann zu großen Diskrepanzen kommen, insbesondere bei Temperaturen unter $0\,\degree\mathrm{C}$.
Dies wird im Adafruit-Forum schon seit einiger Zeit diskutiert, und Pete (heypete) hat es dort und in seinem Blog ausführlich beschrieben. Die Korrekturprozedur ist in der MAX31855 Linearized Thermocouple Temperature (PNG-Datei) beschrieben, die im Forum gepostet wurde. Die Codes sind in einem Artikel von Adafruit Maxim 31855 Thermocouple Linearization zu finden, der eine Zusammenfassung von Implementierungen ist, die von Jeff (jh421797) und Pete (heypete) im obigen Forum gepostet wurden (beide sind im Wesentlichen das Gleiche). Diese haben jedoch die folgenden Nachteile:
-
Die Übersichtlichkeit ist nicht optimal, so dass man nur schwer erkennen kann, was man gerade tut.
-
Die Verwendung der
pow()-Funktion macht sie langsam, und die Größe der Binärdateien ist etwas groß. -
Nicht generisch, da es als
.ino-Datei (Datei für Arduino) geschrieben ist.
Daher habe ich die Funktionen für die Umrechnungen zwischen der elektromotorischen Kraft des Thermoelements und der Temperatur als der Bibliothek für Thermoelemente basierend auf der NIST ITS-90 Datenbank neu implementiert. Diese Bibliothek enthält keine MAX31855-spezifische Verarbeitung, lässt sich aber sehr einfach auf den MAX31855 anwenden, wie im Folgenden erläutert. Darüber hinaus werden alle Typen von Thermoelementen in der NIST ITS-90-Datenbank unterstützt, da die Funktionen durch ein Skript aus der NIST-Datenbank generiert werden. Die Polynome werden nach dem Horner-Schema berechnet. Diese haben zu einer saubereren Beschreibung, einer kleineren Binärgröße und einer viel schnelleren Ausführungszeit geführt.
Korrektur der von MAX31855 ausgegebene Temperatur
Weitere Informationen über die Bibliothek selbst finden Sie unter Bibliothek für Thermoelemente basierend auf der NIST ITS-90 Datenbank.
Im Folgenden ist die Einheit für die Temperatur $\degree\mathrm{C}$ und die Einheit für die elektromotorische Kraft (EMK) mV.
Für Thermoelemente vom Typ K kann die korrigierte (genauere)
Temperatur aus der Messstellentemperatur (rawTemp) und der
Vergleichsstellentemperatur (internalTemp) von MAX31855 berechnet
werden, indem man schreibt
correctedTemp = emf2temp_K((rawTemp - internalTemp) * 0.041276 + temp2emf_K(internalTemp));wobei emf2temp_K() und temp2emf_K() die von der
Bibliothek für Thermoelemente basierend auf der NIST ITS-90 Datenbank
bereitgestellten Funktionen sind.
Für Thermoelemente, die nicht vom Typ K sind, sind die Namen der
Funktionen durch das entsprechende Thermoelement (z. B. emf2temp_B)
und die Konstante (0.041276 im obigen Beispiel) durch den Wert im
Datenblatt des MAX31855 zu ersetzen.
Die Entsprechung zwischen dieser Formel und dem oben angegebenen Verfahren (MAX31855 Linearized Thermocouple Temperature) ist wie folgt: $$\begin{align} t_\mathrm{corr} = \underbrace{ \mathrm{emf2temp}( \underbrace{ \underbrace{ \underbrace{(t'_\mathrm{R} - t_\mathrm{AMB})}_\text{step 1} \cdot C}_\text{step 2} + \underbrace{\mathrm{temp2emf}(t_\mathrm{AMB})}_\text{step 3} }_\text{step 4} )}_\text{step 5} \end{align}$$ wobei:
- $t_\mathrm{corr}$
-
Korrigierte Temperatur
- $t'_\mathrm{R}$
-
Temperatur des Messstellentemperatur (
rawTemp), die MAX31855 ausgibt. $t_\mathrm{R}$ ist mit $'$ gekennzeichnet, um anzudeuten, dass es nicht sehr genau (zu korrigieren) ist. - $t_\mathrm{AMB}$
-
Die von MAX31855 ausgegebene Vergleichsstellentemperatur (
internalTemp) - $C$
-
Die von MAX31855 verwendete Empfindlichkeit (sensitivity, siehe Gleichung (1))
Wenn Sie einen linearen Ausdruck verwenden möchten, um
$t_\mathrm{AMB}$ (internalTemp) in elektromotorische Kraft zu
konvertieren
(siehe Beitrag von Mike (zike)),
können Sie schreiben:
correctedTemp = emf2temp_K((rawTemp - internalTemp) * 0.041276 + internalTemp * 0.04073);(Siehe Datenblatt von MAX31855 für die verwendeten Konstanten).
Vergleich
Als Hinweis wurden die Binärgröße und die Ausführungszeit der
Arduino-Implementierungen mit meiner
Bibliothek für Thermoelemente basierend auf der NIST ITS-90 Datenbank
und HeyPete's
MAX31855-Linearization
verglichen.
(In den folgenden Tabellen werden diese jeweils mit TPKato
bzw. heypete
bezeichnet.)
Der für den Vergleich verwendete Code kann unter
https://github.com/TPKato/arduino-max31855-nist
abgerufen werden.
Umgebung
-
gcc version 11.2.0 (+ Arduino IDE 1.8.19)
-
Arduino libraries
-
SPI at version 1.0
-
Wire at version 1.0
-
Adafruit_MAX31855_library at version 1.3.0
-
Adafruit_BusIO at version 1.10.3
-
Ergebnisse
Binäre Größe (Thermoelement von Typ K, Zeitmessungscode nicht enthalten)
| TPKato | 8490 bytes |
| heypete | 9386 bytes |
Ausführungszeit $\tau_\mathrm{exec}$
Mittelwert von 10 Messungen, etwa alle 1 Sekunde.
| $\overline{\tau_\mathrm{exec}} / \mathrm{\mu{}s}$ | $\overline{t_\mathrm{raw}}/\degree\mathrm{C}$ | $\overline{t_\mathrm{int}}/\degree\mathrm{C}$ | $\overline{t_\mathrm{corr}}/\degree\mathrm{C}$ | |
|---|---|---|---|---|
| TPKato | $\phantom{0}619.6$ | $25.75$ | $26.19$ | $25.73$ |
| heypete | $6654.2$ | $25.75$ | $26.14$ | $25.74$ |
Der einzige wesentliche Unterschied besteht darin, dass das
Horner-Schema anstelle von pow() verwendet wird, aber es zeigt sich,
dass die Leistung deutlich besser ist.
Außerdem ist der Hauptcode viel sauberer und leichter zu verstehen,
indem die Umrechnungen zwischen der elektromotorische Kraft und
Temperatur in Funktionen umgeschrieben werden.
Nachtrag: Herleitungen der obigen Gleichungen
Allgemeine Theorie
Im Allgemeinen werden bei der Temperaturbestimmung mit Thermoelementen die durch den Seebeck-Effekt verursachte Spannung $E$ und die Temperatur $t_\mathrm{AMB}$ an der Vergleichsstelle gemessen. Sei die Spannung $E$ eine Funktion der Temperaturen $T_1$ und $T_2$ der beiden Kontaktstellen $E(T_1, T_2)$, gilt $$\begin{align} E(T_1, T_2) = \int_{T_1}^{T_2} \left( S_\mathrm{B}(T) - S_\mathrm{A}(T) \right) \mathrm{d} T \; , \end{align}$$ wobei $S_\mathrm{A}(T)$ und $S_\mathrm{B}(T)$ jeweils die Seebeck-Koeffizienten der Metalle A und B sind, aus denen das Thermoelement besteht. Daher gilt: $$\begin{align} E(T_1, T_2) &= E(T_1, T_3) + E(T_3, T_2) \\ E(T_1, T_2) &= -E(T_2, T_1) \end{align}$$ (Unterteilung (Intervalladditivität) und Vertauschen der Integrationsgrenzen). Setzt man die Messstellentemperatur $t_\mathrm{R}$, die Vergleichsstellentemperatur $t_\mathrm{AMB}$ und $0\,\mathrm{\degree{}C}$ für $T_1$, $T_2$ und $T_3$ ein, erhält man $$\begin{align} E(t_\mathrm{R}, t_\mathrm{AMB}) &= E(t_\mathrm{R}, 0\,\mathrm{\degree{}C}) - E(t_\mathrm{AMB}, 0\,\mathrm{\degree{}C}) \; , \end{align}$$ daher $$\begin{align} E(t_\mathrm{R}, 0\,\mathrm{\degree{}C}) &= E(t_\mathrm{R}, t_\mathrm{AMB}) + E(t_\mathrm{AMB}, 0\,\mathrm{\degree{}C}) \; . \end{align}$$ (Alternativ kann Gleichung (4) angewendet werden mit $T_1 = t_\mathrm{R}$, $T_2 = 0\,\mathrm{\degree{}C}$ und $T_3 = t_\mathrm{AMB}$.)
Wenn $t^0_\mathrm{TC}(E)$ eine Funktion zur Bestimmung der Temperatur aus der elektromotorischen Kraft in Bezug auf $0\,\mathrm{\degree{}C}$ $E(t, 0\,\mathrm{\degree{}C})$ ist, ergibt die folgende Gleichung die gesuchte Temperatur $t_\mathrm{R}$: $$\begin{align} t_\mathrm{R} & = t^0_\mathrm{TC}(E(t_\mathrm{R}, 0\,\mathrm{\degree{}C})) \\ &= t^0_\mathrm{TC}( \underbrace{E(t_\mathrm{R}, t_\mathrm{AMB})}_\text{measured} + E( \underbrace{t_\mathrm{AMB}}_\text{measured}, 0\,\mathrm{\degree{}C}) ) \end{align}$$
In der Praxis sind $E(t, 0\,\mathrm{\degree{}C})$ und $t^0_\mathrm{TC}(E)$ unbekannt und sollten anhand der entsprechenden Tabellen oder Näherungen berechnet werden.
Beispiel
Als Beispiel ist unten ein Auszug aus der Tabelle von elektromotorischen Kräften für Thermoelemente vom Typ K dargestellt (basierend auf all.tab von NIST, Einheit der elektromotorischen Kraft: mV).
| $t/ \mathrm{\degree{}C}$ | +0 | +1 | +2 | +3 | +4 | +5 | +6 | +7 | +8 | +9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.000 | 0.039 | 0.079 | 0.119 | 0.158 | 0.198 | 0.238 | 0.277 | 0.317 | 0.357 |
| 10 | 0.397 | 0.437 | 0.477 | 0.517 | 0.557 | 0.597 | 0.637 | 0.677 | 0.718 | 0.758 |
| 20 | 0.798 | 0.838 | 0.879 | 0.919 | 0.960 | 1.000 | 1.041 | 1.081 | 1.122 | 1.163 |
| 30 | 1.203 | 1.244 | 1.285 | 1.326 | 1.366 | 1.407 | 1.448 | 1.489 | 1.530 | 1.571 |
| 40 | 1.612 | 1.653 | 1.694 | 1.735 | 1.776 | 1.817 | 1.858 | 1.899 | 1.941 | 1.982 |
Wenn, zum Beispiel,
-
$t_\mathrm{AMB} = 24\,\mathrm{\degree{}C}$ und
-
die gemessene elektromotorische Kraft $0.529\,\mathrm{mV}$ beträgt,
dann kann man die gesuchte Temperatur $t_\mathrm{R}$ aus Gleichung (9) und dieser Tabelle wie folgt bestimmen. $$\begin{align*} t_\mathrm{R} &= t^0_\mathrm{TC}( \underbrace{0.529\,\mathrm{mV}}_{E(t_\mathrm{R}, t_\mathrm{AMB})} + \underbrace{0.960\,\mathrm{mV}}_{E(t_\mathrm{AMB}, 0\,\mathrm{\degree{}C})} ) \\ &= t^0_\mathrm{TC}(1.489\,\mathrm{mV}) \\ &= 37\,\mathrm{\degree{}C} \end{align*}$$
Mit anderen Worten: $E(t, 0\,\mathrm{\degree{}C})$ entspricht der Ermittlung der elektromotorischen Kraft aus der entsprechenden Temperatur in der Tabelle, und $t^0_\mathrm{TC}(E)$ entspricht der Ermittlung der entsprechenden Temperatur, indem man die elektromotorische Kraft in der Tabelle sucht.
Eine solche Tabelle ist jedoch für die Computerverarbeitung nicht geeignet, daher werden approximierte Funktionen verwendet.
Lineare Annahme
Unter der Annahme, dass die Seebeck-Koeffizienten unabhängig von der Temperatur sind, kann Gleichung (3) wie folgt ausgedrückt werden: $$\begin{align} E(T_1, T_2) = C (T_1 - T_2) \end{align}$$ ($C = - S_\mathrm{B} + S_\mathrm{A}$). Setzt man wiederum $t_\mathrm{R}$ und $t_\mathrm{AMB}$ in $T_1$ und $T_2$ ein, erhält man $$\begin{align} E(t_\mathrm{R}, t_\mathrm{AMB}) &= C (t_\mathrm{R} - t_\mathrm{AMB}) \; . \end{align}$$ Daraus ergibt sich $$\begin{align} t'_\mathrm{R} &= \frac{1}{C}E(t_\mathrm{R}, t_\mathrm{AMB}) + t_\mathrm{AMB} \; . \end{align}$$ Hier in Gleichung (12) wurde $'$ zu $t_\mathrm{R}$ hinzugefügt, um eine lineare Annahme (d. h. nicht sehr genau) zu implizieren.
Gleichung (11) ist genau das, was im Datenblatt von MAX31855 steht, und es gibt die so berechneten $t'_\mathrm{R}$ aus. Diese Annahme kann jedoch nur in sehr grober Näherung (innerhalb eines begrenzten Temperaturbereichs) getroffen werden.
Korrektur
Die genauere Messstellentemperatur kann erhalten werden, indem
-
die elektromotorische Kraft $E(t_\mathrm{R}, t_\mathrm{AMB})$ aus $t'_\mathrm{R}$ und $t_\mathrm{AMB}$ aus dem MAX31855 zurückgerechnet wird und
-
Gleichung (9) mit diesem Wert (und $t_\mathrm{AMB}$) erneut angewendet wird.
Setzt man zu diesem Zweck Gleichung (11) in Gleichung (9) ein, so erhält man
$$\begin{align}
t_\mathrm{R} & = t^0_\mathrm{TC}(C (t_\mathrm{R} - t_\mathrm{AMB}) + E(t_\mathrm{AMB}, 0\,\mathrm{\degree{}C})) \; ,
\end{align}$$
also die oben genannte Gleichung.
$t^0_\mathrm{TC}(E)$ entspricht der Funktion emf2temp() und
$E(t, 0\,\mathrm{\degree{}C})$ der Funktion temp2emf().