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 :-)
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.
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 * (i–1) – 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
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.