Hallo,
im Rahmen eines 12-bit Labornetzteils, bin ich dabei die
Temperaturmessung zu implementieren.
Zu dem poste ich mal meine entworfene Funktion:
uint16_t meastemperatur(){
tmpspg=GetADC(2);//funktioniert
tmpspg=(double)tmpspg*(5.0/1024.0);//funktioniert
Rntc=(double)((1.0/1000.0)*(5.0-tmpspg)/((tmpspg/22000.0)));//funktionie
rt
measuretemperatur=(double)(1/(A+(B*log(Rntc/Ref))
+(C*pow((log(Rntc/Ref)),2))+(D*pow((log(Rntc/Ref)),3))));//hier ist der
Fehler!!!
return measuretemperatur;
}
//sorry irgendwie krieg ich die Einrückungen hier nicht richtig hin...
Ich hab die Variablen alle als double (ausser measuretemperatur dort
sollte uint16_t reichen) deklariert, trotzdem kommt in der Anzeige immer
"0".
Das Forum hab ich diesbezüglich auch schon durchsucht, allerdings konnte
ich nicht wirklich Hilfe finden.
Würde mich freuen, wenn jemand einen Fehler in der Formel
measuretemperatur findet.
Math.h is included
Danke
+(D*pow((log(Rntc/Ref)),3))));//hier ist der Fehler!!!
8
9
returnmeasuretemperatur;
10
}
Du willst mit measuretemperatur ein Double zurückgeben, meastemperatur
ist aber als uint16_t deklariert, das kann schonmal nicht gut gehen.
Außderdem ist Fließkommaarithmetik auf dem AVR nicht so der Hit, siehe
Festkommaarithmetik Womöglich lassen sich deine Logarithmen und
Potenzen auch hinreichend genau durch eine ganzrationale Funktion
beschreiben, kannst du mal die Werte der Konstanten posten?
> measuretemperatur=(double)(1/(A+(B*log(Rntc/Ref))
+(C*pow((log(Rntc/Ref)),2))+(D*pow((log(Rntc/Ref)),3))));//hier ist der
Fehler!!!
Brich den Ausdruck in Einzelteile auf. SOlche Monsterausdrücke haben
hauptsächlich eines: Man vertippt sich ständig und auch die Gefahr, dass
man sich mit den Klammern vertut, steigt enorm an.
> uint32_t Rntc;
Wozu dann die ganzen double Rechnereien, wenn du in Rntc dann sowieso
wieder alles wegwirfst?
An dieser Stelle ist das kontraproduktiv.
Das Ergebnis der Berechnung
(double)((1.0/1000.0)*(5.0-tmpspg)/((tmpspg/22000.0)));
muss erst mühsam in einen uint32_t gewandelt werden, nur um dann in der
nächsten Berechnung wieder auf einen double konvertiert zu werden. Nette
Beschäftigungstherapie für den µC.
Karl Heinz Buchegger schrieb:> Wozu dann die ganzen double Rechnereien, wenn du in Rntc dann sowieso>> wieder alles wegwirfst?
Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur
dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den
Genauigkeiten.
Karl Heinz Buchegger schrieb:> Nebeneffekt: Durch den Wegfall der pow() Funktion ist es ausserdem auch>> noch schneller berechnet.
Najaaa, die pow Funktion soll nicht wegfallen, da lt. Datenblatt man mit
x log (...) + y log²(...) + y log³ (...) rechnen soll.
holger schrieb:> 1/... != 1.0/...
...das ist eine Idee, ich schliesse daraus, dass man das bei jedem
Zahlenwert, den man eingibt, tun muss?
Die double Berechnungen und Ausgaben als uint-Werte klappte bei anderen
Funktionen gut.
Markus schrieb:> Karl Heinz Buchegger schrieb:>> Nebeneffekt: Durch den Wegfall der pow() Funktion ist es ausserdem auch>>>> noch schneller berechnet.>> Najaaa, die pow Funktion soll nicht wegfallen,
doch, soll sie.
Denn ein Quadrat kann man auch einfacher berechnen als mit pow(x,2). Und
eine 3.te Potenz kann man einfacher berechnen als mit pow(x,3)
> da lt. Datenblatt man mit> x log (...) + y log²(...) + y log³ (...) rechnen soll.
Und was denkst du ergibt x * x ?
Und was ergibt x*x*x
Markus schrieb:> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den> Genauigkeiten.
Ach, dann spare dir die ganzen Rechnereien und rechne von Hand bzw. mit
dem Präprozessor den ADC-Wert aus, bei dem's zu warm wird.
Markus schrieb:> Karl Heinz Buchegger schrieb:>> Wozu dann die ganzen double Rechnereien, wenn du in Rntc dann sowieso>>>> wieder alles wegwirfst?>> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den> Genauigkeiten.
Wozu dann die ganze Rechnerei eines Polynoms 3.ten Grades, wenn es eine
Näherung auch tut.
Bist du sicher, dass du dich hier
const double A=3.354016;
const double B=2.993410;
const double C=2.13513E-06;
const double D=-8.05672;
beim D nicht mit dem Exponenten vertan hast? Ist der Sensor wirklich so
nichtlinear?
Karl Heinz Buchegger schrieb:> Bist du sicher, dass du dich hier>>>> const double A=3.354016;>> const double B=2.993410;>> const double C=2.13513E-06;>> const double D=-8.05672;>>>> beim D nicht mit dem Exponenten vertan hast? Ist der Sensor wirklich so>> nichtlinear?
...soweit steht es im Datenblatt, wahrscheinlich fehlt da etwas in
diesem Datenblatt, da bei allen Typen, die eine Stelle weniger haben
steht ...E-07, bei 2 oder drei Typen steht nur ...E also wusste ich auch
nicht was los ist und dachte mir , dass ich das Ergebnis schon rauskrieg
:-)
Studieren heisst ja auch rumprobieren...
Markus schrieb:> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den> Genauigkeiten.
Mein Vorschlag:
const int schwelle = 150; //Wert ist zu ermitteln
...
if(GetADC(2) > Schwelle)
abschalten();
:-)
Datenblatt genau lesen (s. Anhang).
Edit1:
Irgendwas stimmt im Datenblatt aber trotzdem nicht: Die Einheit aller
vier Koeffizienten sollte K¯¹ sein. Wenn dies der einzige Fehler ist,
sollte das Ergebnis aber trotzdem stimmen.
Edit2:
Wenn Rref=R25=22Ω ist, ist lt. Datenblatt der B25/85-Wert 3136K und
nicht 3390K. Die Koeffizienten sollten dann nach obiger Tabelle
A1=3.354016e-3
B1=3.243880e-4
C1=2.658012e-6
D1=-2.70156e-7
sein.
...so ich bins wieder, als erst einmal Danke an Euch alle,
die Hinweise mit den Größenordnungen und die Aufspaltung in Einzelne
Terme haben es letztlich gebracht.
Es kommen zwar ca. 25 Grad zu wenig raus aber das krieg ich schon
umgerechnet.
Der interne AD-Wandler oder der Vorwiderstand von 22K zu einem 68K-NTC
werden wohl nun die Ursache für die Abweichung sein,
aber das rechne ich schon irgendwie raus.
MFG
Markus schrieb:> Es kommen zwar ca. 25 Grad zu wenig raus aber das krieg ich schon> umgerechnet.
Dann ist da noch irgendwo ein grober Denkfehler drin.
> Der interne AD-Wandler oder der Vorwiderstand von 22K zu einem 68K-NTC> werden wohl nun die Ursache für die Abweichung sein,
Das glaube ich nicht. Der ADC ist wahrscheinlich genauer als der NTC und
22kΩ vor einem 68kΩ-NTC klingen auch nicht abwegig.
> aber das rechne ich schon irgendwie raus.
"Irgendwie" hat irgendwie immer ein ungewisses Ergebnis. Und irgendwie
habe ich das unbestimmte Gefühl, dass du noch nicht ganz verstanden
hast, wie man den NTC richtig anwendet ;-)
Wenn du mir folgende Fragen beantwortest, zeige ich dir, wie du systema-
tisch zum Ziel kommst:
1. Um welchen Typ von NTC handelt es sich genau? Wenn es der ist, den
ich vermute, kommt er von Vishay/BCcomponents und hat eine Typbe-
zeichnung der Form "2322 640 nnnn", wobei jedes n für eine Ziffer
steht. Wenn du den genauen Typ kennst, weiter mit (5).
2. Welchen R25-Widerstand hat der NTC? Sind die 68kΩ aus deinem letzen
Beitrag sicher oder nur vermutet? Wenn du dir 200%ig sicher bist,
weiter mit (5).
3. Hat der NTC Farbringe? Die o.g. Serie hat bspw. vier davon. Welches
sind deren Farben, von unten nach oben? Wenn der NTC mindestens drei
Farbringe hat, weiter mit (5).
4. Miss den Widerstand bei Zimmertemperatur in ausgebautem Zustand mit
einem Ohmmeter und gleichzeitig die Umgebungstemperatur mit einem
ordentlichen Thermometer. Fass dabei den NTC mindestens 1 Minute vor
der Messung nicht mit den Fingern an, damit er nicht zusätzlich er-
wärmt wird. Wie hoch ist der Wider- stand und die Temperatur?
5. Wie ist der NTC geschaltet? Wenn ich dich richtig verstanden habe
liegt er in Reihe zu einem Vorwiderstand an 5V. Wenn das stimmt:
Welcher der beiden Widerstände liegt an 5V und welcher an Masse?
6. Welchen Temperaturbereich (Minimum, Maximum) möchtest du messen?
Davon hängt die richtige Wahl des Vorwiderstands (oder ggf. einer
geeigneten Verstärkerschaltung) ab.
7. Wie hoch ist die Referenzspannung des A/D-Umsetzers?
8. Welche Genauigkeit und welche Auflösung in K soll die Messung haben?
Nur wenn du zielgerichtet vorgehst, hat die von dir programmierte kom-
plizierte Formel einen Sinn. Wenn man du eine der vielen Einflussgrößen
außer Acht lässt oder dabei von falschen Annahmen ausgehst, wird das
Ergebnis ungenau, und es ist schade um die Rechenzeit, die diese Formel
verschlingt.
Markus schrieb:> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den> Genauigkeiten.
Also nur <> kritische temperatur
Yalu X. schrieb:>[...]> Nur wenn du zielgerichtet vorgehst, hat die von dir programmierte kom-> plizierte Formel einen Sinn. Wenn man du eine der vielen Einflussgrößen> außer Acht lässt oder dabei von falschen Annahmen ausgehst, wird das> Ergebnis ungenau, und es ist schade um die Rechenzeit, die diese Formel> verschlingt.
Wozu das ganze? Mit nem Fön oder wie auch immer den NTC erwärmen,
Thermometer dranhalten, Spannung messen, in ADC-Wert umrechnen, fertig.
Luk4s K. schrieb:> Wozu das ganze? Mit nem Fön oder wie auch immer den NTC erwärmen,> Thermometer dranhalten, Spannung messen, in ADC-Wert umrechnen, fertig.
Ja klar, das geht auch. Nur ist dann die Diskussion um Monsterformel im
Eröffnungsbeitrag mit den auf 7 Stellen genauen Koeffizienten für die
Katz.
Luk4s K. schrieb:> Markus schrieb:>> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur>> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den>> Genauigkeiten.
Huch, das habe ich völlig übersehen :)
Dann genügt ja ein simpler Schwellwert, und es muss praktisch gar nichts
gerechnet werden. Dafür ist aber so ein "Accuracy Line"-NTC eigentlich
viel zu schade ;-)
Markus schrieb:> Ich brauche nur einen Temperaturwert, der muß nicht mal genau sein, nur> dass ein Transistor im Überlastfall abgeschalten wird, daher weg mit den> Genauigkeiten.
Wenn Du den Vorwiderstand = dem NTC-Widerstandswert deiner
Schaltschwelle machst kannst Du davon ausgehen daß die Kennlinie in
einem Bereich +/-15 Grad um die Schaltschwelle halbwegs linear ist
(Linearitätsfehler ca 0,3 Grad). Gleichzeitig hast Du bei dieser
Dimensionierung die maximale Empfindlichkeit.
Da reicht dann ein wenig 3-Satz und 32Bit Integer-Arithmetik.
Gruß Anja
Yalu X. schrieb:> Dann genügt ja ein simpler Schwellwert, und es muss praktisch gar nichts> gerechnet werden.
Und wie soll dann der Flash voll werden?
So lagen wenigstens die Floating Point Routinen da drinnen und der µC
hatte was zu tun. :-)
Karl Heinz Buchegger schrieb:> Yalu X. schrieb:>>> Dann genügt ja ein simpler Schwellwert, und es muss praktisch gar nichts>> gerechnet werden.>>> Und wie soll dann der Flash voll werden?> So lagen wenigstens die Floating Point Routinen da drinnen und der µC> hatte was zu tun. :-)
Ich gehe mal davon aus, dass das Netzgerät nen alphanum. LC-Display
bekommt
Wie wär's mit div Hilfetexten und Serviceanleitungen, die Beschreiben,
was bei zu warmem Transistor zu unternehmen ist? ;)