Temperaturmessung mit KTY

Aus Ethersex_Wiki
Version vom 23. Juni 2009, 13:04 Uhr von Benson (Diskussion | Beiträge) (Temperaturen mit dem ATmega messen)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Temperaturen mit dem ATmega messen

Es ist doch ziemlich interessant wie warm es denn nun drauszen ist. Daran kann man dann auch festmachen, ob man raus geht oder nicht. Also ist es eine prima Sache Temperaturen zu messen.

Es gibt verschiedene temperaturabhaenige Wiederstaende. Zum einen gibts da die PT100 und PT1000. Die sind wahnsinnig linear, wahnsinnig genau (0,001 %) und wahnsinnig beschissen auszulesen ;) Weil einfach die Verstaerkerschaltung die man fuer die Teile braucht immer zu einem gewissen Teil zu ungenauigkeiten fuehren wird. Und auszerdem sind sie auch noch ziemlich Teuer. Werden halt massiv in der Industrie eingesetzt.

Zum anderen gibts da die KTY Reihe. Deren Kennlinie ist zwar unlinear, was sich aber in Software relativ einfach rausrechnen laesst. Und die Genauigkeit liegt maximal bei 0,5 %, was aber auch nicht schlimm ist, wenn mans nur aufs Grad genau haben will. Der grosze Vorteil bei denen ist eben, dass sie Unschlagbar guenstig sind ( 60 Cent das Stueck ) und sie kaum ne Auszenbeschaltung brauchen.

Man koennte jetzt natuerlich einfach hergehen, und sie als einfachen Spannungsteiler mit einem anderen Wiederstand an den ADC des ATmegas klemmen, womit wir dann wir dann aber die Aufloesung des ADC auf 5V verteilt haben und daher auch Bereiche Abdecken die der KTY nie erreichen wird.

Deswegen machen wir uns eine andere Referenzspannung die niedriger liegt, als die Versorgungsspannung des ATmegas. Damit bekommen wir dann einen kleineren Messbereich, mit hoeherer Aufloesung. Fuer die Referenzspannung nehmen wir die Versorgungsspannung und halbieren sie mittels eines Spannungsteilers. Jedoch hat der ATmega auf ARef nur 32 KOhm Eingangswiederstand. Deswegen muessen wir die halbierte Spannung noch durch einen Operationsverstaerker unter Last stabilisieren. Und um das ganze noch gegen Spannungsspitzen abzufedern legen wir noch einen Low-Pass vor alles Analoge.

Was auch noch sehr wichtig ist, ist der Abblockkondensator fuer den ATmega, da sonst komische Dinge mit den Messwerten geschehen. Die Wiederstaende fuer die Spannungsteiler sollten relativ genaue Metalschichtwiederstaende sein, die veraendern ihren Wiederstand auch nicht so stark mit einer Temperaturaenderung.

Und hier mal der Schaltplan fuer das ganze:

Kty-temperatur.png

Das ganze dann mit dem ADC vom ATmega ausgelesen und nach folgender Formel berechnet (C-Code)

float aT = -167.123;
float bT = 0.275501;
float cT = -0.000102316; 
float dT  = 1.92025e-08;

float volt = (2.5/1023)* adcwert;
float R = 2200/(5 - volt) * volt;
float temperatur = aT + R*( bT + R*( cT + R*dT));

printf("%3.1f\
",temperatur);

Das ganze sollte man so vielleicht nicht auf einem AVR machen, der kann naemlich kein Flieszkomma berechnungen in Hardware und muss daher alles in Software nachbilden, was zum einen Flash und zum anderen Zeit kostet.


Tempertur Berechnung im AVR

und wie wir da drauf gekommen sind. gnuplot ist dazu wirklich sehr sehr nützlich gewesen. Dazu auch eine Grafik die sehr Aussagekräftig ist:

Kty81-110-formeln.png

wers selbst mal ausprobieren will:

set xrange [500:2000]
plot "kty81-110-x10.txt",(-59072 + 74 * x) / 64,(-60000 + 76 * x) / 64,(-140995 + 173 * x) / 128,  (-94379 + 131 * x) / 128

kty81-110-x10.txt enthält diese werte:

# KTY81-110
# resistance/Ohm T/degree celsius (*10)
#490   -550
#515   -500
#567   -400
#624   -300
684   -200
747   -100
815    0
886   100
961   200
1000  250
1040  300
1122  400
1209  500
1299  600
1392  700
1490  800
1591  900
1696  1000
1805  1100
#1915  1200
#1970  1250
#2023  1300
#2124  1400
#2211  1500

das führte uns dann zu diesem code:


  int32_t volt = sensorwert;
  volt *= 2500;
  volt /= 1023;
  int32_t R = 2189L;
  R *= volt;
  R /=  5000L - volt;
  int32_t temper;
  if (R > 1110){
    temper = -94379;
    temper += 131 * R;
  }
  else{
    temper = -140995;
    temper += 173 * R;
  }
  temper /= 128;