Temperaturumrechnung KTY81

Moin,

ich versuche mit einem KTY81-220 Temperatur zu messen.
Die dafür bekannten Seite Temperaturmessung und habe ich durchgelesen.
Doch letztlich funktioniert die Umrechnung bei mir nicht.
Ich benutze einen Vorwiderstand von 3kOhm und rrechne mit folgender Formel:

void loop ()
{
  int tempRaw = analogRead(TempPin); //Digitaler Input-Wert wird zu Variable TempRaw
  //Umrechnung von tempRaw Grad Celsius
  //RL: 2870Ohm (Spannungsteiler) 
  //U0: Spannung am PTC bei 0°C
  //U20 u. U30: Spannung am PTC bei 20°C und 30°C
  //R20 u. R30: Widerstand des PTC "
  //URef: 5V (Betriebsspannung)
  //dT: Spannungs- Änderung pro Kelvin
  //Uin: Spannnung am ADC Eingang des µC
  //TC: Temperatur in °C

  //U0 = R0 / (RL + R0) * URef
  //U20 = R20 / (RL + R20) * URef
  //U30 = R30 / (RL + R30) * URef
  //dT = (U30 - U20) / 10.0
  //Uin = (ADC * URef) / 1023 - U0
  //TC = Uin / dT
  float U0 = 1630.0/(3000.0+1630.0)*5.0;
  float U20 = 1922.0/(3000.0+1922.0)*5.0;
  float U30 = 2080.0/(3000.0+2080.0)*5.0;
  float dT = (U30-U20)/10.0;
  float Uin = tempRaw/1024.0*5-U0;
  float tempC = Uin/dT;

Die Werte die ich bekomme Stimmen hinten und vorne nicht. Sieht da jemand den Fehler?

MfG

norman

Wie sieht denn die Schaltung dazu aus?

Deine Formeln lassen vermuten, dass der KTY82 an 5V hängt, und der Vorwiderstand an Masse. Ist das korrekt?

Und dann scheinst du mit deiner Interpolation auch nicht ganz richtig zu liegen:
Du rechnest die lokale Sensitivität aus mit

dT = (U30-U20)/10.0;

wendest aber darauf die absolute Spannung an.

float tempC = Uin/dT;

Korrekt wäre meiner Meinung nach aber:

float tempC = (Uin-U20)/dT+20.0;

U20 und die zugehörige Temperatur kennst du ja schon.
Interpolieren mußt du nur den Teil, der zwischen U20 und U30 liegt.

ich mag mich aber auch irren...
Auch scheint es mir ein Overkill zu sein, das alles mit float zu rechnen. Aber da sollen sich mal die Spezialisten dazu äussern.

Gunther

Zum einen ist Deine Formel so ausgelegt, dass der Widerstand linear ansteigt, Du interpolierst linear den Bereich von 20° bis 30°. Ein KTY81 ist aber eben nicht linear.
Zudem stellt sich die Frage, woher Du die Referenz-Widerstandswerte für 0°, 20° und 30° hast, von der von Dir verlinkten Seite auf jeden Fall nicht.

Die Schaltung habe ich von hier übernommen: Arduino Playground - KtyTemperatureExtDe
Den Vorwiderstand habe ich von 2,7 auf 3,0kOhm erhöht, da ich diesen zur Hand hatte.

Die Widerstandswerte habe ich aus dem Datenblatt des Herstellers.

Mir reicht auch eine Genauigkeit von +/-1°C

Hallo!

Genauigkeit von 1K ist schon eine sehr sportliche Anforderung.

Zweipunktkalibrierung ist unabdingbar.

Wenn Du einen Kty81-220 verwendest, sollte der Vorwiderstand 5.4KOhm sein.

MfG

Hallo,

ich denke da kann ich auch mal jemanden helfen. Ich nehme zwar einen KTY10-6, das Prinzip ist aber gleich. Als Vorwiderstand habe ich einen Rv mit 5540 Ohm (ausgemessen), der hängt an 5V und daran der KTY10-6 gegen Masse. Dazwischen greife ich die Spannung ab zum µC. Die A/D Digit für 0 und 100°C habe ich, und das mußt Du auch, ausgemessen mit Topf kochenden Wassers und kaltes Wasser mit Eiswürfel. Der Rest ist eine Verhältnisgleichung. Ich muß aber zugeben, ganz genau ist das immer noch nicht aber funktioniert erstmal in den Bereich was erwartet.

// Abkürzungen 
#define uint  unsigned int           
#define uchar unsigned char

// Deklaration Datentypen und Variablen

uint KTY10Temp;		        // AD-Wert in Digits 
long wertK;
float TempGrad;
long SensorNull = 233;		// kalibrierter A/D Digitwert = Temperatursensor   0°C
long Sensor100  = 368;		// kalibrierter A/D Digitwert = Temperatursensor 100°C
long SensorOffset = 0;          // A/D Digit Offset

void setup()
{
  Serial.begin(9600);    // startet den serial port:
}

void loop()
{

    KTY10Temp = analogRead(7);                                              // A/D Wandler einlesen an Pin 7
    wertK = (long) KTY10Temp+SensorOffset;				// A/D Wandler Wert an wertK übergeben + ggf. Offset
    wertK = ((wertK-SensorNull)*1000/(Sensor100-SensorNull));	// Bsp. KTY10Temp = 270 | Berechnung | wertK = 238
    TempGrad = (float) wertK/10;                                           // aus 238 werden 23.8°C, für die folgende Terminalfensterausgabe
                  
    Serial.println(KTY10Temp);
    Serial.println(wertK);
    Serial.println(TempGrad,1);
    Serial.print("C");
    
}

Die Schaltung habe ich von hier übernommen: Arduino Playground - KtyTemperatureExtDe
Den Vorwiderstand habe ich von 2,7 auf 3,0kOhm erhöht, da ich diesen zur Hand hatte.

In dieser Schaltung liegt der Vorwiderstand an 5V, der Kty an Masse.

Aber mit dieser Formelzeile

float Uin = tempRaw/1024.0*5-U0;

berechnest du es genau anders herum. Streich das "-U0" weg und es passt wieder.

die lineare Interpolation in 10° Schritten ist ok, das reicht völlig aus. Der KTY ist zwar nicht völlig linear, aber hinreichend.
Wobei du die Genauigkeit von 1 Grad ohne Abgleich sicher nicht erreichen wirst.

Alleine der Kty hat 2,5°C Toleranz, dazu die Toleranz deines Vorwiderstandes und die Toleranz des AD-Wandlers.
Ohne Abgleich schaffst du da vielleicht 5° Genauigkeit!

Und zur Interpolation: ich habe ja im letzten Post schon geschrieben, dass da ein Fehler drin ist.
such doch mal nach "linearer Interpolation" da gibts genügend Literatur und Beispiele im Netz, auch wie man es ohne "float" hinkriegt.

Grüße

Gunther

Danke für die fixen Antworten.

ich habe jetzt die Lösung von Doc_Arduino verwendet und meinen Sensor kalibriert.

Bei 5,47kOhm Vorwiderstand habe ich bei 0°C 245 Digits am Analogeingang, bei 100°C 394. Ist ja wirklich nicht optimal die Range, aber für meine Anwendung sollte das genau genug sein.

Der Rest des Codes funktioniert auch wunderbar und ich kann jetzt Temperatur auslesen. Danke.

Ein anderes Problem, das ich habe ist die Erstellung eines mehreren Minuten langen Timers, dessen Länge über einen Poti einstellbar sein soll.

Ich habe das wie folgt gelöst

int potiPin = A1;
void setup ()
{
  Serial.begin(9600);
}

void loop()
{
  int poti = analogRead(potiPin);
  poti = map(poti, 0, 1023, 180, 720);
  long potiTime = poti*10;
  Serial.println(potiTime); 
  Serial.println(analogRead(potiPin));
  Serial.println(poti);
  
  for(int i = 0; i <= 100; i++){
    delay(potiTime);
  }
  int time = millis();
  Serial.println(time);
}

Das Problem, auf das ich gestossen bin ist, dass ich den analog ausgelesenen Wert, nicht einfach auf 180000 bis 720000 mappen kann. Auch in der Zeile long potiTime = poti*10; Erhalte ich bei Multiplikation mit einem größeren Faktor als Ergebnis negative Werte, obwohl ich extra long benutze. Sollte das nicht anders sein?
Als Behelf daher der Umweg über die for-Schleife.

Gibt es dafür eine elegantere Lösung?

vieleicht statt
int poti = analogRead(potiPin);
gleich ein long nehmen.
Grüße Uwe

Danke Uwe, du liegst richtig. Das war mein Fehler. Jetzt klappt's

Ich hänge mich mal kurz hier mit rein. :wink:

Folgende Frage:
ich habe seit kurzem nun auch einen Arduino (uno) und habe mir nun eine große Ladung an Sensoren/Kondensatoren/Widerständen/Shields
usw. bestellt, da ich möglichst viel zum Testen erstmal nachbauen möchte :slight_smile:

Nun habe ich mal versucht meine Temperatur Sensoren (KTY81-220) zum Laufen zu bringen.
An sich klappt das auch "einigermaßen" (ca. 3 Grad daneben).
Ich benutze einen 5,4k Ohm Vorwiderstand.

Nun habe ich ein wenig im Netz nach weiteren Möglichkeiten des Anschlusses gesucht, und folgendes gefunden:
http://web30.server28.campusspeicher.de/lima05/media/pdf/avr/Analog.pdf -> Folie 7.

Da wird ein 2,7k Widerstand genommen.
==>Warum?

Tut mir Leid wenn ich sowas vermutlich einfaches Frage, jedoch habe ich bisher nichts mit diesem Bereich zu tun gehabt^^

Fischchen:
Da wird ein 2,7k Widerstand genommen.
==>Warum?

Tut mir leid, warum die das so gemacht haben weiß ich nicht, aber 2,7k ist auch (gerade) noch möglich.

Laut Datenblatt sollte der Messstrom des KTY81 nicht über 1mA liegen.
Mit einem 2.7k Vorwiderstand liegt der Messstrom bei Raumtemperatur:
Imess = 5V / (2.7K + 2k) = 1.06mA (R25 des Kty81-220 = 2k)

Du mußt halt deine Berechnung immer an den von dir verwendeten Widerstand anpassen.
Idealerweise ist der Vorwiderstand so groß wie der Widerstand des kty81 bei der Temperatur, die dich am meisten interessiert, denn dann ist die Genauigkeit dort am größten. (aber die 1mA Grenze beachten!)

Für die Messung der Raumtemperatur ist also 2,7k ein guter Wert.
Wenn du aber die Öltemperatur deines Autos messen willst, ist ein Wert um die 4k besser. Aber da geht es nur darum das letzte Quentchen an Auflösung rauszuholen. Funktionieren tut beides.