Forum: Mikrocontroller und Digitale Elektronik Geeignete Linearisierung


von Markus (Gast)


Lesenswert?

Hallo

Ich möchte eine Linearisierung meiner Datenwerte durchführen und hab 
dazu Excel eingesetzt, welches mir die Funktion zu
y = y1 = -0.0002681x^2 + 0.5280417x + 171.1323514
bestimmt hat. x ist dabei der Wert des ADCs. Die Funktion kann ich nun 
natürlich auch noch umschreiben zu
y = y2 = 0.5280417x*(1 - 0.00050773x) + 171.1323514
y = y3 = -0.0002681x*(x - 1969.56994) + 171.1323514
Wie bestimme ich nun eine für den uC geeignete Funktion?

Da der uC ja nur mit Ganzzahlen rechnet könnte ich die Funktion z. b. in 
y = (-2681*ADC*ADC + 5280417*ADC + 1711323514)/1'000'000'000 oder etwas 
gerundet y = (-3*ADC*ADC + 5280*ADC + 17113235)/1'000'000 umwandeln

Nun meine Frage: Von welcher Gleichung (y1, y2 oder y3) gehe ich am 
besten aus?

Ist es sinnvoll mit solch hohen Zahlen auf einem uC (ATTiny13) zu 
rechen? Falls ich stärker runde, fällt mir ja dann der Quadratische Term 
raus und meine Trendkurve ist nicht mehr so schön=(

Gibts schlauere Methoden?

Danke für eure Inputs!

von Karl H. (kbuchegg)


Lesenswert?

Markus schrieb:

> Da der uC ja nur mit Ganzzahlen rechnet

sagt wer?

> könnte ich die Funktion z. b. in
> y = (-2681*ADC*ADC + 5280417*ADC + 1711323514)/1'000'000'000 oder etwas
> gerundet y = (-3*ADC*ADC + 5280*ADC + 17113235)/1'000'000 umwandeln
>
> Nun meine Frage: Von welcher Gleichung (y1, y2 oder y3) gehe ich am
> besten aus?

von denen die dir die besten Ergebnisse liefern.
Du hast weiter oben Excel angesprochen:

mach dir eine Tabelle:

eine Spalte die genaue Formel, eine Spalte y1, eine Spalte y2 ...
Dann einen repräsentativen Satz von Datenpunkten mit jeweils der Formel 
rechnen lassen und die Abweichungen zur genauen Formel feststellen 
(eventuell jeweils ein Diagramm machen). Das geht mit Excel ganz schnell 
und danach hast du eine Entscheidungsgrundlage, die auf Zahlen gestützt 
ist.

>
> Ist es sinnvoll mit solch hohen Zahlen auf einem uC (ATTiny13) zu
> rechen? Falls ich stärker runde, fällt mir ja dann der Quadratische Term
> raus und meine Trendkurve ist nicht mehr so schön=(
>
> Gibts schlauere Methoden?

Wenn deine Zeitvorgaben es erlauben, warum rechnest du nicht einfach 
alles in float?

von Markus (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wenn deine Zeitvorgaben es erlauben, warum rechnest du nicht einfach
> alles in float?

Zeit hat mein uC mehr als genug. Falls ich in float rechne, was muss ich 
dabei beachten? Übernimmt mir das alles der Compiler? Wie heissen die 
(ev. vordefinierten) Datentypen? Hab im AVR-GCC-Tutorial nichts darüber 
gefunden.
Brauche ich für float-Operationen nicht eine spezielle HW, die damit 
umgehen kann?

von Karl H. (kbuchegg)


Lesenswert?

Markus schrieb:

> Zeit hat mein uC mehr als genug. Falls ich in float rechne, was muss ich
> dabei beachten? Übernimmt mir das alles der Compiler?

Ja

> Wie heissen die
> (ev. vordefinierten) Datentypen?


Ähm.  float ?
C-Buch lesen?

> Brauche ich für float-Operationen nicht eine spezielle HW, die damit
> umgehen kann?

Was denkst du, wie man das im letzten Jahrhundert gemacht hat, als es 
noch keine mathem. Coprozessoren gab? Und die machen derartige 
Berechnungen ja auch nicht einfach irgendwie magisch, sondern gehen nach 
Algorithmen vor. Und diese Algorithmen kann man anstelle von in Silizium 
auch in ein Programm giessen.

von Markus (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ähm.  float ?
> C-Buch lesen?

na ja, für ATMegas, und Tinys gibts ja auch (auf Registergrösse) 
optimierte Typen, wie z. B. int8_t, int16_t, ...

Karl Heinz Buchegger schrieb:
> Wenn deine Zeitvorgaben es erlauben, warum rechnest du nicht einfach
> alles in float?

Hab nur ein 1k Flash. Da passt mein Programm mit einer float-Funktion 
leider nicht mehr in den Speicher=(

von Karl H. (kbuchegg)


Lesenswert?

Ooops. den Tiny13 hab ich überlesen.

von Detlef _. (detlef_a)


Lesenswert?

Du rechnest mit integern und bildest den Vorfaktor durch nen Bruch nach, 
in dessen Nenner eine Potenz von zwei steht. z.B. entspricht 0.5280417 
fast 34606/2^16 , du multipliziert also den ADC-Wert mit 34606 und 
schiebst das Ergebnis 16 Stellen nach rechts. Du muß den Zahlenbereich 
beachten: 34606 hat 16Bit, das Produkt mit Deinem ADC-Wert darf bei 32 
Bit Wortbreite keinen Overflow verursachen, ggf. 64 Bit Integertypen 
verwenden, vielleicht passen die in nen tiny.

Vorfaktoren wie 0.00050773 machen keinen Sinn, weil z.B. die Werte eines 
14Bit ADC maximal als Produkt ne 8 liefern. Du muß Dir die Formel so 
aufteilen, dass Du möglichst genau bleibst bei Deiner integerRechnung 
und nicht ohne Not Rechendynamik verschenkst.

Ein anderer Trick besteht darin, den Vorfaktor durch nen beliebigen 
Bruch a/b nachzubilden und den Bruch a/b beispielsweise so zu zerlegen:

a/b= z1/2+z2/4+z3/8 .....

math rulez
Cheers
Detlef

von Anja (Gast)


Lesenswert?

Hallo,

Du solltest darauf achten daß alle Koeffizienten möglichst gleich groß 
sind.
Meist ist es auch günstig den ADC-Wert linksbündig zu erfassen.

Also z.B.

y4 = - (0.0163737 x)^2 + 0.5280417x + 171.1323514
     - (1073 x / 65536)^2 + 34606 x / 65536 + ....

Eventuell kann ja auch Y umnormiert werden z.B. von Meter in cm oder 
umgekehrt um die Koeffizienten noch näher an 1.0 zu setzen.

Gruß Anja

von Markus (Gast)


Lesenswert?

Danke für die Inputs. Ich werde mich eurer Tipps annehmen und 
gegebenenfalls meine Unklarheiten posten.

LG
Markus

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.