Forum: Mikrocontroller und Digitale Elektronik Mit Microcontroller eine Linearisierungskurve erstellen und für Berechnungen verwenden


von Harald Wünsch (Gast)


Lesenswert?

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

von Purzel H. (hacky)


Lesenswert?

Der Standardansatz ist ein Polynom:

Pneu:=Offset + a0*Pmess + a1*Pmess^2 + a2*Pmess^3+ .....

von Marius W. (mw1987)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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?

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

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

von Horst H. (horha)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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
   a   b   c   |   y1
2
       b   c   |   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

von Master S. (snowman)


Lesenswert?

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

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

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%29

http://en.wikipedia.org/wiki/Fixed-point_theorem

http://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

von Harald Wünsch (Gast)


Lesenswert?

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:
1
   x   |   y
2
   ---------
3
   0   |  20
4
   2   |  26
5
   4   |  28
6
7
   a   + b*0^1 + c*0^2 = 20
8
   a   + b*2^1 + c*2^2 = 26
9
   a   + b*4^1 + c*4^2 = 28
10
11
   a                   = 20
12
   a   +  2b   +  4c   = 26
13
   a   +  4b   + 16c   = 28
14
15
   Den Koeff. a habe ich (a = 20) - diesen setze ich in die 2. Gl. ein:
16
17
     20 + 2b + 4c = 26
18
<=>  2b = 6 - 4c
19
<=>  b = 3 - 2c
20
21
   Nun setze ich a und b in die dritte ein:
22
23
     20 + 4(3 - 2c) + 16c = 28
24
<=>  20 + 12 - 8c + 16c = 28
25
<=>  32 - 8c = 28
26
<=>  -8c = -4
27
<=>  c = 0.5
28
29
   Jetzt setze ich a und c wieder in die zweite Gleichung ein:
30
31
     20 + 2b + 4(0.5) = 26
32
<=>  20 + 2b + 2 = 26
33
<=>  22 + 2b = 26
34
<=>  2b = 4
35
<=>  b = 2
36
37
   Somit habe ich meine Koeffizienten
38
39
     a = 20
40
     b = 2
41
     c = 0.5
42
43
   Und damit meine Gleichung: y = 20 + 2x + 0.5x^2


Sehe ich das so richtig? Sorry, ist schon was her.


Harald

von Master S. (snowman)


Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

Super!!


Besten Dank für die ganze Mühe! Ich bin dabei...


Harald

von Harald Wünsch (Gast)


Lesenswert?

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 = 20     RICHTIG
10
y(2) = 20 + 2(2) + 0.5(2^2) = 20 + 4 + 2 = 26     RICHTIG
11
y(3) = 20 + 2(4) + 0.5(4^2) = 20 + 8 + 8 = 36     FALSCH

Sieht da jemand den Fehler?

von Karl H. (kbuchegg)


Lesenswert?

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 
:-)

von Karl H. (kbuchegg)


Lesenswert?

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 = 20     RICHTIG
10
> y(2) = 20 + 2(2) + 0.5(2^2) = 20 + 4 + 2 = 26     RICHTIG
11
> y(3) = 20 + 2(4) + 0.5(4^2) = 20 + 8 + 8 = 36     FALSCH
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.

von Harald Wünsch (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anja (Gast)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Matthias N. (nippey)


Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?

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

von Horst H. (horha)


Lesenswert?


von STK500-Besitzer (Gast)


Lesenswert?

Prima! Nach 24 Jahren endlich den Stoff aus der 8. Klasse (Lösung 
Linearer Gleichungssysteme) verstanden.
Danke Karl-Heinz!

von Harald Wünsch (Gast)


Lesenswert?

Horst Hahn schrieb:
> und es wiederholt sich

?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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

von Matthias N. (nippey)


Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anja (Gast)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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.

von Anja (Gast)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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?

von Arc N. (arc)


Lesenswert?

Von Microchip gibt's dazu auch eine AppNote
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en024238

Anderes Stichwort wäre Spline-Interpolation. Will man das 
Über/Unterschwingen verhindern und die Monotonität erhalten, dann z.B.
http://en.wikipedia.org/wiki/Monotone_cubic_interpolation

von Anja (Gast)


Lesenswert?

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

von Helmut S. (helmuts)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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 :)

von Karl H. (kbuchegg)


Lesenswert?

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 :)

von Anja (Gast)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

OK Anja, du scheinst mir ein Linearisierungs-Profi zu sein!

Also um mal Konkret zu werden:
1
Ich habe beispielsweise folgende Werte [mbar]:
2
3
(Ich habe Anfangs- und Endpunkt aufgenommen und durch 1000 mbar geteilt -
4
 Den ADC-Wert rechne ich um und lasse ihn mir anzeigen.
5
 Die Messzelle ist eine alte, ich benutze sie zu Testzwecken, daher sehr
6
 verschoben.)
7
8
  Soll  |  Ist  |  Abweichung
9
  ---------------------------
10
      0 |    0  |  0
11
    100 |   86  | 14
12
    200 |  178  | 22
13
    300 |  272  | 28
14
    400 |  369  | 31
15
    500 |  469  | 31
16
    600 |  571  | 29
17
    700 |  676  | 24
18
    800 |  782  | 18
19
    900 |  889  | 11
20
   1000 | 1000  |  0
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.

von Horst H. (horha)


Lesenswert?

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/Polynominterpolation
http://de.wikipedia.org/wiki/Lineare_Regression
http://de.wikipedia.org/wiki/Kubischer_Spline


es klingelt...

von Harald Wünsch (Gast)


Lesenswert?

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...

von Harald Wünsch (Gast)


Lesenswert?

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 :)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anja (Gast)


Angehängte Dateien:

Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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³

von Harald Wünsch (Gast)


Lesenswert?

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!

von Helmut S. (helmuts)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Helmut S. (helmuts)


Lesenswert?

Ah, ich glaube ich verstehe dich. Ich hätte für x die Meswwerte/100 
nehmen sollen.
Jetzt ist die Abweichung ca. 3.8 .


-->

-->//x=[0,1,2,3,4,5,6,7,8,9,10];

-->x=[0,0.86,1.78,2.72,3.69,4.69,5.71,6.76,7.82,8.89,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  =

    23871.536    2855.6969    365.4048
    2855.6969    365.4048     52.92
    365.4048     52.92        66.

-->b
 b  =

    5403.5502
    953.52
    208.

-->c=inv(a)*b
 c  =

  - 1.314794
    12.86851
    0.1125833

-->

-->// 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.1125833
  - 3.7929198
  - 3.1472623
  - 2.6124417
  - 1.3049819
    0.5455542
    1.7240993
    3.0207792
    2.3415211
  - 0.3972960
  - 2.6817195




// Scilab-Code

//x=[0,1,2,3,4,5,6,7,8,9,10];
x=[0,0.86,1.78,2.72,3.69,4.69,5.71,6.76,7.82,8.89,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

von Anja (Gast)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

Helmut S. schrieb:
> Jetzt ist die Abweichung ca. 3.8

Paßt in etwa zu meinen 3.5 bei Extended Float.

Gruß Anja

von Helmut S. (helmuts)


Lesenswert?

Scilab rechnet mit double.

von Helmut S. (helmuts)


Lesenswert?

Hab gerade noch einen Fehler in meinem Programm entdeckt.
Komm jetzt auch auf die 3,5.
Da musste eine 1 rein.
a1=[x(k)^4,x(k)^3,x(k)^2; x(k)^3,x(k)^2,x(k); x(k)^2,x(k),1]

http://math.fullerton.edu/mathews/n2003/leastsquarespoly/LeastSqPolyProof.pdf

Das lineare Gleichungssystem lautet
(a)*(c) = (b)

Im Fehlerarray (e) siehst man die Abweichung von der Parabel

// Scilab-Code

//x=[0,1,2,3,4,5,6,7,8,9,10];
x=[0,0.86,1.78,2.72,3.69,4.69,5.71,6.76,7.82,8.89,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),1];
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

        _________________________________________
                         scilab-4.1.2

                  Copyright (c) 1989-2007
              Consortium Scilab (INRIA, ENPC)
        _________________________________________


Startup execution:
  loading initial environment

-->// Scilab-Code

-->

-->//x=[0,1,2,3,4,5,6,7,8,9,10];

-->x=[0,0.86,1.78,2.72,3.69,4.69,5.71,6.76,7.82,8.89,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),1];
-->a=a+a1;
-->b1=[x(k)^2*y(k);x(k)*y(k); y(k)];
-->b=b+b1;
-->end

-->a
 a  =

    23871.536    2855.6969    365.4048
    2855.6969    365.4048     52.92
    365.4048     52.92        11.

-->b
 b  =

    5403.5502
    953.52
    208.

-->c=inv(a)*b
 c  =

  - 1.2105883
    11.567352
    3.4736816

-->

-->// 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  =

    3.4736816
  - 1.4737468
  - 1.7720597
  - 2.0195372
  - 1.3262804
    0.0963418
    1.0531205
    2.3480025
    1.899996
  - 0.3678926
  - 1.9116257

-->

von Harald Wünsch (Gast)


Lesenswert?

Man oh man, ich weiß garnicht, was ihr da alles rechnet...

von Anja (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anja (Gast)


Lesenswert?

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

von Obermayer F. (Firma: tbd) (foikei)


Lesenswert?

und das in 13,5 Stunden...ihr seid echt wahnsinn :-) faszinierend 
Captain...

von Harald Wünsch (Gast)


Lesenswert?

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...

von Ralf G. (old-school) Benutzerseite


Lesenswert?

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

von Leider (Gast)


Lesenswert?

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 ?

von Anja (Gast)


Lesenswert?

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

von Helmut S. (helmuts)


Lesenswert?

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

von Detlev T. (detlevt)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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?

von Leider (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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ß

von Thomas (kosmos)


Lesenswert?

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.

von Arc N. (arc)


Lesenswert?

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.

von Schüler (Gast)


Angehängte Dateien:

Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Schüler (Gast)


Lesenswert?

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?

von Schüler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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)

von Anja (Gast)


Lesenswert?

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

von Thomas (kosmos)


Lesenswert?

wie hoch ist den nun die Auflösung des ADC an dem der Sensor hängt?

von Schüler (Gast)


Lesenswert?

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.

von Anja (Gast)


Lesenswert?

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

von Obermayer F. (Firma: tbd) (foikei)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Arc N. (arc)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Nico (Gast)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Horst H. (horha)


Lesenswert?

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?

von Detlev T. (detlevt)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

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.

von Harald Wünsch (Gast)


Lesenswert?

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.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

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

von Harald Wünsch (Gast)


Lesenswert?

Doch, die Look-Up-Table war auch schon im Gespräch.

Nur dann muss immer der PC beteiligt sein. Das geht nicht, der uC muss 
alleine klarkommen ;-\

von Karl H. (kbuchegg)


Lesenswert?

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.

von Horst H. (horha)


Lesenswert?

Hallo,

eine schöne Internetseite zu kubischen Splines:
http://www.arndt-bruenner.de/mathe/scripts/kubspline.htm
Setze mal dort Deine Werte ein:
gemessen-> richtig
-schnipp-
    0      0
   86    100
  178    200
  272    300
  369    400
  469    500
  571    600
  676    700
  782    800
  889    900
 1000   1000
-schnapp-

Erst ab 6 Dezimalen kommen x^3 Glieder vor, etwa 20 Bit.
1
x aus [0; 86]
2
S0(x) = -0,000003x^3 + 1,181332x //+0
3
      = -0,000003x^3 + 1,181332x
4
..
5
x aus [782; 889]  / ergibt f(x) aus 800..900 
6
S8(x) = -0,000001(x-782)^3 + 0,000001(x-782)^2 + 0,942801(x-782) + 800
7
      = -0,000001x^3 + 0,001701x^2 - 0,387691x + 409,687939
Man sieht dort die leichte Berechnenbarkeit der Koeffizienten.
d_i= y_i, b leicht zu rechnen -> a_i ,c_i

von Thomas (kosmos)


Lesenswert?

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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.