Hallo Forum,
neulich habe ich eine wirklich saubere Funktionssammlung für NTCs von
Davide Gironi gefunden welche Funktionen für Beta und auch
Steinhart-Hart beinhaltet.
http://davidegironi.blogspot.co.at/2012/12/reading-temperature-on-avr-atmega-using.html
Ich wollte ausprobieren wieviel der Unterschied bei der Verwendung von
Beta-Values und der Steinhart-Hart Methode ist.
Das Auslesen des ADCs liefert einen NTC-Widerstand von 9100Ohm (Was für
einen 10k-Typen recht plausibel klingt.)
SH:
Mit den Koeffizienten von meinem 10k NTC-Sensor erhalte ich für
gemessene 9100Ohm als Resultat 17434°C. Das ist ziemlich warm, ja fast
Rekordverdächtig.
Beta:
Dann habe ich die Funktion für Beta probiert.
Diese liefert -15605°C!!!
Als Physiker würde ich jetzt den Nobelpreis beantragen.
Ich habe daraufhin mein Datenblatt verifiziert und das Beta-Value dort
eingegeben:
http://www.daycounter.com/Calculators/Steinhart-Hart-Thermistor-Calculator.phtml
Die Website berechnet mir 27°C für meinen Widerstand.
Offenbar rufe ich die Funktionen falsch auf.
Könnt ihr den Fehler erkennen?
Beta:
1
// Call
2
longl;
3
doubled;
4
l=adc_getresistence(adc,10000);
5
d=ntctemp_getB(9100.0,3970,25.0,10000);
6
7
// Function
8
/*
9
* get temperature using Beta Model Equation
10
*
11
* "adcresistance" adc resistence read
12
* "beta" beta value
13
* "adctref" temperature reference for the measuread value
14
* "adcrref" resistance reference for the measured value
Solche Fragen beantwortet man mit Taschenrechner und Debugger. Genau für
solche Probleme wurden die erfunden.
Am besten die Berechnungen in Einzelschritte zerlegen, duchsteppen, und
schauen, was wo schief geht.
Das ist seit Menschengedenken Programmieralltag. Da musst du durch.
Oliver
Von der Funktion adc_getresistence() bekomme ich folgenden Wert: 9320
Das klingt bei einem 10k NTC ganz normal.
Diesen Wert gebe ich an ntctemp_getB() oder ntctemp_getSH() weiter.
Das mit dem 'left justified' werde ich mir jetzt noch genauer ansehen.
Das Datenblatt hat Shibaura
http://www.shibauraelectronics.com/html/products/p_sensor_pre_a.html
leider nicht online. Ich müsste den Ausdruck einscannen...
@ Oliver, ja genau so debugge ich im Visual Studio auf dem PC. Mit einem
µC ohne Debugschnittstelle, ohne Display ist das nicht so einfach, werde
ich natürlich trotzdem bewerkstelligen wenn herauskommt, dass kein
offensichtlicher Anfängerfehler vorliegt.
Danke so weit...
Lg,
Tom
Taucher schrieb:> @ Oliver, ja genau so debugge ich im Visual Studio auf dem PC. Mit einem> µC ohne Debugschnittstelle, ohne Display ist das nicht so einfach, werde> ich natürlich trotzdem bewerkstelligen wenn herauskommt, dass kein> offensichtlicher Anfängerfehler vorliegt.
dann nimmt den code doch mal auf den PC und schau was dort rauskommt.
Hab jetzt meine Glaskugel augepackt.
Beachte die Skalierungsfaktoren in dem PDF.
http://assets.newport.com/webDocuments-EN/images/AN04_Thermistor_Calibration_IX.PDF
-->R=9100;A=1.123219e-3;B=2.35988061e-4;C=7.3295648e-8;
-->T=1/(A+B*log(R)+C*(log(R))^3)
T =
300.29858
-->T1=T-273.15
T1 =
27.148583
Die Nagelprobe:
-->R=10000
R =
10000.
-->T=1/(A+B*log(R)+C*(log(R))^3)
T =
298.15
Das entspricht exakt 25°C.
Beachte, dass in Matheprogrammen und allgemein in englischsprachigen
Ländern "log" zur Basis e ist, also dem deutschen "ln" entspricht.
Vielleicht ist "ln" sogar nur in deutschsprachigen Ländern gebräuchlich.
Nachtrag zum Programm
Falsch:
float t;
t = log( adcresistence );
t = 1 / (A + (B*t) + (C*t*t*t));
t = t - 273.15; // convert Kelvin to Celcius
Richtig:
float r, t;
r = log( adcresistence );
t = 1 / (A + B*r + C*r*r*r);
t = t - 273.15; // convert Kelvin to Celcius
>Falsch:> float t;> t = log( adcresistence );> t = 1 / (A + (B*t) + (C*t*t*t));> t = t - 273.15; // convert Kelvin to Celcius>Richtig:> float r, t;> r = log( adcresistence );> t = 1 / (A + B*r + C*r*r*r);> t = t - 273.15; // convert Kelvin to Celcius
Und warum? Wo ist der Unterschied? Ich kann keinen Fehler entdecken.
> Warum gibs du 9100.0 - das musz doch einen LONG sein oder ???
Wenn ein ordentlicher Funktionsprototyp vorhanden ist, dann weiß der
Compiler schon, wie man aus einem double einen long macht.
Im Ausgabecode könnte auch noch ein Fehler stecken.
Wenn man die Bytes eines double einer int-verarbeitenden Funktion auf
Byteebene unterjubelt, dann werden da auch die schrägsten 'Ergebnisse'
auftauchen.
-> kompletter, kombilierbarer Code
wenn sich da nichts findet, dann eben auf die Taschenrechnermethode. Mit
einem bekannten Eingangswert am Taschenrechner die Sache durchrechnen,
alle Zwischenergebnisse notieren (und checken ob das Endergebnis stimmt
:-) und dann das ganze nochmal mit dem µC, wobei man dann eben auch die
Zwischenergebnisse vergleicht. Zwischenergebnisse ansehen ist eine
Technik, die sich seit 60 Jahren bewährt hat.
> Und warum? Wo ist der Unterschied? Ich kann keinen Fehler entdecken.>
Weil du die Variable t falsch verwendet hast. Schau meinen Code an. Der
stimmt. Deiner nicht.
t = log( adcresistence );
Das ist doch einfach nur falsch.
Helmut S. schrieb:>> Und warum? Wo ist der Unterschied? Ich kann keinen Fehler entdecken.>>>> Weil du die Variable t falsch verwendet hast.
Na ja.
Falsch ist jetzt übertrieben.
t hat zwischendurch mal einen Wert, der nicht die Temperatur ist. Aber
falsch ist es deswegen nicht. Die 'Gültigkeitsbereiche' von r und t
überlappen sich nicht. Von daher ist es verzeihlich, die Variable in
diesem kurzen Code mal kurz zu zweckentfremden um darin den log zu
speichern.
Nachdem dann
1
....1/(A+(B*t)+(C*t*t*t))
berechnet wurde (mit t in der Funktion 'hält den Logarithmus'), kriegt t
dann seine endgültige Bedeutung einer Temperatur.
1
t=1/.....
und ab da wird dann der Logarithmus nicht mehr gebraucht.
Codemässig würde ich mal schätzen macht es keinen Unterschied, weil der
Compiler beide Variablen aufgrund der Einfachheit des Codes nicht
unbedingt anlegen muss, wenn er genügend Register frei hat.
Wie bereits Helmut S. halte auch ich die von Dir verwendeten
Koeffizienten für falsch. Insbesondere die Zehnerpotenzen von B und C
sind sehr ungewöhnlich.
Hier:
Beitrag "Re: NTC - Steinhart-Hart -> -15605°C (Weltrekord?)"
hat Helmut ja bereits plausiblere Werte aufgeführt.
Aber es muss noch ein anderer Fehler in Deinem Programm stecken, denn
selbst mit den falschen Koeffizienten kommt ein anderer Wert raus, als
von Deinem Programm berechnet.
Mit meinen Werten ist das Ergebnis richtig.
A=1.123219e-3
B=2.35988061e-4
C=7.3295648e-8
Ich verstehe gar nicht wo da jetzt noch ein Problem sein soll.
Helmut S. schrieb:> Mit meinen Werten ist das Ergebnis richtig.
Ja eben, das sehe ich ja auch so.
> Ich verstehe gar nicht wo da jetzt noch ein Problem sein soll.
Das Problem ist, dass selbst mit seinen falschen Koeffizienten nach der
Steinhart-Hart-Formel nie und nimmer 17434°C raus kommt. Hier teile ich
die Meinung von Karl Heinz, dass die Ausgabefunktion fehlerhaft ist.