Forum: Mikrocontroller und Digitale Elektronik Temperaturmessung mit KTY84 und 2-Punkt Kalibrierung


von Wulf D. (holler)


Lesenswert?

Ich möchte mit einem KTY84 eine Temperatur im Bereich von etwa 0-230°C 
messen. Habe kaum Wahl beim Sensor, es soll der vorhandene, an einem 
einfachen Spannungsteiler angeschlossene KTY84 weiterverwendet werden.
Der wird noch für eine andere Aufgabe benutzt.
Genauigkeitsanforderung von +/- 2°C wäre ausreichend.
Möchte den Sensor an einen 10 Bit ADC eines uC (Attiny841) anschließen. 
Eingangsspannungsbereich passt.

Die Frage ist nach der Auswertung: der Temperaturbereich ist groß. Die 
Tabelle im Datenblatt möchte ich ungern abschreiben.
Habe zwar keine Fehlerbetrachtung durchgeführt, aber ich denke ein 
quadratisches Polynom mit einigen Kalibierwerten sollte den Zweck 
erfüllen.

Man findet jede Menge Beispiele einer Linearisierung im Netz. Und bei 
größeren Temperaturbereichen den Hinweis, man solle doch einen PT1000 
nehmen. Hilft hier nicht.
Frage: hat jemand schon eine quadratische Annäherung für einen KTY 
umgesetzt, und hätte vielleicht sogar Beispielcode für eine 
Integer-Arithmetik?

Es gibt ein Datenblatt mit einem Polynom höherer Ordnung, müsste man 
aber entweder nach T umstellen oder Intervall-Schachteln.

Vielleicht hat jemand was zur Hand und ich muss das Rad nicht neu 
erfinden :-)

von H. H. (Gast)


Lesenswert?

Beitrag "Polynom für PTC KTY84-110"

Dort findest du das Polynom.

von Wulf D. (holler)


Lesenswert?

Ja Danke, den Thread mit dem NXP-Sheet fand ich auch schon, meinte damit 
den "Polynom höherer Ordnung".
Die Frage war, ob schon jemand daraus eine Umsetzung in 
Intergerarthmetik zur Bestimmung der Temperatur implementiert hat und 
den Code teilen mag.

von Bernhard S. (b_spitzer)


Lesenswert?

Wenn Du die Kennlinie des Sensors hast (Datenblatt oder Messung), dann 
kannst du auch einfach die zugehörigen Digitalwerte (incl. 
Spannungsteiler) berechnen und in einer Tabelle/Array ablegen. Damit 
dann eine lineare Interpolation zwischen 2 Stützstellen durchführen.
Einfacher wird es, wenn die Temperaturwerte der Stützstellen einen 
konstanten Abstand haben.
Mit zwei bekannten Punkten (X0, Y0) und (X1, Y1) kann entlang der 
Geraden der Wert Y(X) gefunden werden. Der Wert von X muss dabei im 
Intervall X0, X1 liegen. (In Arduino könnte man da einfach für jeden 
Bereich jeweils eine map-Funktion drauf loslassen.)
Zunächst muss das Intervall gefunden werden, in dem der gesuchte 
Ausgabewert liegt. Eine einfache Suchfunktion geht das Array durch, bis 
der gemessene Analogwert über dem Wert X1 liegt. Die Tabelle für den 
Sensor liegt hier z.B. in gleichmäßigen Temperaturabständen von 5°C vor, 
beginnend bei 0°C. Die Suche nach dem Intervall sieht dann so aus 
(stetig steigende Funktion vorausgesetzt):
1
// Digialwerte fuer     0°C  5°C  10°C etc.
2
unsigned int Tabelle[]={100, 150, 200, 250...}; // für deinen Aufbau anpassen
3
#define T_low 0                 // unterste Temperatur in der Tabelle
4
i = 0;        // erster Tabelleneintrag
5
while (Tabelle[i] < ADWert) { i++; }
6
// Jetzt ist die Suche beendet und bei i ist der Punkt (X1, Y1)
7
X1 = Tabelle[i];    // X = ADWert
8
X0 = Tabelle[i-1];    // Y = gesuchte Temperatur 
9
Y1 = 5 * i  T_low ;    // Temperatur in 5°C-Schritten ab T_low 
10
Y0 = 5 * (i1)  T_low ;   // 
11
12
Temperatur = Y0 + (ADWert  X0) * 5 / (X1  X0);// Y1–Y0 ist konstant 5°C.
Wenn man Nachkommastellen haben will, dann rechnet man einfach in 1/10°C 
oder 1/100°C ganzzahlig. Mit signed int und 1/100°C kommt man dann von 
-273°C bis +327,67°C.

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Wulf D. schrieb:
> Die Tabelle im Datenblatt möchte ich ungern abschreiben.

Gib Dir einen kleinen Ruck, und dann klappt das schon. Und rechne ruhig 
mit float-Routinen; das ist nicht böse.
Ein Beispiel für einen KTY81 findest Du hier: 
http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#lcd7
Ob der 10 Bit ADC eines ATtiny reicht, müßtest Du noch nachrechnen.

von Wulf D. (holler)


Lesenswert?

Ja danke, das ist der Tabellenansatz mit linear Interpolation 
dazwischen. Funktioniert garantiert und ist genau.
Werde ich so machen den den Code übernehmen, wenn ich mit den 
arithmetischen Ansatz nicht weiter komme.

von Wolfgang (Gast)


Lesenswert?

Wulf D. schrieb:
> Die Tabelle im Datenblatt möchte ich ungern abschreiben.

Um eine Parabel durchzulegen, brauchst du mindestens 3 Punkte.
Das ist gerade noch abtipbar.
Aber nicht jede krumme Kurve wird gut durch eine Parabel beschrieben, 
also sind ein paar "Kontrollpunkte" auf jeden Fall angeraten.

von Wulf D. (holler)


Lesenswert?

Habe mir den Polynom aus den Phillips / NXP Datenblatt genauer 
angesehen. Im Temperaturbereich bis 230°C braucht man den kubischen Teil 
nicht.
Mittels der bekannten p-q Formel nach T umgestellt und ein kleines 
Programm mit 16 Bit Festkomma-Arithmetik getestet:
1
int16_t KTY84temp(uint16_t rt)
2
{
3
uint16_t p=rt>>2;
4
p=p*91;
5
p=p>>2;
6
p=p-846;
7
p=SQRT16(p);
8
p=p<<2;
9
int16_t q=-179+p;
10
return(q+3);
11
}
Integer Wurzelziehen wurde schon im Forum gepostet, wiederhole ich der 
Vollständigkeit halber:
1
/*
2
Hier ein Algorithmus der aus einer Integer die Wurzel zieht. Er ist
3
schnell (kleiner 200 Takte) und kurz (ca. 100 Bytes).
4
Quelle:
5
https://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
6
*/
7
uint16_t SQRT16(uint16_t op)
8
{
9
  uint16_t res = 0;
10
  uint16_t one = 1 << 14; // The second-to-top bit is set: 1L<<30 for long
11
  // "one" starts at the highest power of four <= the argument.
12
  while (one > op)
13
  {
14
    one >>= 2;
15
  }  
16
  while (one != 0)
17
  {
18
    if (op >= res + one)
19
    {
20
      op -= res + one;
21
      res += 2 * one;
22
    }
23
    res >>= 1;
24
    one >>= 2;
25
  }
26
  return (res);
27
}

Die Ergebnisse:
1
Widerstand  Temperatur  Temperatur
2
gemessen    Datenblatt  16Bit gerechnet
3
[Ohm]       [°C]        [°C]
4
498         0           0
5
1000        100         100
6
1982        230         232
7
2166        250         252

Die Auflösung des ADC sollte kein Problem darstellen, um einen 16Bit 
Überlauf zu verhindern, wird der Widerstand in der Rechnung gleich um 
Faktor 4 geteilt (Fractional).

Was ist nun effektiver: Rechnen oder Tabelle?
Ich weiß es nicht. Egal, es funktioniert so.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.