Guten morgen zusammen!
Ich wende mich an euch Experten mit folgendem Problem und hoffe, ihr
könnt mir einen Denkanstoß, bzw. etwas Hilfe geben:
Ich habe eine Messzelle, welche leider keinen linearen Verlauf hat - der
Verlauf ist eher parabelförmig mit dem größten Fehler in der Mitte.
Es handelt sich um einen DMS in einer Messzelle (Druck). Dessen Werte
verstärke ich mittels OPs und gebe diese Werte auf einen Diff.-ADC - von
da per SPI zum Microcontroller. Klappt auch alles wunderbar, jedoch sehe
ich bei den Werten, dass diese von den errechneten gerade im mittleren
Bereich etwas abweichen. Ist ja auch nicht so unüblich.
Der Fehler sieht in etwa so aus:
1
Fehler[%]
2
|
3
|**
4
|**
5
|**
6
|**
7
|**
8
|**
9
|**
10
------------------------------------------>
11
Druck
Nun würde ich diesen Fehler im Microcontroller gerne herausrechnen, weiß
aber nicht so richtig, wie ich das anstellen könnte. Ich bräuchte quasi
eine Formel, in die ich den ADC-Wert hindurchschicke und somit den
tatsächlichen Wert errechnet bekomme - ähnlich wie bei den
Platinsensoren, nur dass da halt feste Formeln gelten, da diese genormt
sind.
Mein Ziel wäre es, beispielsweise fünf Punkte aufzunehmen, von denen ich
weiß, dass sie genau 0%, 25%, 50%, 75% und 100% eines bestimmten Drucks
entsprechen.
Der Microcontroller müsste sich dann eine Formel selber erstellen und
diese dann weiter für seine Berechnungen verwenden.
Es wäre mir halt wichtig, dass der Controller das selber macht - ich
weiß wohl, dass ich die Werte in Excel eingeben könnte und mir eine
Gleichung ausspucken lassen könnte, aber da ich mehrere dieser Zellen
habe, wäre es super wenn das Controller-Intern passiert. Zumal es mich
generell interessiert, wie so etwas realisiert wird.
Kann mir da einer gedanklich unter die Arme greifen, ich weiß grad echt
nicht, wie man so etwas anstellt - ich wäre um jede Hilfe sehr dankbar!
Gruß, Harald
Du könntest die 5 Messwerte als Stützstellen für eine lineare
Interpolation verwenden. Also einfach Geraden durch die Punkte legen.
Geradengleichung lässt sich ja recht einfach berechnen.
MfG
Marius
Hä-jetzt Noch schrieb:> Der Standardansatz ist ein Polynom
Ja, das habe ich bereits gefunden, das ist ja auch das, was Excel einem
ausspucken würde, jedoch ist da ja kein Hinweis drauf, wie dieses
Polynom erstellt wird, also genauer genommen, wie die Koeffizienten
ermittelt werden.
Diese sind ja mitunter sehr klein, um doubles komme ich dann ja
höchstwahrscheinlich bei der Berechnung auch nicht herum, aber man kann
nicht alles haben - die Linearisierung wäre mir wichtig.
Aber wie könnte ich die Koeffizienten des Polynoms ermitteln?
HI Harrald,
Harald Wünsch schrieb:> in Ziel wäre es, beispielsweise fünf Punkte aufzunehmen, von denen ich> weiß, dass sie genau 0%, 25%, 50%, 75% und 100% eines bestimmten Drucks> entsprechen.>Aber wie könnte ich die Koeffizienten des Polynoms ermitteln?
du gehst folgendermaßen vor. Du stellst ein Gleichungssystem auf.
Soll heißen:
P bei 25% = a0 + a1* Pmess bei 25% + a2* (Pmess bei 25%)^2 + a3* (Pmess
bei 25%)^3
P bei 50% = a0 + a1* Pmess bei 50% + a2* (Pmess bei 50%)^2 + a3* (Pmess
bei 50%)^3
P bei 75% = a0 + a1* Pmess bei 75% + a2* (Pmess bei 75%)^2 + a3* (Pmess
bei 75%)^3
P bei 100% = a0 + a1* Pmess bei 100% + a2* (Pmess bei 100%)^2 + a3*
(Pmess bei 100%)^3
das sind 4 Gleichungen und 4 Unbekannte (a0-a3). Jetzt musst du das
Gleichungssystem lösen. Die Formeln die du dann für die einzelen a's
hast schreibst du in deinem Programm nieder, fertig jetzt kann der
Controller das errechnen.
Beachte je mehr Messpunkte du nimmst desto mehr Gleichungen kannst du
aufstellen und desto mehr Koeffizienten(a's) kannst du bestimmen und so
die Genauigkeit bliebig hoch treiben.
Das du dafür doubles brauchst glaube ich nicht, du musst halt nur etwas
mit der Festpunktarithmetik spielen, aber 16 oder sogar 32 Bit Variabeln
wirst du brauchen.
MfG
Harald Wünsch schrieb:> Ja, das habe ich bereits gefunden, das ist ja auch das, was Excel einem> ausspucken würde, jedoch ist da ja kein Hinweis drauf, wie dieses> Polynom erstellt wird, also genauer genommen, wie die Koeffizienten> ermittelt werden.
Du gibst vor, wie das Polynom auszusehen hat.
ZB
y = a*x + b*x^2 + c*x^3
x ist der Messwert und y ist dann der dich interessierende Wert
D.h du musst a, b, c bestimmen.
Wie machst du das.
Nun, du machst 3 Messungen (weil du 3 zu bestimmende Koeffizienten hast)
Du misst zb bei x gleich 0 einen Wert von 20. Bei 3 Messungen hast du
festgestellt
x y
---------
0 20
2 26
4 28
diese Werte kannst du in deine Polynomgleichung einsetzen für x und y
einsetzen und erhältst damit
20 = a*0 + b*0^2 + c*0^3
26 = a*2 + b*2^2 + c*2^3
28 = a*4 + b*4^2 + c*4^3
3 GLeichungen in 3 Unbekannten (stör dich nicht daran, dass deine
Unbekannten jetzt a, b und c heißen und nicht wie sonst x y z. Wir
wollen ja die Koeffizienten des ursprünglichen Polynoms bestimmen und da
sind die nun einmal unbekannt)
Das ist aber ein stink normales Gleichungssystem welches man zb mit
einem Gauss-Verfahren lösen kann. Als Ergebnis erhlät man die Werte für
a, b und c und hat damit die Koeffizienten parat, mit denen dann
beliebige Werte für x durch das Urpolynom
y = a*x + b*x^2 + c*x^3
gejagt werden können um daraus y zu erhalten.
Oh, da kommt ja recht schnell ziemlich viel Input für mich - vielen Dank
euch schonmal!!!
Das werde ich nun mal durcharbeiten.
Mit den doubles oder ints: Ich bekomme in Excel ja z.b. Werte mit
0,00010423577 x^2 - wie mache ich sowas ohne Fließkomma-Arithmetik?
Das ist mir noch unverständlich.
Harald Wünsch schrieb:> Mit den doubles oder ints: Ich bekomme in Excel ja z.b. Werte mit> 0,00010423577 x^2 - wie mache ich sowas ohne Fließkomma-Arithmetik?
Es gibt die einfache Variante, wenn du das Ganze um mehrere 10er
Potenzen verschiebst also z.b. 10^9 überall mit rein Multiplizieren.
Aber da die Werte sehr weit auseinander liegen werden, wirst du Zahlen
Modelle wie 8 bit vor dem Komma und 24 bit nach dem Komma, dh, 8,45678
stellt sich dann so da, in den Hochsten 8 bit steht die 8, in den 24 Bit
steht 45678, das hat aber zu Folge das du dir Funktionen für die
Multiplikation usw. selber machen musst. Bzw es gibt dazu auch Beispiele
bzw Bibliotheken im Netzt und auch hier im Forum ist das thema schon
durch gekaut worden.
Wobei du Koeffizienten die extrem viel kleiner sind vernachlässigen
kannst, sofern es deine Anforderung an die Genauigkeit zulässt.
MfG
Hallo,
nur mit integer zu rechnen, geht wohl nur mit passender Skalierung.
Wenn die Kurve schon augenscheinlich eine Parabel 2 Grades ist, würde
ich auch nicht versuchen mit einem Polynom vom Grade 10 diese
anzunähern, die Werte werden an den Enden de Definitionsbereiches
"grauselig"
Du suchst sicher etwas in Richtung Regression n-ten Grades.
http://de.wikibooks.org/wiki/Mathematik:_Statistik:_Regressionsanalyse
oder
http://www.wiwi.uni-rostock.de/~stat/vorl_gs/Regression_II.pdf
dort steht dann auch ganz unten beschreiben, wie eine quadrastische
Regression als multiple Regression behandelt werden kann.
Eine Alternative ist die Berechnung von Regressionsgeraden für 3 bis 5
Abschnitte, je nach gewünschter Genauigkeit
Tec Nologic schrieb:> Bzw es gibt dazu auch Beispiele> bzw Bibliotheken im Netzt und auch hier im Forum ist das thema schon> durch gekaut worden.
Könntest du mir netterweise einen Link dahin gegen? Ich bin bei der
Suche nicht so erfolgreich.
Ich mache so etwas zum ersten mal, daher tue ich mich damit momentan
noch etwas schwer.
Ich rechne gerade mit Beispielwerten, von Karl-Heinz.
Habe jetzt:
1
x|y
2
---------
3
1|20
4
2|26
5
3|28
und daraus halt die Gleichungen:
1
a*1+b*1^2+c*1^3=20
2
a*2+b*2^2+c*2^3=26
3
a*3+b*3^2+c*3^3=28
4
5
daraus:
6
7
a+b+c=20
8
2a+4b+8c=26
9
3a+9b+27c=28
Nach dem Gauss-Verfahren würde ich ja nun durch Additionen und
Substraktionen einzelne Elemente in der Matrix entfernen, sodass ich auf
folgende Form komme:
1
abc|y1
2
bc|y2
3
c|y3
Aber wie realisiere ich sowas im Microcontroller? Ich mein, ich kann dem
ja nicht sagen, wie er sinnvoll Zeilen eliminiert, oder?
Bitte seid nicht zu kritisch mit mir, das ist absolutes Neuland für
mich, aber ich möchte mich da sehr gerne einarbeiten.
Gruß, Harald
bemerkung: bei der gleichung fehlt der offset. also bei 3 messpunkten
geht die gleichungslösung bis maximal x^2 und nicht bis x^3
z.b. y = a + b*x + c*x^2
etc
Harald Wünsch schrieb:> Aber wie realisiere ich sowas im Microcontroller? Ich mein, ich kann dem> ja nicht sagen, wie er sinnvoll Zeilen eliminiert, oder?
Gar nicht! Du musst das auf dem Papier allgemein ausrechnen, dann kannst
du diese Formel in dein Programm einbauen.
jetzt gehst du hin und musst deinen Sensor Kalibieren, also deine
definierten Messpunkte messen (25%, 50% , 75%). Hat der uC diese Werte,
kann er mit den von dir ermittelten Formeln das Gleichungssystem
berechnen, und sich seine Koeffizienten bestimmen, diese speichert er
ggf im EEPROM, und kann dann jeden Messwert mit den Koeffizenten
korrekturrechnen.
0% würde ich nicht nehmen da es hier sein kann, das die Messwerte durch
Störungen zustark beeinflusst sind.
Hier ein paar Links.
http://en.wikipedia.org/wiki/Fixed_point_%28mathematics%29http://en.wikipedia.org/wiki/Fixed-point_theoremhttp://mathworld.wolfram.com/FixedPoint.html
Das Thema ist nicht unbedingt trivial mit der Fixed Point Berechnung.
Ich kann dir dabei nicht gut weiter helfen, vllt meldet sich hier ja
noch jemend der öfter mit Fixed Point DSP's oder so arbeitet.
MfG
Master Snowman schrieb:> bei der gleichung fehlt der offset. also maximal bis ^2 und> nicht bis ^3
HOPPLA, natürlich, entschuldigt! Das stimmt natürlich!
Dumm, wenn man Hilfe erwartet und die ersten Hilfestellungen schon
falsch übernimmt...
Also ändere ich es zu:
bei
y1 = a + b*x1 + c*x1^2
y2 = a + b*x2 + c*x2^2
y3 = a + b*x3 + c*x3^2
komme ich auf:
c = ((y1-y2)/(x1-x2) - (y2-y3)/(x2-x3)) / ((x1^2-x2^2)/(x1-x2) +
(x2^2-x3^2)/(x2-x3))
b = (y1-y2-c*(x1^2-x2^2)) / (x1-x2)
a = y1-b*x1-c*x1^2
es soll jemad dies verifizieren (ich hab's nur ganz schnell gerechnet,
d.h. ev. einen flüchtigkeitsfehler gemacht)
Harald Wünsch schrieb:>> Ich rechne gerade mit Beispielwerten, von Karl-Heinz.
Es war noch sehr früh und ich hatte noch keinen Kaffee
die Gleichung sollte sein
y = a*x + b*x^2 + c*x^3 + d
(also noch ein konstantes Glied dazu, damit man die Kurve auch als
ganzes noch unten oben verschieben kann)
Damit: 4 Messungen für 4 Unbekannte
Oder aber wenn du bei 3 Messungen bleiben willst (weil du weißt das in
erster Näherung eine Parabel rauskommen wird)
y = a*x + b*x^2 + c
Der Rest des Verfahrens bleibt aber gleich.
Generell braucht man immer eine 'Messung' mehr, als der Grad des
Polynoms ist.
Für ein Polynom 2.ten Grades 3 Messungen, 3.ten Grades sind es dann 4
Messungen.
Und nein. Man möchte den Grad des Polynoms nicht extrem in die Höhe
treiben. Bei 11 Punkten, die auf einer Parabel liegen erzeugt ein
Polynom 10ten Grades Schwingungen zwischen den Punkten anstelle das da
sauber durchgelegt wird.
> Aber wie realisiere ich sowas im Microcontroller? Ich mein, ich kann dem> ja nicht sagen, wie er sinnvoll Zeilen eliminiert, oder?
1. Das Verfahren ist doch immer gleich.
D.h du arbeitest auf dem Papier vor, solange bis du
3 Lösungsformeln hast, in die du nur noch die Zahlenwerte
einsetzen musst.
Und die implementierst du dann
2. Doch man kann das schon machen
Das hier
a b c | y1
b c | y2
c | y3
heisst ja nur, dass du die 3. Zeile auf die Form gebracht hast
0*a + 0*b + 1*c = y3
Du musst also die Koeffizienten der 3.ten Gleichung so manipulieren,
der erste zu 0 wird, der 2.te zu 0 wird und der 3.te zu 1
> Bitte seid nicht zu kritisch mit mir, das ist absolutes Neuland für> mich, aber ich möchte mich da sehr gerne einarbeiten.
Dann musst du üben.
Und genau deshalb gibts hier auch keinen fertigen Code.
Das ganze sieht zunächst kompliziert aus, ist aber in Wirklichkeit nicht
so schlimm.
Harald Wünsch schrieb:> a + b*0^1 + c*0^2 = 20> a + b*2^1 + c*2^2 = 26> a + b*4^1 + c*4^2 = 28>> a = 20> a + 2b + 4c = 26> a + 4b + 16c = 28>> Den Koeff. a habe ich (a = 20) - diesen setze ich in die 2. Gl. ein:
Du orientierst dich hier zu sehr an den beispielhaft angenommenen
Zahlenwerten. Im allgemeinen sieht deine erste Gleichung nicht so aus,
weil du für X1 eben nicht 0 hast.
Anstelle der realen Zahlen nimm meinetwegen X1, X2, X3, Y
damit du auf ein allgemeines Lösungsverfahren kommst.
Die realen Zahlen kannst du ja dann benutzen um die Probe zu machen.
Wenn du 2 Gleichungen hast (jetzt am Beispiel einer Linearen)
1
a + b * X1 = Y1
2
a + b * X2 = Y2
wie eliminierst du den b-Term aus der 2.ten Gleichung?
Du möchtest ein geeignetes Vielfaches der 1.ten Gleichung von der 2.ten
Gleichung abziehen, und zwar so, dass sich zum Schluss der b-Term in der
2.ten Gleichung zu 0 ergibt.
dazu musst du die erste Gleichung mit X2/X1 multiplizieren (kannst du
sehen warum?)
1
a * X2/X1 + b * X1 * X2/X1 = Y1 * X2 / Y1
2
a + b * X2 = Y2
Gleichung I von Gleichung II angezogen ergibt
1
(a - a * X2/X1) + ( b * X2 - b * X1 * X2 / X1 ) = Y2 - Y1 * X2 / X1
und vereinfachen
( i * j / j ergibt wieder i; b*X1/X1*X2 ergibt daher b*X2 )
1
(a - a * X2/X1) + ( b * X2 - b * X2 ) = Y2 - Y1 * X2 / X1
(jetzt steht da beim b Term eine Differenz, die zu 0 wird)
1
(a - a * X2/X1) + 0 = Y2 - Y1 * X2 / X1
a herausheben
1
a( 1 - X2/X1) = Y2 - Y1 * X2 / X1
2
3
Y2 - Y1 * X2 / X1
4
a = ---------------------------
5
1 - X2/X1
mit dem X2/X1 liese sich sicherlich auch noch etwas machen. Aber: jetzt
hat man eine Formel für a.
Die setzt man jetzt in die andere Gleichung ein (wird dort also das a
los) und löst die dann nach b auf.
Karl heinz Buchegger schrieb:> Und genau deshalb gibts hier auch keinen fertigen Code.
Ohje, bitte versteht mich nicht falsch, danach hatte ich auch nicht
gefragt - fertigen Code möchte ich garnicht haben. Das bringt mir
persönlich ja auch nichts.
Ich werde jetzt mal mit den Gleichungen rumhantieren und gucken, dass
ich eine Lösung auf Papier bekomme. Vielen Dank erstmal! Ich melde mich
bestimmt nochmal wieder.
Harald
Karl heinz Buchegger schrieb:> Du orientierst dich hier zu sehr an den beispielhaft angenommenen> Zahlenwerten.
Ja klar, in dem Beispiel jetzt schon, war nur zum Verständnis - wie
gesagt, meine Schulzeit ist schon ne Weile her und ich hatte seitdem
nicht mehr viel damit zu tun.
Ich werde es jetzt mal allgemein versuchen zu formulieren...
Harald
Harald Wünsch schrieb:> Karl heinz Buchegger schrieb:>> Du orientierst dich hier zu sehr an den beispielhaft angenommenen>> Zahlenwerten.>> Ja klar, in dem Beispiel jetzt schon, war nur zum Verständnis - wie> gesagt, meine Schulzeit ist schon ne Weile her und ich hatte seitdem> nicht mehr viel damit zu tun.>> Ich werde es jetzt mal allgemein versuchen zu formulieren...
OK.
Das kann zwischendurch zu ganz schönen Monstern ausarten.
Harald Wünsch schrieb:> Und damit meine Gleichung: y = 20 + 2x + 0.5x^2
Ich muss mich doch mal selber in Frage stellen...
Mit meiner oben angegebenen Gleichung komme ich doch in meinem Beispiel
auch nicht hin:
Hinweis:
Man kann sich aber auch viel Arbeit sparen, indem man den Rechner
dieses Eliminierungsverfahren (dann allerdings mit realen Zahlen)
durchspielen lässt. D.h. der Rechner zieht geiegnet gewählte Vielfache
der Gleichungen voneinander ab, so dass die Koeffizienten nacheinander 0
werden, bzw. setzt dann bei der Rücksubstitution enstprechend ein
Das ganze ist Arbeiten mit 2D-Arrays und ein bischen rechnen. Das ganze
Gauss-Jordan Verfahren ist in vielleicht 20 bis 30 Codezeilen in C
abgehandelt.
Dazu ist es aber ganz gut, wenn man das tatsächlich ein paar mal mit der
Hand (diesmal mit realen Werten, aber ohne Ausnutzung von Spezialitäten
in den Beispielwerten) gemacht hat. Spätestens nach dem 3. händisch
gelösten Gleichungssystem hast du das allgemeine Vorgehensschema
komplett durchschaut und kannst es locker programmieren.
An deinem (etwas modifizierten) Beispiel
a + 3b + 2c = 20
a + 2b + 4c = 26
a + 4b + 16c = 28
Ich stell das mal um, so dass c vorne steht. Alle Terme die nicht
auftauchen werden mittels 0 angedeutet
2c + 3b + 1a = 20
4c + 2b + 1a = 26
16c + 4b + 1a = 28
(da das a, b und c eh immer an der gleichen Stelle bleiben, lass ich sie
einfach weg. Das Gleichungsystem sieht also so aus
2 3 1 20
4 2 1 26
16 4 1 28
(das ganze Gleichungssystem sind nur noch Zahlen, die perfekt in einem
2D Array der Größe 4 * 3 gespeichert werden kann :-)
und das lösen wir mal.
Damit in der 2.ten Zeile in der ersten Spalte eine 0 entsteht, müssen
wir ein geeignet gewähltes Vielfaches der 1ten Zeile abziehen.
In dem Fall ist das geeignet gewählte Vielfache (wie weiter oben) * 4 /
2
4 deswegen, weil der erste Term in der 2.ten Zeile 4 ist, 2 deswegen
weil der erste Term in der 1.ten Zeile 2 ist.
Zwischendurch bestimme ich mir mal eine neue temporäre erste Zeile, die
diese Werte für die erste Zeile enthält
2*4/2 3*4/2 1*4/2 20*4/2
ausgerechnet
4 6 2 40
das jetzt von der 2.ten Zeile abgezogen
4 2 1 26
- 4 6 2 40
------------------------
0 -4 -1 -14
aus dem ursprünglichen Gleichungssystem
2 3 1 20
4 2 1 26
16 4 1 28
haben wir also eine Trasformation gemacht
2 3 1 20
0 -4 -1 -14
16 4 1 28
dasselbe kann man jetzt mit der 1.ten Zeile und der 3.ten Zeile machen
um dort in der 1.ten Spalte eine 0 zu erzeugen
1.te Gleichung *16/2
16 24 8 160
und von der 3.ten abgezogen
2 3 1 20
0 -4 -1 -14
0 -20 -7 -132
um in der 3.ten Zeile 2.te Spalte eine 0 zu erzeugen, zieht man die 2.te
Zeile geeignet skaliert ab. Gleiches Schema: 2.te Zeile *(-20)/(-4)
rechnen und abziehen. (ICh rechne das jetzt nicht mehr, die Zahlen
werden mir zu unhandlich).
Auf jeden Fall haben wir damit das 'Gleichungssystem' so umgeformt
2 3 1 20
0 -4 -1 -14
0 0 ... ...
(Bei ... kommen irgendwelche Zahlenwerte raus).
Damit ist der Vorwärtslauf beendet. Das System hat Dreiecksgestalt,
alles unter der Diagonale ist zu 0 geworden.
Die letzte Zeile ist jetzt interessant, denn da steht ja jetzt mehr oder
weniger im Klartext
0c + 0b + 398a = 876
(Die Zahlen hab ich jetzt erfunden)
oder eben
398a = 876
das lässt sich ganz leicht umformen, indem man durch 398 dividiert
Das System wird so zu
a = 876/398 = 2.201
2 3 1 20
0 -4 -1 -14
0 0 1 2.201
Jetzt wollen wir im System beginend bei der letzten Zeile jeweils in den
darüberliegenden einsetzen und die Diagonalelemente zu 1 werden lassen.
Ein geeignet skaliertes Vielfaches der 3.ten Zeile von der 2.ten Zeile
abgezogen, führt dazu, dass wir hier angelangt sind
2 3 1 20
0 -4 0 ....
0 0 1 2.201
dasselbe mit der ersten und dritten Zeile
2 3 0 ....
0 -4 0 ....
0 0 1 2.201
In der 2.ten Zeile wollen wir wieder die -4 zu einer 1 machen, indem die
Zeile durch -4 dividiert wird
2 3 0 ....
0 1 0 ....
0 0 1 2.201
und ein geeignet gewähltes Vielfaches der 2.ten Zeile beschert uns
wieder eine 0 in der 1ten Zeile
2 0 0 ....
0 1 0 ....
0 0 1 2.201
die erste Zeile noch durch 2 dividieren und wir sind angelangt bei
1 0 0 ....
0 1 0 ....
0 0 1 2.201
'rückübersetzt' in normale Mathe-Schreibweise steht da also im Klartext
c = ...
b = ...
a = ...
und das ist dann die Lösung des Gleichungssystems
2c + 3b + 1a = 20
4c + 2b + 1a = 26
16c + 4b + 1a = 28
Aufpassen muss man nur, dass man nie durch 0 dividiert (drum hab ich
auch deine Originalgleichung verändert, da wär das nämlich aufgetreten
:-)
Harald Wünsch schrieb:> Harald Wünsch schrieb:>> Und damit meine Gleichung: y = 20 + 2x + 0.5x^2>> Ich muss mich doch mal selber in Frage stellen...>> Mit meiner oben angegebenen Gleichung komme ich doch in meinem Beispiel> auch nicht hin:>>
1
>y=20+2x+0.5x^2
2
>
3
>x|y
4
>---------
5
>0|20
6
>2|26
7
>4|28
8
>
9
>y(1)=20+2(0)+0.5(0^2)=20+0+0=20RICHTIG
10
>y(2)=20+2(2)+0.5(2^2)=20+4+2=26RICHTIG
11
>y(3)=20+2(4)+0.5(4^2)=20+8+8=36FALSCH
12
>
>> Sieht da jemand den Fehler?
Irgendwo wirst du dich verrechnet haben (vielleicht ein Vorzeichenfehler
irgendwo). Auf jeden Fall stimmen die Koeffizienten der Gleichung nicht.
Und darum ist es auch wichtig bei solchen Sachen die Probe zu machen,
indem man einfach die Ausgangswerte mal einsetzt. Besonders wenn man das
länger nicht gemacht hat, macht man schon mal einen Flüchtigkeitsfehler.
Mensch Karl-Heinz, für deine Arbeit muss ich dir bald Geld bezahlen!!
Danke danke danke! Ich rechne jetzt nochmal meine Ursprungsgleichung
wegen dem Fehler.
Aber super Hilfe, wirklich!
Harald
Harald Wünsch schrieb:> Mensch Karl-Heinz, für deine Arbeit muss ich dir bald Geld bezahlen!!> Danke danke danke!
Halb so wild.
Solange du das Schema durchschaust, bin ich zufrieden.
Das Schema ist:
von oben nach unten durchgehen und unter der Diagonalen lauter 0
erzeugen, mit der 1.ten Zeile kann man in allen darunterliegenden
Zeilen in der 1.ten Spalte eine 0 erzeugen.
mit der 2.ten Zeile (die vorne schon eine 0 hat) kann man in der
2.ten Spalte in allen darunterliegenden Zeilen eine 0 erzeugen
mit der 3.ten Zeile (die in den ertsen beiden Spalten schon eine 0
hat) kann man in allen darunterliegenden Zeilen in der 3.ten Spalte
eine 0 erzeugen
etc. etc.
Sukzessive wird das System umgeformt um die Gestalt
.................
0 ...............
0 0 .............
0 0 0 ...........
0 0 0 0 .........
.
.
.
anzunehmen. Alles unter der Diagonale wird zu 0
und dann beginnt es bei der letzten Zeile, von dort ausgehend macht man
alle elemente über der Diagonalen zu 0. Gleiches Schema: mit der letzten
Zeile kann man in allen darüberliegenden Zeilen in der letzten Spalte
eine 0 erzeugen. Mit der dann vorletzten Zeile erzeugt man in allen
darüberliegenden Zeilen in der vorletzen Spalte eine 0 etc. etc.
..0 0 0 0........
0 ..0 0 0........
0 0 ..0 0........
0 0 0 ..0........
0 0 0 0 .........
.
.
.
Die Diagonalen noch schnell auf 1 bringen und die Lösung steht da
Das ist das Gauss Jordan Verfahren.
Harald Wünsch schrieb:> wie mache ich sowas ohne Fließkomma-Arithmetik?
Hallo,
Linear Technology hat da eine Application Note wie man einen 24-Bit
A/D-Wandler entsprechend mit Integer-Arithmetik linearisiert (ist
ebenfalls ein parabelförmiger Ansatz). Der Trick dabei ist daß man
lediglich einen Korrekturwert berechet den man dann addiert. (Da werden
die Koeffzienten gleich viel leichter handhabbar).
http://cds.linear.com/docs/Application%20Note/an86f.pdf
Ich selbst speichere die Koeffizienten meiner A/D-Wandler passend
skaliert im EEPROM eines Microcontrollers. Die Übertragung
(Programmierung) in den Microcontroller erfolgt über die serielle
Schnittstelle. Natürlich ist auch die Meßwertaufnahme und
Korrekturwertberechnung auf dem PC automatisiert denkbar. (Erfolgt bei
mir mittels 11 Messwerte-Paaren von Hand da keine Stückzahl dahinter
steht).
Gruß Anja
Ach ja noch was:
ich werfe mal die Methode der kleinsten Fehlerquadrate in den Raum. Die
Anzahl der Messwerte ist dort beliebig solange sie größer ist als der
Grad des Polynoms + 1.
Obwohl in dem speziellen Fall ist die Parabel ja mittensymmetrisch (oder
kann zumindest ohne großen Fehler so approximiert werden) -> man braucht
lediglich einen Koeffizienten (für x²) bestimmen wenn man die Gleichung
entsprechend umstellt (der lineare Teil ist dann = 0).
Man kann dann für jeden einzelnen Messwert den Koeffizienten direkt
bestimmen und kann dann die ergebnisse ausmitteln. (Wobei ich
persöhnlich die Werte bei 50% höher gewichten würde da dort der
Messfehler vermutlich geringer ist als nahe 0 und 100%).
Gruß Anja
Huch, da vergehen zwischen Aufruf der Seite und geplanter Antwort mal 2
Stunden und es lohnt sich fast nicht mehr ;)
Ich wollte folgendes der Vollständigkeit halber noch loswerden, vermute
aber, dass du dich schon auf die Polynome eingeschossen hast ;)
zur linearen Interpolation:
Ich habe diese in meiner Projektarbeit vollkommen in Integer-Arithmetik
aufgebaut und aus meinem Programm alle floats rausgeworfen.
Die in meiner Anwendung benötigte Genauigkeit von 0,1% konnte mit einer
handvoll Stützpunkten eingehalten werden.
Daraus sind folgende Vorteile entstanden:
- Sehr schnelle Berechnung des Korrekturwertes (binäre Suche bei großer
Menge an Stützpunkten) im Vergleich zur Fließkommaberechnung.
- Deutlich geringerer Speicherbedarf (wenn auch sonst keine weiteren
Fließkommawerte genutzt werden)
Matthias N. schrieb:> Huch, da vergehen zwischen Aufruf der Seite und geplanter Antwort mal 2> Stunden und es lohnt sich fast nicht mehr ;)
Lohnt sich praktisch immer.
Mehrere Alternativen zu kennen war noch nie schlecht :-)
> Ich wollte folgendes der Vollständigkeit halber noch loswerden, vermute> aber, dass du dich schon auf die Polynome eingeschossen hast ;)
Bis jetzt sind ja die "Probleme" damit noch gar nicht wirklich
angesprochen worden :-)
Denn: so das Allheilmittel ist es dann auch wieder nicht, wenn man
einfach ein Polynom mit hohem Grad auf eine Handvoll Messwerte loslässt
:-)
> Ich habe diese in meiner Projektarbeit vollkommen in Integer-Arithmetik> aufgebaut und aus meinem Programm alle floats rausgeworfen.> Die in meiner Anwendung benötigte Genauigkeit von 0,1% konnte mit einer> handvoll Stützpunkten eingehalten werden.
Also stückweise linear approximieren.
Auch ein guter Ansatz
stückweise lineare Approximation ist weiter oben schon einmal
aufgetaucht.
Jetzt ist es nur so, dass man allgemeines Polynomlösen im Rechner (also
zb. das Gauss Jordan Verfahren) nicht in 3 Sätzen abhandeln und erklären
kann. Das braucht ein wenig Platz, wenn man nicht einfach auf einen
externen Link verweisen will.
Und darüber geht dann die Information verloren, dass weiter oben bereits
Alternativen angerissen und besprochen wurden.
Wie Horst so richtig sagt: Der Nachteil von langen Threads die an einem
Thema ins Detail gehen.
Also ich blicke durch deine Rechnung ja nun auch wieder durch, Karl
Heinz. Danke nochmal.
Wenn dieses Verfahren dafür geeignet ist, dann werde ich es damit
natürlich versuchen, wo ich jetzt jetzt schon erneut "gelernt" habe.
Ich werde also am Ende 5 Punkte aufnehmen, nachdem ich vorher die
allgemein-gültige Gleichung aufgestellt habe und den uC dann die
Koeffizienten berechnen lassen und diese abspeichern - das muss er ja
nur einmal tun.
Wenn ich damit mein Problem loswerde, dann bin ich ja wunschlos
glücklich - die Rechnung ohne Fließkommaarithmetik guck ich mir danach
an. Wäre natürlich auch noch um Längen besser, aber erstmal musses
überhaupt was bringen.
Mit 5 Werten habe ich ja dann ein Polynom 4. Grades, das ist doch OK,
oder nicht?
Harald
Ob das Polynom vom Ergebnis ausreicht ist oder nicht kannst du am
besten selbst herausfinden indem du mal vergleichst inwiefern die
gewünschten Werte mit den berechneten übereinstimmen bzw von diesen
abweichen (zB 2 Graphen in Excel übereinanderlegen)
Harald Wünsch schrieb:> Mit 5 Werten habe ich ja dann ein Polynom 4. Grades, das ist doch OK,> oder nicht?
Im Prinzip: ja
Ich sag absichtlich "im Prinzip", denn da kann noch so einiges
passieren, mit dem du jetzt nicht rechnest, abhängig von den Werten :-)
Wenn du kannst, dann würde ich dir empfehlen:
Programmier dir das am PC aus und mach dort Versuche. Ideal wäre es,
wenn du das Polynom grafisch anzeigen lassen könntest.
Probiers mit den zu erwartenden Werten aus.
Probiers aber auch mit entarteten Werten aus:
was passiert wenn alle 5 Messwerte auf einer Geraden liegen
wie vorher, nur verschiebst du 1 Punkt leicht von der Geraden weg
wie vorher, nur diesmal weiter weg
wie verändern sich die Eigenschaften des Polynoms, je nachdem
welchen Punkt du weggeschoben hast. Hat das Auswirkungen?
Das Resultat: du kriegst ein viel besseres Verständnis dafür, was dir
alles alles passieren kann, woran du erkennen kannst das es dir passiert
ist, und was das Problem dabei ist. Das kann unter Umständen wichtig
sein um einen Kunden am Telefon gezielt auszufragen und ihm eine Lösung
anbieten zu können.
Harald Wünsch schrieb:> Mit 5 Werten habe ich ja dann ein Polynom 4. Grades, das ist doch OK,> oder nicht?
Vorsicht die Werte bei 0% und 100% sowie 25% und 75% sind nicht linear
unabhängig. -> Beim Lösen der Matrix wirst du Divisionen nahe 0 oder
durch Null haben (je nach Wandlerrauschen). -> Die Koeffizienten werden
sehr instabil.
Wenn Du wirklich ein Polynom 4. Ordnung haben willst müßtest Du dir
andere Stützstellen aussuchen (z.B. 100% 50% 25% 12,5% 0%)
Ferner würde ich mir mal die AN86 von Linear Technology anschauen (s.
o.)
Gruß Anja
Anja schrieb:> Vorsicht die Werte bei 0% und 100% sowie 25% und 75% sind nicht linear> unabhängig.
Was genau meinst du damit, wieso hängen die zusammen?
Deine Application Note habe ich mir schon runtergeladen. Werde sie
nachher studieren.
Harald Wünsch schrieb:> Was genau meinst du damit, wieso hängen die zusammen?
In der Fehlerkurve haben beide den selben Y-Wert (in der Theorie) und
sind spiegelsymmetrisch. In der Praxis kommt dann noch das
Wandlerrauschen hinzu.
Damit hast Du für 2 Werte die in der Matrix dieselben x-Koeffizienten
mit unterschiedlichem Vorzeichen (bezüglich Mittelline) haben völlig
unterschiedliche Y-Werte. Dies kann dann bei der Weiterverarbeitung
unerwartete Schwingungen zwischen den Stützstellen zur Folge haben.
Daher verwende ich bei realen (verrauschten) Messwerten immer die
Methode der kleinsten Fehlerquadrate bei genügend großer
Messwerteanzahl.
Ansonsten versuche ich das Problem zu Linearisieren z.B. wie in AN86.
Dort wird nur der Koeffizient für den Quadratischen Term der Fehlerkurve
bestimmt und der Fehlerterm zur Gesamtkurve addiert.
Wobei in der AN86 noch die Parabel durch eine linearisierte Näherung
approximiert wird um Multiplikationen zu vermeiden. Aber so weit würde
ich heutzutage nicht mehr gehen.
Gruß Anja
Anja schrieb:> In der Fehlerkurve haben beide den selben Y-Wert (in der Theorie) und> sind spiegelsymmetrisch. In der Praxis kommt dann noch das> Wandlerrauschen hinzu
OK, verstehe was du meinst.
Aber das ist ja der Fehler in %.
Ich würde ja dann die ADC-Werte korrigieren, die würden sich also nicht
wiederholen, da sie von bsp. 110000 (Offset) bis 900000 (Endwert)
laufen.
Oder sehe ich da jetzt was falsch?
Harald Wünsch schrieb:> Ich würde ja dann die ADC-Werte korrigieren, die würden sich also nicht> wiederholen, da sie von bsp. 110000 (Offset) bis 900000 (Endwert)> laufen.
Ob Du jetzt die Matrix für die Gesamtfunktion aufstellst oder nur für
den Fehlertherm macht (zumindest in der Theorie bei unendlicher
Auflösung der Floating Point Zahlen) keinen Unterschied für die
Stabilität der Matrix. Der Offset Koeffizient a und der lineare
Koeeffizient b (* x) sind halt dann etwas größer. Die Probleme treten
erst bei den Quadratischen Thermen auf.
In der Praxis erreichst Du allerdings viel schneller die
Genauigkeitsgrenzen deines Zahlenformats. Ich würde daher die
Fehlerkurve vom linearen Anteil trennen. Dadurch hast du weniger
Rundungsfehler bei der Berechnung.
Schon allein aus praktischen Erwägungen: Du wirst viel häufiger den
Offset und ggf. den Endwert (bzw. Steilheit) Kalibrieren wollen (1-2
Messpunkte) als die Nichtlinearität (5 Messpunkte), die sich meist auf
die Differenz von Offset und Endwert normieren läßt.
Gruß Anja
Hallo,
Ein Curvefit mit hohem Grad (3, 4) führt zu lästigen Oszillationen.
Sowas willst du nicht haben.
Wie wärs mit Ausgleichs- oder Regressionsparabel. Die passt am besten zu
deinem Problem. Da wird auch ein lineares Gleichungssystem(3 Unbekannte)
aufgesellt.
y = a*x^2+b*x+c
Man muss allerdings mit dem Dynamikbereich aufpassen und deshalb erst
die Zahlen normieren, da in dem Gleichungssystem Faktoren bis Zahl^4
vorkommen.
OK Anja, was würdest du mir empfehlen?
Ich seh grad schon, dass ich bereits mit der hier besprochenen Methode
von Karl Heinz, welche ich gerade am ausrechnen bin, meine kleinen
Probleme in der Übersichtlichkeit der Terme habe.
Das sind schon ganz schön große Sachen...und jetzt könnte ich damit
sogar Probleme bekommen? Ich hab mal kurz über die AppNote
drübergeguckt. Hab auf die schnell erstmal nur Assembler gesehen, das
hat mich natürlich direkt wieder etwas abgeschreckt, werde mir den Text
natürlich trotzdem noch durchlesen. Ich kann nur garkein Assembler, nur
C.
Helmut S. schrieb:> Wie wärs mit Ausgleichs- oder Regressionsparabel
Und ein neuer Vorschlag...hört sich auch wieder interessant und schwer
an - ich verzweifle hier noch.
Ich wollt doch nur eine einfache Form der Linearisierung :)
Harald Wünsch schrieb:> Helmut S. schrieb:>> Wie wärs mit Ausgleichs- oder Regressionsparabel>> Und ein neuer Vorschlag...hört sich auch wieder interessant und schwer> an - ich verzweifle hier noch.
:-)
Viele Wege führen nach Rom
>> Ich wollt doch nur eine einfache Form der Linearisierung :)
Harald Wünsch schrieb:>> Wie wärs mit Ausgleichs- oder Regressionsparabel>> Und ein neuer Vorschlag...hört sich auch wieder interessant und schwer> an - ich verzweifle hier noch.
Ist nur ein Spezialfall der Methode der kleinsten Fehlerquadrate mit
einer Parabel als Zielfunktion, also nix neues.
Harald Wünsch schrieb:> Ich wollt doch nur eine einfache Form der Linearisierung :)
Mit der kleinen "Nebenbedingung" daß diese auch eine Verbesserung der
Messwerte bringt und zwar nicht nur an den Stützstellen sondern auch
noch dazwischen. Da sollte man sich die Meßwerte schon etwas näher
anschauen und ggf. mehrere Verfahren mit realen Messwerten und diversen
Normierungen (z.B. Normiert auf Meßbereichsmitte) vergleichen.
Die Frage ist halt:
- Wie groß ist der Fehler jetzt
- Welchen Fehler willst Du erreichen
(eine Verbesserung Faktor 10 sollte immer drin sein)
- Wieviel Speicher hast Du für die Linearisierung
(Tabelle, abschnittweise Linearisierung oder nur Koeffizienten)
- Reicht eine einfache Parabel 2. oder eine 4. Ordnung
(darüber wirds mit doppelter Genauigkeit schwierig
überhaupt noch eine Verbesserung zu erzielen).
Harald Wünsch schrieb:> OK Anja, was würdest du mir empfehlen?
Hängt von den tatsächlichen Messwerten ab:
Wenn es wirklich nur eine Parabel ist würde ich einfach
Die Formel aufstellen a2 * (Messbereich/2)^2 = Fehler bei 50%.
Das ganze nach a2 aufgelöst ergibt den Korrekturkoeffizienten.
Bei der Korrektur ist dann als x-Wert der Abstand von 0% oder 100%
(quadriert) einzusetzen. Der maximale Korrekturwert ergibt sich dann bei
50%. Das ganze dann vorzeichenrichtig addiert -> linear.
Wenn das nicht reicht kannst Du ja immer noch mit abschnittweiser
Linearisierung oder Regressionsparabel arbeiten.
Gruß Anja
Anja schrieb:> Bei der Korrektur ist dann als x-Wert der Abstand von 0% oder 100%> (quadriert) einzusetzen. Der maximale Korrekturwert ergibt sich dann bei> 50%. Das ganze dann vorzeichenrichtig addiert -> linear.
Oh sorry, stimmt so nicht ganz:
muß natürlich genau anders herum sein:
Bei der Korrektur ist dann als xa-Wert der Abstand von 50% des
Messbereichs (=X2) (quadriert) einzusetzen. Der Korrekturwert ergibt
sich dann als
K = a2 * (1 - (xa/X2)^2) * X2^2
Gruß Anja
Es ist eine Fehlerkurve (prozentual gesehen), welche folgendermaßen
aussieht:
1
Fehler[%]
2
|
3
|**
4
|**
5
|**
6
|**
7
|**
8
|**
9
|**
10
------------------------------------------>
11
Druck
In der Mitte halt am höchsten.
Aus den Werten würde ich nun gerne eine Linearisierungskurve aufstellen,
welche mir den errechneten, richtigen Wert rausgibt.
Ich hatte schon mehrere Messzellen, welche auch mal eine Parabel 3.
Grades aufweisen (aber nur sehr leicht) - meistens sieht der Fehler so
wie hier aus, wenn auch nicht so extrem.
Speicher habe ich genug, ist ein 60k uC.
Leider komm ich mit der ganzen Thematik nicht so gut voran, daher bin
ich um jede Hilfe, die mich zum Ziel führt sehr dankbar.
Hallo,
warum eine Ausgleichsrechnung, wenn Du mit linearer oder quadratischer
Interpolation arbeiten kannst, um Zwischenwerte zu berechnen.
Zitat:
http://electronicdesign.com/article/components/efficient-algorithms-improve-the-linearization-of-.aspx:
Or, the table can be kept the same size and the calculation made a more
elaborate by going to second-order interpolation:
//Eine Tabelle mit 10 Werten, bei Dir sind es 11
IINTERP = RRTD/10 // 10 äquidistante Stützstellen
IINT = INTEGER(lINTERP) //Ganzzahlanteil
IFRAC = IINTERP − IINT //Nachkommaanteil
a = rtdtable(IINT)
b = rtdtable(IINT + 1)/2
c = rtdtable(IINT − 1)/2
f = a+IFRAC[b-c +IFRAC*(c+b-a)]
Was mich eigentlich wundert, wer teilt dem Mikrocontroller mit, wie groß
der Fehler ist.
Ein PC? Der könnte eine beliebig komplizierte Rechnug ausführen und ein
Polynom oder dessen Faktoren zurückgeben.
http://de.wikipedia.org/wiki/Polynominterpolationhttp://de.wikipedia.org/wiki/Lineare_Regressionhttp://de.wikipedia.org/wiki/Kubischer_Spline
es klingelt...
Horst Hahn schrieb:> Was mich eigentlich wundert, wer teilt dem Mikrocontroller mit, wie groß> der Fehler ist.
Das teilt ihm keiner mit - ich muss eine Funktion erstellen (vorher auf
dem Papier weiß ich mittlerweile), die ich dann in den uC schreibe und
dann quasi Messwerte aufnehme (10 wären etwas viel - 5 müssten reichen),
anhand derer der uC die eigentlichen Werte durch Berechnung der
Koeffizienten einer Linearisierungskurve bestimmen kann.
Der erste Link ist leider nicht erreichbar, omentan zumindest. Die
Wiki-Artikel hab ich auch schon angeguckt - viele Bäume - seh den Wald
nicht mehr...
Und habe sowas noch nicht gemacht, daher weiß ich leider nicht, welche
Methode die geeignetste ist. Ich freu mich sehr über die vielen
Antworten hier. Für den Einen ist es trivial, ich hab da grad echt noch
ein Problem mit, aber ich bleib dran, wird ein langer Abend :)
Harald Wünsch schrieb:> Und habe sowas noch nicht gemacht, daher weiß ich leider nicht, welche> Methode die geeignetste ist.
Du verzeihst wenn ich da ein wenig nachhake.
'die geeignetste'
das fällt in dieselbe Kategorie wie 'der beste Prozessor', 'der
einfachste Weg', 'das optimalste Vorgehen', 'das beste Programm'
und allen gemeinsam ist: so etwas gibt es in der Technik nur ganz
selten. 'Der geeigneste, beste, schönste, etc X' ist oftmals einfach nur
der X, den du realisieren kannst.
Man muss oftmals Kompromisse schliessen. Jedes Verfahren hat seine Vor-
und seine Nachteile. Das geeignetste ist auch oft nur das Verfahren mit
den wenisgten Nachteilen oder dasjenige mit zwar vielen Nachteilen, die
sich allesamt nicht gravierend auswirken.
Wenn es so etwas wie 'das geeigneste, beste, etc.' gäbe, dann würde es
jeder verwenden und man müsste nicht Alternativen entwickeln. Da das
aber offenbar nicht so ist, gibt es den "pauschel geeignesten" nicht.
QED
Deswegen kriegst du hier auch viele verschiedene Möglichkeiten
angeboten, weil natürlich jeder sein Leib und Magen Lieblingsverfahren
präsentiert. Das heißt nicht, dass die jeweiligen Verfahren schlecht
sind! Das heißt nur, für unterschiedliche Leute haben in der
Vergangenheit unterschiedliche Verfahren gut funktioniert, so dass sie
sich gemerkt haben
Ich würde mir
von den bisherigen Vorschlägen den aussuchen, der am einfachsten zu
realisieren ist. Und dann praktisch abklären ob er gut genug ist. Gut
genug kann wieder viele Bewertungen beinhalten: Speicherverbrauch,
Rechenzeit, Einfachheit der Bedienung, ....
Wenn es keinen Einwand gibt, dann benutzt man den eben.
Stellt sich raus, dass das nicht das Erhoffte gebracht hat, dann
probiert man einen anderen.
Neben reichlich Praxis in der IMplementierung gewinnt man so auch
Einsicht in die Stärken und Schwächen von Alternativen und hat dann beim
nächsten mal ein Entscheidungskriterium, welches aus erster Hand,
nämlich von dir selber, gewonnen wurde. Das sind Erfahrungen, die
vergisst man nicht so schnell. Gewissermassen ein: Lerning by doing.
Harald Wünsch schrieb:> die ich dann in den uC schreibe und> dann quasi Messwerte aufnehme (10 wären etwas viel - 5 müssten reichen),
ok ich habe mal etwas gerechnet:
im einfachsten Fall da reichen im Prinzip 3 Messwerte also (Offset
50%-Wert und 100%-Wert) komme ich mit einem Tabellenkalkulationsprogramm
auf einen Restfehler von 4.0 mBar nach Korrektur.
Deine Spalten habe ich erweitert um
- Normierung auf Mitte (500mBar abgezogen).
- Normierung auf 1 (durch 500mBar geteilt)
- Quadriert = vorherige Spalte mal sich selbst
- 1-Quadrat = 1.0 - Quadiert
- Korrektur = 31.747 * vorherige Spalte
- Restfehler
Den Korrekturfaktor 31 habe ich auf 31.747 aufgerundet so daß sich die
Summe aller Restfehler auf fast 0 ergibt.
Bei exakt 31.0 ergibt sich eine maximale Abweichung von 4.25 bei 100
mBar.
Wenn Du mit einer Verbesserung von Faktor 7 leben kannst wäre das die
Methode mit der geringsten Anzahl von Meßwerten.
--------------------
Zum Vergleich habe ich noch die Methode der kleinsten Fehlerquadrate mit
angehängt. Ich habe mir hier allerdings nicht die Mühe gemacht eine
vernünftige Normierung zu suchen sondern die Meßwerte und die Sollwerte
direkt eingegeben (was aber bei der geringen Anzahl von Meßwerten noch
keine Rolle spielen sollte). Gerechnet wurde mit EXTENDED (10-Byte)
floating point.
Es ergeben sich folgende maximalen Fehler-Werte:
Parabel 4. Ordnung: 0.79
Parabel 6. Ordnung: 0.37
Parabel 2. Ordnung habe ich nicht mit angehängt da der Fehlerbetrag 3.5
nicht wesentlich unter der "Einfachmethode" liegt.
Die Software ist in ISBN 3-446-11701-6 zu finden.
Gruß Anja
Mensch, wenn ich euch doch persönlich die Hand schütteln könnte!
Das ist ja super nett von euch, also das reicht erstmal für heute - ein
wenig Eigenleisutng muss ja auch noch drin sein.
So gute Hilfe hab ich ja noch nirgends bekommen.
DANKE³
Karl heinz Buchegger schrieb:> Neben reichlich Praxis in der IMplementierung gewinnt man so auch> Einsicht in die Stärken und Schwächen von Alternativen und hat dann beim> nächsten mal ein Entscheidungskriterium, welches aus erster Hand,> nämlich von dir selber, gewonnen wurde. Das sind Erfahrungen, die> vergisst man nicht so schnell. Gewissermassen ein: Lerning by doing.
Da stimme ich dir natürlich voll und ganz zu. Ich hoffe, da recht bald
ein wenig besser durch zu blicken.
Schönen Abend euch allen!
Hier mal die Berechnung der Ausgleichsparabel.
Ich habe deine x-Werte durch 100 geteilt, damit wegen x^4 keine so irre
hohen Werte entstehen.
Helmut
Das lineare Gleichungssystem lautet
(a)*(c) = (b)
Im Fehlerarray (e) siehst du die Abweichung von der Parabel, max. 2.5.
-->x=[0,1,2,3,4,5,6,7,8,9,10];
-->y=[0,14,22,28,31,31,29,24,18,11,0];
-->
-->a=zeros(3,3);
-->b=zeros(3,1);
-->for k=1:11
-->a1=[x(k)^4,x(k)^3,x(k)^2; x(k)^3,x(k)^2,x(k); x(k)^2,x(k),k];
-->a=a+a1;
-->b1=[x(k)^2*y(k);x(k)*y(k); y(k)];
-->b=b+b1;
-->end
-->a
a =
25333. 3025. 385.
3025. 385. 55.
385. 55. 66.
-->b
b =
5888.
1006.
208.
-->c=inv(a)*b
c =
- 1.2863566
12.711123
0.0626593
-->
-->// y = c(1)*x^2+c(2)*x+c(3)
-->// Test
-->for k=1:11
--> z(k)=c(1)*x(k)^2+c(2)*x(k)+c(3);
--> e(k)=z(k)-y(k);
-->end
-->e
e =
0.0626593
- 2.5125743
- 1.6605211
- 1.381181
- 0.6745540
0.4593600
1.0205607
2.0090484
1.424823
- 0.7321155
- 1.4617672
-->
// Scilab-Code
x=[0,1,2,3,4,5,6,7,8,9,10];
y=[0,14,22,28,31,31,29,24,18,11,0];
a=zeros(3,3);
b=zeros(3,1);
for k=1:11
a1=[x(k)^4,x(k)^3,x(k)^2; x(k)^3,x(k)^2,x(k); x(k)^2,x(k),k];
a=a+a1;
b1=[x(k)^2*y(k);x(k)*y(k); y(k)];
b=b+b1;
end
a
b
c=inv(a)*b
// y = c(1)*x^2+c(2)*x+c(3)
// Test
for k=1:11
z(k)=c(1)*x(k)^2+c(2)*x(k)+c(3);
e(k)=z(k)-y(k);
end
e
Helmut S. schrieb:> Hier mal die Berechnung der Ausgleichsparabel.
Vorsicht: bei der Korrektur hat Harald leider nicht die Sollwerte
sondern nur die Meßwerte. d.h. die gesuchte Zielfunktion müßte von den
"krummen" Meßwerten und nicht von den Sollwerten aus gerechnet werden.
Da hier jedoch schon 3% Fehler vergraben sind wird der Restfehler nicht
mehr nur 2,5% betragen.
Gruß Anja
Helmut S. schrieb:> Im Fehlerarray (e) siehst du die Abweichung von der Parabel, max. 2.5.
Merkwürdig: mit der Methode der kleinsten Fehlerquadrate und gleicher
Zielfunktion komme ich auf max 2.06 Abweichung.
Und das unabhängig von Normierung / 100 oder nicht.
Mit Welcher internen Auflösung rechnet denn Scilab?
Ist das nur Single Float?
Gruß Anja
Helmut S. schrieb:> Komm jetzt auch auf die 3,5.
Ok die Abweichungen sehen jetzt bei mir exakt gleich aus.
Also doch noch keine numerischen Probleme.
Gruß Anja
Harald Wünsch schrieb:> Man oh man, ich weiß garnicht, was ihr da alles rechnet...
Sie legen eine Regressionsparabel durch deine Daten und sehen sich an,
welche Abweichungen sich dadurch von der Parabel zu deinen echten Daten
ergeben.
Harald Wünsch schrieb:> Man oh man, ich weiß garnicht, was ihr da alles rechnet...
Dann ist für Dich am Anfang vielleicht der Einfach-Ansatz nur für den
quadratischen Koeffizienten von mir besser geeignet. Du wirst damit
vielleicht nicht bei allen Sensoren das Optimum holen, aber die letzten
Prozent Verbesserung kosten halt auch mehr Schweiß und vor allem: viel
mehr Meßpunkte.
Gruß Anja
Obermayer Florian schrieb:> und das in 13,5 Stunden...ihr seid echt wahnsinn :-) faszinierend> Captain...
Was heißt das? Machst du dich über mich lustig, weil ich es nicht ralle?
:)
Ich bin da nicht so bewandert...
Hallo an alle Theoretiker ....
Respekt ... so viel Formeln und Zahlen ...
>> Ich habe eine Messzelle, welche leider keinen linearen Verlauf hat - der>> Verlauf ist eher parabelförmig mit dem größten Fehler in der Mitte.>> Es handelt sich um einen DMS in einer Messzelle (Druck). Dessen Werte>> verstärke ich mittels OPs und gebe diese Werte auf einen Diff.-ADC
An der Schaltung kann man nichts machen ... um z.B. linearere Werte zu
bekommen ?
Um was für eine Messzelle handelt es sich denn (Datenblatt)
Schaltplan von deinem Aufbau wäre auch nicht schlecht ...
Gruss Ralf
bin ich in Mathe nicht so bewandert, dass ich Eure Ausführungen ganz
nachvollziehen kann. Gilt das von Euch abgeleitete/ ausgeführte nur
dann, wenn die Kennline einen math. beschreibbaren (Formel) Verlauf
(Hier: Parabel) hat ? Ich habe habe das Problem, dass Sensor- Kennlinien
KEINEN exakten math. Verlauf haben d.h. im Anfangsbereich sind sie
linear und prima brauchbar, gehen aber im Endbereich in die Sättigung
(heißt wohl math. gleiche X Intervalle ergeben kleinere Y Intervalle ?).
Leider streuen die Sensor- Kennlinien von Sensor- Exemplar zu Sensor-
Exemplar, sodass wohl zu jedem Sensor- Exemplar spezielle Korrektur-
Werte errechnet/ gemessen werden müßten. (Look up table ?) Gibt es da
einen einfachen / anderen Ansatz, um dieses Problem zu lösen ?
Leider schrieb:> Gibt es da> einen einfachen / anderen Ansatz, um dieses Problem zu lösen ?
Einen allgemeinen Ansatz gibt es leider nicht für alle Problemfälle. Bei
einem Sättigungsverhalten würde ich das ganze versuchen in 3 Teile
aufzuspalten: Linearer Bereich = Lineare Approximation, Übergangsbereich
evtl als Parabel, Gesättigter Bereich wieder als Lineare Funktion.
Im Zweifelsfall hilft immer noch die "brute force" Methode: für jeden
Meßwert einen eigenen Zielwert in einer Tabelle.
Ist halt immer ein Kompromiß zwischen Genauigkeit und Speicherplatz.
Meist reichen jedoch Parabeln 2. oder 3. Ordnung um übliche
Nichtlinearitäten (zumindest in Teilbereichen) zu kompensieren.
Gruß Anja
Hier mal was Einfaches und trotzdem Gutes.
Wenn du tatsächlich 11 oder mehr Werte hast, dann mach doch einfache
eine lineare Approximation. Um die Welligkeit zu verringern bildest du
als erstes neue Zwischenpunkte die genau in der Mitte zwischen den
bisherigen Punkten liegen.
Soll | Ist | Abweichung
---------------------------
0 | 0 | 0
100 | 86 | 14
200 | 178 | 22
300 | 272 | 28
400 | 369 | 31
500 | 469 | 31
600 | 571 | 29
700 | 676 | 24
800 | 782 | 18
900 | 889 | 11
1000 | 1000 | 0
Neue Tabelle geglättet.
-----------------------
Ist Soll Abweichung
0 0 0
43 50 7
132 150 18
...
In dieser neuen Tabelle suchst du jetzt einfach nach dem Punkt links und
rechts deines Messwerts und führst eine lineare Approximation zwischen
diesen beiden Punkten Xn und Xn+1 durch.
Y = Yn + (X-Xn)/(Xn+1 - Xn)*(Yn+1 - Yn)
Gruß
Helmut
Ich sehe zwei Wege:
1) Man berechnet aus n Kalibrierungswerten um den aktuellen Messwert ein
Polynom (n-1) Grades und nimmt das als Wert. Vorteil: Man kann die
Parameter direkt berechnen. Nachteil: Man ist auf Polynome festgelegt
und dass die Kalibrierungswerte auch fehlerbehaftet sein können, geht
nicht ein.
2) Man denkt sich eine "sinnvolle", differenzierbare(!) Funktion aus,
die von möglichst wenig Parametern abhängt und den gesamten Bereich
beschreiben soll. Die Parameter erhält man dann durch Fitten, d.h. die
Parameter werden solange variiert bis die Abweichung zur Messkurve
minimal wird.
Die bekannte "lineare Regression" ist z.B. so etwas. Weil sie so einfach
ist, kann man da die Parameter noch mit Formeln berechnen. In der Regel
muss man aber nummerische Näherungsverfahren einsetzen. Wie weit man das
mit einem Controller treiben kann, der ja nicht direkt ein
"Number-Cruncher" ist, habe ich allerdings noch nicht ausprobiert.
ich habe das ganze jetzt nur überflogen. Wird ganz schön kompliziert
gemacht.
Ich würde es so angehen. Da du die Abweichung ja kennst erstelle eine
Kennlinie zur Kompensation. Wenn dein Messwert nun 127 ist bewegst du
den Z-Pointer in der Kennlinie um 127 Stellen nach rechts, ließt den
Kompensationswert ein und zieht ihn vom deinem Messwert ab und schon
hast du das korrekte Ergebnis. Beim nächsten mal den Pointer wieder auf
0 setzen und das gleiche nochmal. Das muss man doch wirklich nicht den
µC rechnen lassen.
Schau dir mal im Instruction Set den Befehl LPM an.
Kompensationslinie kannst du dir ja in Excel erstellen lassen und der µC
muss nur an die richtige Stelle springen um sich den Wert zu holen.
Thomas O. schrieb:> Ich würde es so angehen. Da du die Abweichung ja kennst erstelle eine> Kennlinie zur Kompensation. Wenn dein Messwert nun 127 ist bewegst du> den Z-Pointer in der Kennlinie um 127 Stellen nach rechts, ließt den> Kompensationswert ein und zieht ihn vom deinem Messwert ab und schon> hast du das korrekte Ergebnis.
Da er 1000 mögliche Messwerte hat, bedeutet das, das du eine Tabelle mit
1000 Einträgen
a) im Speicher haben muss
b) vom Kunden (oder zumindest beim Kunden) auch gewartet werden muss.
> 0 setzen und das gleiche nochmal. Das muss man doch wirklich nicht den> µC rechnen lassen.
Irgendwer muss deine vorgeschlagene Tabelle aufnehmen und berechnen. Wer
genau macht das vor Ort, wenn es gilt ein Gerät einzumessen?
> Kompensationslinie kannst du dir ja in Excel erstellen lassen und
Das bedeutet aber auch, du setzt vorraus das dein Kunde ein Excel hat.
Er schaltet dein Gerät ein, geht auf kalibrieren, das Gerät führt in
durch die Kalibrierprozedur, gibt ihm ein paar Kennzahlen. Die tippt er
im Excel ein, woraufhin Ecxel (grummel, grummel, grummel) eine Kurve
berechnet undd daraus eine Tabelle mit 1000 Werten bestimmt. Soweit ist
mir das noch klar.
Und wie kommen jetzt die Tabellen-Werte in den µC?
Danke mal für Eure Hilfe. Anjas "Brute Force" habe ich prinzipiell schon
angewendet, ohne den Begriff zu kennen.
Karl Heinz : 1000 Werte ist wohl nur theoretisch. Würde das dann eine
Genauigkeit/ Abweichungskorrektur im Promille- Bereich (?) bedeuten,
was ja nicht notwendig ist, weil andere Stör- Parameter (Temperatur
etc.)größere Abweichungen hervorrufen. Mit 100 Korrektur- Werten liegt
man (?) ja bei +/1 % Abweichung. Sehe ich das richtig?
Leider schrieb:> Danke mal für Eure Hilfe. Anjas "Brute Force" habe ich prinzipiell schon> angewendet, ohne den Begriff zu kennen.> Karl Heinz : 1000 Werte ist wohl nur theoretisch. Würde das dann eine> Genauigkeit/ Abweichungskorrektur im Promille- Bereich (?) bedeuten,
Äh nein.
Beim Vorschlag vom Thomas (der ja prinzipiell nicht schlecht ist)
bedeutet das:
Dein Sensor liefert über den ADC zb. 1024 Werte
also muss auch die Tabelle 1024 Einträge haben.
Was er vorschlägt:
Nimm den Wert vom ADC, geh damit in eine Tabelle und hol dir den
Korrekturwert für diesen ADC Wert. Simpel, einfach und doch nicht so
ganz brauchbar:
Nimmst du einen 12 Bit ADC, dann ist deine Tabelle 4096 Bytes groß
das mit der Größe der Tabelle in Abhängigkeit wäre vielleicht ein
Argument aber man kann das ganze auch im Codesegment ablegen, Flash
gibts ja genug also statt eines ATM16 nimmt man halt einen ATM32, hat 16
kByte für seine Tabellen und braucht weder EEPROM noch SRAM zu
verschenken.
Tippen muss man ja die Tabelle auch nicht selber, sondern kanns per
Copy&Paste aus Excel in das AVR-Studio einbringen. Und die komplizierte
Berechnungen kann man auch in Excel durchführen lassen.
Thomas O. schrieb:> das mit der Größe der Tabelle in Abhängigkeit wäre vielleicht ein> Argument aber man kann das ganze auch im Codesegment ablegen, Flash> gibts ja genug also statt eines ATM16 nimmt man halt einen ATM32, hat 16> kByte für seine Tabellen und braucht weder EEPROM noch SRAM zu> verschenken.>> Tippen muss man ja die Tabelle auch nicht selber, sondern kanns per> Copy&Paste aus Excel in das AVR-Studio einbringen. Und die komplizierte> Berechnungen kann man auch in Excel durchführen lassen.
Was ich bei solchen Sachen auch gerne mache ist folgendes:
Muss der Controller die korrigierten Messwerte nicht direkt anzeigen
oder weitergeben, speichert der Controller nur die Koeffizienten und
liefert sie beim Auslesen mit. Die Berechnungen und Korrekturen laufen
auf dem PC/Server.
Hallo,
habe gerade das Grundproblem gelesen und schrecklich komplizierte
Vorschläge.
Wie wäre es mit folgenden Überlegungen:
1. Parabel, Nullstellen x=0 und x=1000 ==> f(x)= -a*x*(x-1000)
2. Bei x=500 muss 31 raus kommen ==> a=31/500^2 = 0,000124
Excel liefert mir die angehängte Tabelle
und die sieht doch ganz gut aus.
(Mathe LK Stufe 11)
Schüler schrieb:> 1. Parabel, Nullstellen x=0 und x=1000 ==> f(x)= -a*x*(x-1000)
Was, wenn dem nicht so wäre?
>> 2. Bei x=500 muss 31 raus kommen ==> a=31/500^2 = 0,000124
Warum bei 500?
Laut Tabelle muss auch bei 400 die 31 rauskommen
> und die sieht doch ganz gut aus.
In der Tat. Gute Arbeit.
Trotzdem solltest du noch einmal darüber nachdenken, ob du dein
Verfahren verallgemeinern kannst, so dass du nicht mehr darauf
angewiesen bist, dass
* der Fehler an den Intervallenden exakt 0 ist
* das Maximum in der Mitte deiner Messwerte liegt.
Klar kann ich Polynome höheren Grades nehmen.
Ist mehr Rechenarbeit, schwieriger und liefert sicher kleinerer
verbleibende Abweichungen.
Aber was ist das wichtigere?
Eine einfache aber praktikabele Lösung für den Fragesteller oder eine
Vorlesung über Fehlerkorrekturen.
Auch bei meiner Variante gibts sicher noch Verbesserungen.
Aber lohnt sich der Aufwand ein komplizierteres Polynom zu nehmen um
eine Abweichung von 1,24 bei x=400 zu vermeiden?
Ich habe noch eine Idee.
Unter dem Thema Spline-Interpolation findet man auch einen Lösungsweg.
Mein Lehrer aus der 9. Klasse hat mir das mal erklärt, als wir lineare
Gleichungssysteme behandelt haben.
Ein Freund von mir hat am Gymi ne Facharbeit (Stufe 12) dazu
geschrieben.
Dann sind die Messwerte an allen vorgegebenen Punkten richtig.
Schüler schrieb:> Aber lohnt sich der Aufwand ein komplizierteres Polynom zu nehmen um> eine Abweichung von 1,24 bei x=400 zu vermeiden?
Ich hab das Gefühl du fühlst dich persönlich angegriffen.
Daher möchte ich dir versichern, dass das nicht meine Absicht ist.
Ich möchte dich nur dazu bringen, ein paar Gedankengänge zu machen.
> Klar kann ich Polynome höheren Grades nehmen.
Natürlich.
Wurde ja ebenfalls auch schon angesprochen. Inklusive der Mathe
dahinter, wie man sie bestimmt.
> Ist mehr Rechenarbeit, schwieriger und liefert sicher kleinerer> verbleibende Abweichungen.>> Aber was ist das wichtigere?
Das wichtigste ist in der Programmierung IMMER, das Verfahren nicht nur
dann funktionieren wenn man die richtigen Zahlenwerte einsetzt :-)
Auch wichtig: Das man keinen Spezialisten braucht um ein Programm
bedienen (in diesem Fall kalibrieren) zu können.
> Eine einfache aber praktikabele Lösung für den Fragesteller oder eine> Vorlesung über Fehlerkorrekturen.
Deine einfache, praktikable Lösung hängt nun mal von ein paar
Voraussetzungen und Annahmen ab. Ob die ein Problem darstellen oder
nicht, können wir nicht beurteilen, das kann nur der TO.
Aber im Zweifelsfall ist man in der Programmierung immer gut beraten,
wenn man so wenige Annahmen wie möglich machen muss.
Es ist leicht ein Programm zu schreiben, wenn man nicht allgemein sein
muss. Das in einer speziellen Problemstellung ruhende allgemeinere
Problem zu lösen um sich damit aus der sicher scheinenden Welt dieser
speziellen Problemstellung zu lösen, ist aber oftmals um einiges
schwieriger und erfordert mehr Aufwand.
Und nochmal: Ich finde es gut, wenn du dich beteiligst und dir Dinge
überlegst. Gute Arbeit!
(Und das meine ich ehrlich)
Schüler schrieb:> Unter dem Thema Spline-Interpolation findet man auch einen Lösungsweg.> Dann sind die Messwerte an allen vorgegebenen Punkten richtig.
Die Erfahrung habe ich auch gemacht... nur mit dem Problem: nur an den
vorgegebenen Punkten. Dazwischen schwingt es oft mehr oder weniger
heftig.
In realen Aufgabenstellungen mit realen Meßwerten (einschließlich
Meßfehlern und Rauschen) habe ich noch nie mittels Splines
zufriedenstellende Interpolationen erreicht. Würde mich mal
interessieren unter welchen Randbedingungen (außer dem Schiffsbau) dies
gelingt.
Gruß Anja
Anja schrieb:> Schüler schrieb:>>> Unter dem Thema Spline-Interpolation findet man auch einen Lösungsweg.>> Dann sind die Messwerte an allen vorgegebenen Punkten richtig.> Anja schrieb:> Die Erfahrung habe ich auch gemacht... nur mit dem Problem: nur an den> vorgegebenen Punkten. Dazwischen schwingt es oft mehr oder weniger> heftig.
Hallo Anja,
ich habe mich auch schon mit der Spline-Interpolation und kann mit
Sicherheit sagen, dass du die Polynom-Interpolation mit der
Spline-Interpolation verwechselst.
Die Polynom-Interpolation "schwingt" heftig und gerade diesen
Schwachpunkt besitzt die Spline-Interpolation nicht.
Harald Wünsch schrieb:> Ich würde ja dann die ADC-Werte korrigieren, die würden sich also nicht> wiederholen, da sie von bsp. 110000 (Offset) bis 900000 (Endwert)> laufen.
Also ich gehe mal davon aus daß Harald mindestens einen 20-Bit
A/D-Wandler hat. Das Rauschen des Sensors dürfte allerdings so bei 0,1
bis 1 mBar liegen.
Gruß Anja
hallo Harald,
nene..echt ned. Im Gegenteil: mich hat es fasziniert, dass du da so dran
geblieben bist! Ich bin schon ganz früh ausgestiegen...bin da leider
überhaupt ned bewandert.
Es war echt "bewundernd" gemeint...und die ist gestiegen...wie sich der
Thread die letzten 24 Stunden entwickelt hat :-)
Wünsch euch weiterhin viel Spass und Erfolg, bin aber jetzt still :-)
mfg
foikei
Schüler schrieb:> ich habe mich auch schon mit der Spline-Interpolation und kann mit> Sicherheit sagen, dass du die Polynom-Interpolation mit der> Spline-Interpolation verwechselst.
Glaube ich nicht.
> Die Polynom-Interpolation "schwingt" heftig und gerade diesen> Schwachpunkt besitzt die Spline-Interpolation nicht.
Du hast natürlich Recht: bei gleicher Anzahl von Meßwerten (z.B. 10)
schwingt eine Parabel höherer Ordnung (in dem Fall 9.) viel stärker als
ein Kubischer Spline (bestehend aus Parabeln 3. Ordnung).
Trotzdem: dadurch daß ein Spline immer genau durch die Meßwerte geht
(egal ob diese mit großen oder kleinen Meßfehlern behaftet sind) ergibt
sich zwischen den Meßwerten häufig ein ungewolltes Schwingen. Die
Splines haben nur den Anspruch mit möglichst geringer Krümmung durch die
vorgegebenen Meßpunkte zu laufen.
Bei dem von mir angesprochenen Beispiel wollte ich den Temperaturgang
eines Quarzoszillators mittels Temperaturfühler und Kapazitätsdiode auf
10^-7 (oder besser) über 0..70 Grad mit möglichst wenig
Temperaturmeßpunkten (bzw. Kalibrierdauer) bei der Kalibrierung stabil
halten.
Der 1. Ansatz mit Polynom 5. oder 7. Ordnung (was sich aus der
Überlagerung der Bauteile hätte ergeben sollen) ist wegen starker
Schwingungen gescheitert. Bei den Splines hätte ich so viele Meßpunkte
bzw. Koeffizienten gebraucht (mindestens 20-30 Splines und damit
mindestens 80-120 Floating Point Koeffizienten) daß es einfacher war 1
Grad-Schritte linear zu approximieren. Da mußte dann auch kein
Verifizerungslauf gestartet werden ob die gefundene Interpolation nicht
doch zwischendrin irgendwo schwingt.
Damals kannte ich die Methode der kleinsten Fehlerquadrate leider noch
nicht, so daß ich nicht sagen kann ob hier mittels Parabel 7. oder 9.
Ordnung ein besseres Ergebnis hätte erzielt werden können.
Gruß Anja
Anja schrieb:> Schüler schrieb:>> Unter dem Thema Spline-Interpolation findet man auch einen Lösungsweg.>>> Dann sind die Messwerte an allen vorgegebenen Punkten richtig.>> Die Erfahrung habe ich auch gemacht... nur mit dem Problem: nur an den> vorgegebenen Punkten. Dazwischen schwingt es oft mehr oder weniger> heftig.>> In realen Aufgabenstellungen mit realen Meßwerten (einschließlich> Meßfehlern und Rauschen) habe ich noch nie mittels Splines> zufriedenstellende Interpolationen erreicht. Würde mich mal> interessieren unter welchen Randbedingungen (außer dem Schiffsbau) dies> gelingt.>> Gruß Anja
Sieh dir mal den Link von oben
(http://en.wikipedia.org/wiki/Monotone_cubic_interpolation) an...
Diese Variante garantiert, dass die Interpolante zw. den Stützstellen
monoton ist.
So, ich muss mich jetzt ja auch mal wieder zurückmelden!
Also ich freue mich ebenfalls sehr, wie sich dieses Thema hier mit
qualifizierten Antworten füllt.
Ich habe die letzten zwei Tage mal ein wenig Mathematik nachgeholt (muss
ich leider abends machen, da auf der Arbeit nicht möglich :)
Also um die eine Frage zu beantworten: Es ist ein 20Bit ADC, da ist
immer etwas Rauschen drin, klar.
"Meine" geeignetste Methode habe ich noch nicht gefunden, aber es sollte
natürlich so "allgemeingültig" wie möglich sein, ohne schwierige
Kalibrierung.
Schüler schrieb:> habe gerade das Grundproblem gelesen und schrecklich komplizierte> Vorschläge.>> Wie wäre es mit folgenden Überlegungen:>> 1. Parabel, Nullstellen x=0 und x=1000 ==> f(x)= -a*x*(x-1000)>> 2. Bei x=500 muss 31 raus kommen ==> a=31/500^2 = 0,000124>> Excel liefert mir die angehängte Tabelle>> und die sieht doch ganz gut aus.>> (Mathe LK Stufe 11)
Ist denn das nicht genau falsch herum? Also die die Sollwerte sind ja
die wichtigen und die Messwerte die falschen.
Solche Polynome zur Laufzeit für jeden Messwert vom Controller
ausrechnen zu lassen kann schnell an die Grenzen zeitlicher
Anforderungen führen. Ich hatte ein ganz ähnlichen Problem und habe es
lieber mit einem Geradenabgleich mit n Punkten und n-1
Geradengleichungen gemacht, die Steigungen und Offsets einmal berechnen
lassen und dann im Flash / EEPROM gespeichert. Die Genauigkeit leidet
dabei nur unwesendlich im Vergleich zu einem Polynom.
Zur Berechnung des Polynoms kann ich dir Matlab oder alternative die
kostenlosen Tools in dieser Richtung empfehlen. Die können auch
anspruchsvollere Interpolationsverfahren, wenn es mal ganz genau werden
muss.
Es halt nur immernoch so, dass ich nicht vorher mit dem ADC Messwerte
aufnehmen kann, diese dann in Excel reinschicken kann, da eine
Korrekturhilfe erstellen lassen kann und diese Werte dann wieder zurück
in den uC, sondern das sollte nach Möglichkeit schon Controller-intern
passieren. Also dass ich einmal eine Gleichung aufstelle, diese
reinprogrammiere und der Controller dann die Messwerte am Anfang einmal
da durch schickt und die Korrekturfaktoren selber errechnet und
abspeichert.
Hallo,
@Harald Wünsch
Wie wird denn nun kalibriert.
Stellst Du deinen Kontroller auf Kalibrieren und dann erscheint 100 mBar
einstellen, wenn passend mit geeichtem Gerät geprüft, dann Taste drücken
und das sukzessive bis 1000 mBar?
Anschliessend soll der Kontroller die Zwischenwerte und Umrechnung
selbst erledigen.
Oder wie oder was?
Hallo Harald,
es gibt hier deshalb so viele Lösungsansätze, weil du die Anforderungen
nicht spezifiziert hast. z.B.: Können die Werte der Kalibrierung als
genau angenommen werden?
Eine einfache Lösung wäre die lineare Annäherung zwischen zwei
Stützpunkten. Du trägst die Werte der Kalibrierung in eine Tabelle (x_n,
y_n). Für einen neuen Messwert x durchsuchst du die Tabelle, so dass
gilt. Dann ist
Die Steigung kann man natürlich schon gleich nach der Kalibrierung
ausrechnen und ebenfalls in die Tabelle eintragen. Wenn aber die Messung
eines y_n fehlerhaft war, hast du halt Pech gehabt.
Gruß, DetlevT
OK, also folgendes habe ich vor:
Ich habe mein eigenes Konstrukt (also Messzelle, ADC, Mikrocontroller,
LCD) und ich habe ein Referenzgerät, welches den Druck relativ genau
anzeigen kann.
Jetzt kalibriere ich mein eigenes Gerät, indem ich den Druck einstelle
(mit dem genauen Messgerät) - Jetzt mal an einem Beispiel von 0 - 1 bar:
0 mbar -> ADC-Wert der Zelle aufnehmen
250 mbar -> ADC-Wert der Zelle aufnehmen
500 mbar -> ADC-Wert der Zelle aufnehmen
750 mbar -> ADC-Wert der Zelle aufnehmen
1000 mbar -> ADC-Wert der Zelle aufnehmen
Der Controller weiß jetzt, dass er fünf Messpunkte hat und weiß auch,
dass der erste zu 0 mbar gehört, der zweite zu 250 mbar usw.
Jetzt hat er dadurch fünf Wertepaare, mit denen er eine Linearisierung
anstellen soll.
Achso:
Bis jetzt nehme ich halt 0 mbar und 1000 mbar auf und habe somit eine
Spanne im ADC-Wert-Bereich, sowie meine Spanne von 1000 mbar.
Hierdurch kann ich mit jedem ADC-Wert einen Druckwert errechnen.
Also quasi in etwa nach dem Schema:
1
Druckspanne
2
Druck-Wert=-------------*(ADC-Wert-Offset)
3
ADC-Spanne
Leider nehmen die Werte auf Grund der Nichtlinearität in der Zelle zur
Mitte größere Fehler an. Und genau diese möchte ich herausrechnen.
In der ganzen Diskussion fiehl nicht einmal der Begriff "LUT" (lookup
table)?
Ich würde das System mit einem geeichten Messgerät in 100 oder 200 oder
1000 Schritten kalibrieren, auf dem PC die Korrekturwerte berechnen und
in den MC laden. Der braucht dann garnix mehr rechnen, nur etwas
Speicher ...
Frank
Harald Wünsch schrieb:> Achso:>> Bis jetzt nehme ich halt 0 mbar und 1000 mbar auf und habe somit eine> Spanne im ADC-Wert-Bereich, sowie meine Spanne von 1000 mbar.>> Hierdurch kann ich mit jedem ADC-Wert einen Druckwert errechnen.>> Also quasi in etwa nach dem Schema:>
1
>Druckspanne
2
>Druck-Wert=-------------*(ADC-Wert-Offset)
3
>ADC-Spanne
4
>
>> Leider nehmen die Werte auf Grund der Nichtlinearität in der Zelle zur> Mitte größere Fehler an. Und genau diese möchte ich herausrechnen.
Dann hast du ja eh schon die halbe Miete :-)
Probiers doch zuerst mit einer feineren Unterteilung.
Du musst ja nicht den Fehler an sich ausrechnen.
Anstelle das du nur einen Satz von Umrechnungswerten vom ADC Wert in
deinen Druck hast, hast du jetzt zb 2.
So wie du jetzt bei 0 und bei 1000 aufgenommen hast, nimmst du bei 3
auf.
0, 500, 1000
Kriegst du einen ADC Messwert, dann siehst du einfach in dieser Tabelle
nach, welcher der beiden Bereiche 0 bis 500 oder 500 bis 1000 zuständig
ist und benutzt dann denjenigen Satz von UMrechnungswerten, die du dir
für diesen Bereich bei der Kalibrierung berechnet hast.
Und wenn du das jetzt weiter denkst, verallgemeinert das wunderbar. Kein
Mensch zwingt dich, da jetzt nur 2 Bereiche zu benutzen. Du kannst auch
4 oder 8 oder 10 oder 15 benutzen. Ist nur eine Frage dessen, was du
deinem Benutzer bei der Kalibrierung zumutest.
Damit hast du genau das realisiert, was schon die ganze Zeit immer
wieder vorgeschlagen wird: stückweise lineare Approximation.
Und die Änderungen sind nun wirklich einfach zu machen. Das meiste davon
hast du ja schon. Du musst nur deine Umrechnungswerte in einer Tabelle
organsieren und noch mit in die Tabelle aufnehmen, wann welcher
Tabellensatz gilt abhängig vom ADC Wert. Ehe du den ADC Wert in den
Druck umrechnest, gehst du die Tabelle durch und siehst nach, welcher
Satz von Umrechnungswerten zuständig ist. Fertig.
Wundert mich, dass du das nicht schon längst ausprobiert hast. Nur Mut,
das ist schnell realisiert. In weniger als 1 Stunde hast du das.
ja so eine Lookup-Tabelle habe ich vorgeschlagen, aber bei 20 Bit
Auflösung ist das wohl nicht praktikabel und anscheinend soll der Sensor
sich selbst kalibrieren. Aber im Prinzip bleibt es immer eine
Interpolation da ja ein Sensor sich an einem Punkt nichtlinear verhält.
20bit sind etwas mehr als 1 Millionen Werte also die Tabelle wäre sehr
groß.
Man könnte aber die Lookuptabelle kleiner auslegen und dazwischen noch
interpolieren.
Ich habe sowieso die Befürchtung das der Sensor diese Auflösung garnicht
bieten. Was soll der den messen das Husten einer Mücke?