mikrocontroller.net

Forum: Compiler & IDEs Korrekturfunktion in Programm einbinden


Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte eine Korrekturfunktion erstellen, womit ich bestimmte 
Variablenwerte korrigieren kann, also Anhand von:

a = Korrekturfunktion(variable b);

Das Problem ist, dass ich die "Korrekturfunktion" nicht habe, sondern 
nur eine Tabelle mit bestimmten diskreten Werten. Das könnte ich mit IF 
oder SWITCH Abfragen machen, wäre aber sehr aufwendig und ich kann nur 
die Werte zuweisen, die in der Tabelle stehen, nicht Werte die zwischen 
den Tabellenwerten liegen.


Jetzt die Frage, gibt es eine Möglichkeit aus den Tabellenwerten eine 
Funktion zu erstellen? Stellt gcc gewisse Funktionen bereit, die einem 
die Korrekturfunktionen erleichtern? Vielleicht über arrays oder 
ähnliches?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem GCC selbst hat das nichts zu tun.  Die Frage ist ja auch,
wie du die Approximation durchführen willst: lineare Interpolation
zwischen den Stützstellen, Polynom n-ten Grades, das durch alle
n+1 Stützstellen durchgeht, Polynom m-ten Grades mit m < n+1 und
geringstem quadratischen Fehler zu allen Stützstellen?

Für all diese Dinge hat die Mathematik Lösungen parat.  Die musst
du in irgendein Programm gießen (das kann ein GCC sein, dass kann
eine Scriptsprache sein wie Perl oder Python, das kann ein
Mathematikprogramm sein), und das lässt du dann deine Tabelle
berechnen.

Autor: Roland Praml (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am Einfachsten (und meistens auch ausreichend) ist wohl lineare 
Interpolation

Mach dir ne Tabelle, welche soritert ist, dann läust die Tabelle durch, 
schaust wann du zum ersten mal größer oder gleich dem Wert im Array 
bist.
(bei größeren Tabellen kann man auch binäre Suche verwenden)
Wenn du die Stelle gefunden hast, dann bist zwischen 2 Stützsstellen.
Dann musst noch das Verhältnis ausrechen zwischen den 2 Stützsstellen 
und auf die andere Spalte anwenden. Hab hier mal ein Beispiel wie ich 
die Werte von einen Temp-Fühler vom ADC auf °C umrechne
int __attribute__ ((progmem)) adc_table [20*2] = {
  -999,  0,
  -350,  64,
  -200,  129,
  -100,  171,
  00,  213,
  150,  273,
  250,  312,
  350,  351,
  450,  389,
  600,  444,
  750,  497,
  900,  549,
  1050,  600,
  1200,  649,
  1500,  743,
  1800,  833,
  2100,  917,
  2300,  972,
  2490,  1021,
  3000,  1023 };

int adc_getTemp(int adc) {
  unsigned char i;
  int x1,x2,t1,t2; 
  for (i = 1; i < 19; i++) {
    if (PRG_RDInt(&adc_table[i*2+1]) >= adc) break;
  }
  x1 = PRG_RDInt(&adc_table[i*2-1]);
  x2 = PRG_RDInt(&adc_table[i*2+1]);
  t1 = PRG_RDInt(&adc_table[i*2-2]);
  t2 = PRG_RDInt(&adc_table[i*2]);
  

  return ((adc-x1) * (t2-t1)) / (x2-x1) + t1;
}

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Jetzt die Frage, gibt es eine Möglichkeit aus den Tabellenwerten eine
>Funktion zu erstellen? Stellt gcc gewisse Funktionen bereit, die einem
>die Korrekturfunktionen erleichtern? Vielleicht über arrays oder
>ähnliches?

GCC ist nur ein C-Compiler. Du brauchst ein Programm zur 
Datenverarbeitung/analyse. Versuchs mal mit Excel, das kann AFAIK 
lineare Regression sowie quadratische Interpolation.

MfG
Falk

Autor: Roland Praml (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich seh grad dass der code noch für ne alte gcc-Version ist.
Besser man verwendet anstatt PRG_RDint pgm_... aber das wirst schon 
selber heraus finden ;-)

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das steuert genau in die Richtung wo ich hin möchte. Es wäre schon eine 
Hilfe, wenn man aus den einfachen Tabellenwerten mit Hilfe eines 
Programms irgendwie eine Mathemantische Funktion erstellen könnte. Die 
dazwischenliegenden Werte würde ausreichen linear zu interpolieren oder 
sonstwie anzunähern. Leider habe ich nichts passendes gefunden.

Ich werde mal versuchen über eine Switch Anweisung das abzudecken, die 
dazwischenliegenden Werte einfach zu berechnen.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
interpolationsformel von Lagrange oder Newton. gibt natürlich noch 
andere verfahren um eine funktion aus stützstellen zu erhalten. ein 
matheprogramm ist da definitiv zu empfehlen, ansonsten kann es passieren 
dass du ewig rechnest.

pumpkin

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Leute!

ich versuche mal den Lösungsansatz von Roland umzusetzen. Danach melde 
ich mich wieder zu Wort.

Autor: Christoph Kessler (db1uq) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OpenOfficeCalc legt immerhin eine Gerade durch die Tabellenwerte, als 
erster Anhaltspunkt welche Kurvenform geeignet wäre. Durch 
Logarithmieren der Tabellenwerte kann man auch Geraden in 
"halblogaritmischen" Diagrammen zeichnen lassen.
"lineare Regression sowie quadratische Interpolation" hab ich in der 
OpenOffice-Hilfefunktion nicht gefunden, aber vielleicht nur die 
falschen Suchbegriffe benutzt.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
edit:

aber um deine zwischenwerte linear zu interpolieren reicht eine kleine 
funktion. etwa so: nehme den nächst kleineren und den nächst größeren. 
größerer - kleinerer = deltaY. dein deltaX (also x beim größeren - x 
beim kleineren) ist vermutlich immer gleich. somit kannst du die 
steigung zwischen den beiden punkten ausrechnen (deltaY/deltaX = dY/dX). 
dann nimmst du dein aktuellen X wert und ziehst das X des kleineren ab 
und multiplizierst das ergebniss mit dem dY/dX. kleineren Y-wert 
hinzuaddiert, fertig.

pseudocode also:

( (( Y[größer] - Y[kleiner] )/( X[größer] - X[kleiner] )) * ( X[aktuell] 
- X[kleiner] ) ) + Y[kleiner]

pumpkin

Autor: Christoph Kessler (db1uq) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gnuplot wird oft empfohlen:
http://gnuplot.sourceforge.net/demo/
"Math functions and curve fitting"

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube mich zu erinnern, dass es da auch was passendes in Matlab 
gab. Hab das Prog aber leider nicht zur Hand.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Das steuert genau in die Richtung wo ich hin möchte. Es wäre schon eine
>> Hilfe, wenn man aus den einfachen Tabellenwerten mit Hilfe eines
>> Programms irgendwie eine Mathemantische Funktion erstellen könnte. Die
>> dazwischenliegenden Werte würde ausreichen linear zu interpolieren oder
>> sonstwie anzunähern. Leider habe ich nichts passendes gefunden.

was willst du eigentlich? eine mathematische funktion? lineare 
interpolation zwischen den werten? wenn du eine stetige funktion willst, 
bekommst du ein polynom x-ten grades, wobei x+1 die anzahl deiner 
stützstellen ist (wie Jörg schon schrieb). das auf einem µC ist zwar 
machbar aber nicht empfehlenswert. soll es denn überhaupt für einen µC 
sein?

pumpkin

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Funktion wäre am genauesten. Aber ich habe ca. 45 Stützstellen, 
diese in ein Polynom zu gießen wäre glaube ich zu aufwendig. Habe von 
der MAthe nicht so die Ahnung, aber müsste man dann nicht vorher ein 
Gleichungssystem mit 44 unbekannten lösen?

Ich habe jetzt eine einfache Funktion gemacht, die auf nem Atmega laufen 
soll. Tabellenwerte vergleichen und dann lineare Interpolation anwenden 
und so den zugehörigen Wert approximieren. Die Genauigkeit ist da 
ausreichend für meine Zwecke.

Eine exakte Funktion mit 44 Polynomen wäre Seitens der Implementation zu 
aufwendig und (für mich) zu schwierig.

Autor: Chef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, Du solltest die Interpolation bereits explizit vorziehen und 
nicht die Stützstellen, sondern die Steigung und den Achsabschnitt 
vorgeben. Dann gibt es weniger zu rechnen.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mister mit Kanister

>Eine Funktion wäre am genauesten. Aber ich habe ca. 45 Stützstellen,
>diese in ein Polynom zu gießen wäre glaube ich zu aufwendig. Habe von

Wieso, das macht das Programm für dich.

>der MAthe nicht so die Ahnung, aber müsste man dann nicht vorher ein
>Gleichungssystem mit 44 unbekannten lösen?

Nur wenn du ein Polynom 44. Grades haben willst. Aber meist tuts eins 
dritten Grades. Aber auch das rechnet dir das richtige Programm 
automatisch aus.

>Ich habe jetzt eine einfache Funktion gemacht, die auf nem Atmega laufen
>soll. Tabellenwerte vergleichen und dann lineare Interpolation anwenden
>und so den zugehörigen Wert approximieren. Die Genauigkeit ist da
>ausreichend für meine Zwecke.

Problem gelöst.

>Eine exakte Funktion mit 44 Polynomen wäre Seitens der Implementation zu
>aufwendig und (für mich) zu schwierig.

Braucht keiner, siehe oben.

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.