Anzeige:

Temperaturmessung über Atmega 16

Hier finden sie die archivierten Beiträge des alten PHPBB Forums von www.loetstelle.net

Von niki1 am 12.01.2009 18:44

Hallo.

Ich hab jetzt ein Diagramm nur weiß ich nicht wie du das gemeint hast mit den Werten die der ADC ausgibt , was gibt den der für Werte aus?

Oke...
Aber hier verstehe ich nur BAHNHOF,

Zitat:

Dann die Umkehrfunktion von dem ganzen Dingens.
Das wird aehnlich nichtlinear ausfallen. Solche Kurven kannst du dann durch Potenzreihen approximieren. Ich glaub', dass sogar im Excel eine Funktion dafuer drinnen ist, die dir ein Polynom bestimmter Ordnung ausspuckt, was moeglichst gut durch deine Messpunkte geht - da bin ich mir aber nicht sicher, ich arbeite nicht mit Excel.
Je hoeher die Ordnung, desto genauer die Approximation.
Wuerd' ich aber erstmal nur mit einem Polynom 2.Kajuete anfangen, also einer quadratischen Funktion.
Diese Funktion liefert dir dann fuer den gegebenen Wert des ADCs die dazu gehoerige Temperatur - und schon ist's fertig Smile


Danke für die Bemühungen

Mfg niki1

Von BellaD am 12.01.2009 21:42

moin

Zitat:
die der ADC ausgibt , was gibt den der für Werte aus?


falls sich dir die Frage stellen sollte ' Was ist ein Microkontroller ? ' dann solltest du hier einmal nachlesen :

http://www.mikrocontroller.net/articles/AVR-Tutorial

http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC

viel Spaß

Von derguteweka am 12.01.2009 21:46

Moin,

niki1 hat folgendes geschrieben:
Hallo.

Ich hab jetzt ein Diagramm nur weiß ich nicht wie du das gemeint hast mit den Werten die der ADC ausgibt , was gibt den der für Werte aus?

Ja, halt einfach den nackerten Binaerwert. Wenn das, was weiter oben im Thread steht, hinhaut, dann waere das bei einem 10bit ADC ein wert zwischen 0 und 1023 - entsprechend einer Eingangsspannung zwischen 0 und 5V.


niki1 hat folgendes geschrieben:
Oke...
Aber hier verstehe ich nur BAHNHOF,

Jo, is normal - da wird's dann ein wenig arg mathematisch. Ich versuch's mal vorzurechnen:
Am Anfang hab' ich also den Widerstand des NTC bei verschiedenen Temperaturen, am Schluss soll ein Wert herauskommen, der in einem Display angezeigt wird. Als Wert sollte man vielleicht nicht direkt die Temperatur in °C haben, sondern vielleicht immer das Zehnfache davon. Dann kannst du auf dem Display eine Nachkommastelle darstellen und trotzdem nur mit Ganzzahlen arbeiten. Beispiel: Es hat 23.7 °C, dann sollte aus der Software die Zahl 237 rauskommen, die du dann auf dem Display (verziert mit dem Dezimalpunkt an der richtigen Stelle) anzeigen kannst.

Dazu greif' ich mir jertzt mal willkuerlich 3 Wertepaare aus deinem Diagramm raus:
A.) 5°C -> 14000 Ohm
B.) 25°C -> 6000 Ohm
C.) 50°C -> 2300 Ohm

Widerstaende kann der ADC nicht messen, sondern nur Spannungen. Also bau' ich einen Spannungsteiler aus einem Festwiderstand und dem NTC. Den Spannungsteiler betreib' ich mit 5V, die werden dann durch den Festwiderstand und den NTC in eine temperaturabhaengige Spannung geteilt.
Als Festwiderstand greif' ich blind in meine Bastelkiste und ziehe einen 8.2KOhm Widerstand raus.
Also 5V -> 8.2Kohm -> NTC -> Masse.
Die Spannung an der Verbindung aus NTC und 8.2Ohm geb' ich auf den ADC.
Damit krieg' ich fuer meine drei Faelle von oben folgende Werte:
A.) 5°C -> Messwert des ADC: 645
B.) 25°C -> " " " : 432
C.) 50°C -> " " " : 224
Hier kann man schon sehen, dass die Schaltung mit dem 8.2K Ohm Widerstand nicht so pralle ist, weil aus den moeglichen 1023 verschiedenen Werten des ADCs nur so gut 400 (=645-224) genommen werden. Aber ist mir jetzt erstmal wurscht, geht ja mehr ums Prinzip.
Also brauchst du jetzt eine Funktion, der du den Wert aus dem ADC uebergibst und dafuer einen Wert bekommst, der 10x so hoch ist, wie die Temperatur in °C.
Also eine Funktion, die durch diese 3 Punkte geht:
A'.) X=645, Y=50 (=> 5.0°C)
B'.) X=432, Y=250
C'.) X=224, Y=500
So, und jetzt sag' ich einfach mal: Die Kurve, die entstehen wuerde, wenn ich die 3 Wertepaare und noch viele andere Wertepaare in ein Diagramm zeichnen wuerde, ist ein Teil einer Parabel. Punkt.
Stimmt zwar wahrscheinlich nicht genau (warum sollte das denn jetzt ausgerechnet eine Parabel sein), ist mir aber wurscht, denn der Fehler den ich dabei mache ist klein genug, um ihn zu vernachlaessigen. Das nennt man eine Approximation.
(Ist zumindest besser, als wenn ich nur 2 Werte nehmen wuerde und die mit einer Geraden verbinden wuerde)
Eine Parabel entsteht durch eine quadratische Funktion, die sieht allgemein so aus:
Y(X)=a*X²+b*X+c

a,b und c weiss ich grad' noch nicht - dafuer weiss ich aber 3 Faelle fuer X und Y, naemlich die, ein paar Zeilen weiter oben, A', B' und C'.
Damit kann ich 3 Gleichungen mit den drei Unbekannten a,b und c aufstellen, indem ich fuer X und Y jeweils die Werte einsetz':

50 = a*645²+b*645+c
250 = a*432²+b*432+c
500 = a*224²+b*224+c
(Puh, das ist ein bisschen Fummelei, das zu loesen, ich hab' da schon mal was vorbereitet Very Happy ) Es kommt so ungefaehr raus:
a= 6.246e-4
b= -1.6116
c= 829.67

Also sieht meine Funktion so aus:
Y=6.246e-4*X²-1.6116*X+829.67
Zur Erinnerung: X ist der Wert, der aus dem ADC kommt, Y der Wert der dann die Temperatur in °C x10 darstellen soll.

Als kleinen Test exerziere ich das jetzt mal mit einer Temperatur von 40°C, da waere der Widerstand des NTC also so bei 3.5 KOhm, wenn ich's richtig aus deinem Diagramm ables'.
Spannungsteiler: 5V*3.5K/(8.2K+3.5K)=5V*0.2991=1.496V
ADC-Wert: 1.496V/5V*1023=306
Jetzt setz' ich die 306 in die Funktion ein und hoff' das fuer Y was vernuenftiges rauskommt...
y=6.246e-4*306²-1.6116*306+829.67 = 395.0
Hmmmmm - wuerde dann einer Temperatur von 39.5°C entsprechen - und nicht den 40°C. Unschoen, aber das kommt durch Ablesefehler (die 3.5KOhm hab' ich ja nicht genau abgelesen sondern eher so Pi*daumen*Bildschirmverzerrung) und natuerlich auch dadurch, dass ich weiter oben einfach mal so behauptet hab' dass das eine Parabel waere - was es ja nicht unbedingt ist, und deshalb ja auch nur 3 Punkte zum berechnen meiner Funktion herangezogen hab' (Bei mehr Punkten werden die vielen Gleichungen mit den vielen Unbekannten unangenehmer zu loesen, deshalb geht das auch irgendwie in Excel, ich weiss nur nicht wie). Aber immerhin bloss ein halbes Grad Fehler bei nur 3 verwendeten (ungenau von mir abelesenen) Messwerten, damit kann ich gut leben.

Aber weil ich grad so schoen am Tippen und Rechnen bin, probier ich doch mal, das ganze jetzt in 16bit Integer und mit Simpel-Arithmetik (=leicht in Assembler zu programmieren) zu berechnen; ich glaub' nicht, dass ein kleiner Prozessor mit Floatingpoints so gut umgehen kann.

c= 829.67, das rund' ich flott auf 830 auf.

b= -1.6116, naja das waeren so ca. -13/8

a= 6.246e-4 - Hmm, da nehm ich mal die Wurzel von a, das ist dann fast ziemlich genau so ungefaehr 13/512

Damit:
Code:
int16_t a,b,c;
int16_t x=read_from_adc();
c=830;
a=((x+x+x)<<2)+x; /* a=x*13 */
b=a;
a=(a+256)>>9; /* a=a/512; richtig runden, daher die +256 */
a=a*a; /* hier die einzige "richtige" Multiplikation */
b=(b+4)>>3;
y=c-b+a;


Als Test nehm' ich mal die Temperatur von 25°C. Damit sollte ja dann y so um die 250 rauskommen...
25°C, d.h. ADC Wert ist 432.
Der ganze Schmonz eingesetzt und durchgerechnet, komm ich auf y=249. Dafuer, dass ich nur eine kleine Multiplikation gebraucht hab' und den Rest nur durch Addition und Schieben erledigt hab', kann man doch nicht meckern Smile

Das ganze Verfahren laesst sich natuerlich noch so ziemlich an allen Punkten viel weiter optimieren. Ich hab's halt bloss einmal stumpf durchgerechnet, um zu gucken, was so geht....

Gruss
WK

Von A4Schorsch am 27.08.2012 23:16

Mahlzeit,
nach langer Suche bin ich auf diesen Beitrag gestossen. Ich habe ähnliche Probleme mit der Umsetzung. Die Ausführung in der letzten Anwort habe ich mit Begeisterung gelesen und auch so mal in Excel versicht umzusetzen.
Allerdings komme ich nicht dahinter wie ich die 3 Werte für A, B und C errechne. Mein Geber hat eine 5V Versorgung und eine recht breite Spreizung der ADC Werte.
1,8 °C = 730
10,8 °C = 641
20,7 °C = 536
30,6 °C = 445
40,5 °C = 358
50,4 °C = 281
60,3 °C = 221
71,1 °C = 169
76,5 °C = 147
84,6 °C = 119

Gibt es da ein besonderes Vorgehen .....ich habe was zu Polynomen gelesen nur fehlt mir noch der zündende Funke um es zu kapieren.
Könnte mich da jemand ins Bild setzen ?????

Danke
Schorsch

Von derguteweka am 28.08.2012 00:07

Moin,

Jaaa, also ich weiss nur, dass es mit Excel gehen muss. Ich hab' aber kein Excel, und auch keine Ahnung davon. Mit Matlab oder Octave geht's auch.
Das Verfahren heisst, mein' ich, irgendwas mit "least mean square", die Funktion in Matlab/Octave heisst "polyfit" - mit deinen Werten kommt sowas raus:
temp=1.1643e-04 * adc² - 2.2664e-01*adc + 1.0702e+02
wenn man dem polyfit sagt, er solls durch ein Polynom 2. Ordnung annaehren.

Das Verfahren, was ich hier vorher mal durchexerziert hab', ging nur von 3 Messwertpaaren aus, damit kann man dann 3 Gleichungen mit 3 Unbekannten (= den Koeffizienten des Polynoms) aufstellen. Die Methode mit dem polyfit, (oder auch Excel, wenn man weiss wie's geht) liefert aus mehr als 3 Wertepaaren ein Polynom n-ter Ordnung, das moeglichst wenig von den Werten abweicht. "Zu Fuss" wollt' ich das aber nicht mehr rechnen muessen Smile

Gruss
WK

Von A4Schorsch am 28.08.2012 08:39

Hallo
danke für die schnelle Antwort. In Excel habe ich die Ausrechnung der Formel aus deinem Beispiel mal nachvollzogen und die errechneten Werte verglichen. Händisch mit den Werte (A,B und C) zuspielen und hoffen mal den richtigen zutreffen ist Mumpitz. Ich werde heute Abend die Werte die du angegeben hast mal einpflegen und sehen ob ich die Wertepaare auch erhalte.
Von hier aus schon mal eien großen Dank.

Schorsch

Von A4Schorsch am 28.08.2012 21:43

Hallo, das war schonmal ein guter Ansatz.

Messwert =ADC-> berechnet -> Abweichung
10,8 °C = 641 -> 9,80 -> -1,00
20,7 °C = 536 -> 19,20 -> -1,50
30,6 °C = 445 -> 29,40 -> -1,20
40,5 °C = 358 -> 41,00 -> +0,50
50,4 °C = 281 -> 52,70 -> +2,30
60,3 °C = 221 -> 62,80 -> +2,50
71,1 °C = 169 -> 72,20 -> +1,10
76,5 °C = 147 -> 76,40 -> -0,10
84,6 °C = 119 -> 81,90 -> -2,70

Kann man das noch genauer ???? ich frage deshalb weil man bei der zuvor behandelten Aufgabe super nah dran war, quasi genau und ich jetzt in dem Beispiel zu weit weg bin. Wenn ich auf +- 0,5 °C Abweichung kommen würde das wäre schon echt super gut.

Wäre man mit einer Berechnung 3. Ordnung besser dran ????
Muß man die Programme kaufen oder geht die Berechnung auch mit der Demo.

Gruß
Schorsch

Von derguteweka am 28.08.2012 22:15

A4Schorsch hat folgendes geschrieben:
Kann man das noch genauer ???? ich frage deshalb weil man bei der zuvor behandelten Aufgabe super nah dran war, quasi genau und ich jetzt in dem Beispiel zu weit weg bin. Wenn ich auf +- 0,5 °C Abweichung kommen würde das wäre schon echt super gut.

Ja, klar gehts genauer, wenns in dem vorherigen Beispiel besser gepasst hat, dann war das reiner Zufall. Es ist halt eine Frage der Moeglichkeiten auf dem Rechner, der die Funktion berechnen soll. In Assembler mit Festpunktarithmetik sind Polynome hoeherer Ordnung schnell ein ganz schoenes Gewuerge.

A4Schorsch hat folgendes geschrieben:
Wäre man mit einer Berechnung 3. Ordnung besser dran ????

Geh' ich mal stark davon aus. Das waeren die Koeffizienten fuer verschiedene Ordnungen von linear bis 4. Kajuete:
Code:
-0.13084   92.44614
 1.1643e-04  -2.2664e-01   1.0702e+02
 -3.0667e-07   5.0326e-04  -3.6755e-01   1.2088e+02
 6.2404e-10  -1.3586e-06   1.1085e-03  -5.0472e-01   1.3092e+02


Wenn ich mir aber mal den Kurvenverlauf deiner Messwerte so anschau, sieht das tatsaechlich nicht sehr "parabelig" aus - eher "hyperbelig" (das kann ich jetzt nicht math. sauber nachweisen, es "sieht fuer mich halt so aus"). Dann kanns vielleicht besser laufen, wenn du nicht mit den ADC Werten direkt arbeitest, sondern mit Kehrwerten, also so was mit einer Hilfsvariablen:

helper=1/adc /* statt 1 geht auch jede andere Zahl != 0 */
temp=a*helper²+b*helper+c

Ob das dann genauer wird, wie wenn du mit einem Polynom 3 Ordnung ohne die Kehrwerte arbeitest - keine Ahnung; Versuch macht Kluch.

Was hast du denn an Rechenkapazitaet fuer die Funktion? int oder float? C oder Assembler oder sonstwas?

A4Schorsch hat folgendes geschrieben:
Muß man die Programme kaufen oder geht die Berechnung auch mit der Demo.


Von Matlab gibts mein' ich eine Studentenversion, Octave (www.octave.org) kost' nix. Sind aber beide knackig komplex.

Gruss
WK

Von A4Schorsch am 28.08.2012 22:47

Hallo,
puh da haust du mir aber was um die Ohren. Ich, als Unwissender, dachte es wäre einfacher.
Die Kurve gehört zu einem Messaufnehmer in einem Fahrzeug der eine 5V Versorgung hat und Druck und Temperatur ausgibt. Mit einer Diagnoseeinheit kann ich den Messwert auslesen, den ADC Wert hohle ich direkt aus dem Mega32. Nebenbei beschäfftige ich den Mega32 (soll mal ein Mega1284 werden) noch mit 2 Can Controllern per SPI. Die Druckkurve ich nahezu linear und per einfacher Faktorrisierung vollkommen okay. Der Tempmessaufnehmer ist halt irgendein Geber mit NTC Verhalten. Es gibt kein Datenblatt. Eine kleine/große Ungenauigkeit habe ich sowie so schon da die ausgelesene Temp nur 0,9 °C Schritte kann. Das macht die Abweichung natürlich wieder relativ.
Ich habe heute mal provisorisch mit einem Poti den Geber simuliert und den ausgelesenen Temperaturwert und den ADC in Excel mit geschrieben. Ich dachte zunächst an eine Datentabelle, aber das habe ich mit C noch nie gemacht.
Wie gesagt ich dachte berechnen wäre easy - war wohl nichts.
In dem Feld bin ich C Anfänger. Der Mega32 kann int und float.

Danke
Schorsch

Von derguteweka am 28.08.2012 23:20

Moin,

Jaaa, also mit dem Excel kann ich nix recht's anfangen. Hier mal ein Plot, der die verschiedenen Naerungen zeigt.
rueber: ADC Wert, rauf: Temperatur in °C
Schwarz: Messwerte
rot: lineare Naerung
gruen: quadratische N.
blau: kubische N.

Da kann man schon sehen, wie's von quadratisch auf kubisch besser wird; also dann mit der Funktion:
temp= -3.0667e-07*adc³ +5.0326e-04*adc² -3.6755e-01*adc +1.2088e+02

Bei so "fetten" CPUs solltest du keine Probleme mit der Rechnerei kriegen (wenn du nicht gerade zigtausend Werte pro Millisekunde brauchst).

Gruss
WK

Anzeige: