mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tabelle Interpolieren


Autor: Bane (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich benötige für bestimmte Berechnungen Werte aus einem Diagramm.
Diese würde ich nun gerne über ein Tabelle interpolieren.
Nur hab ich weder von Tabellen noch vom interpolieren eine Ahnung.
Kann mir da jemand weiterhelfen?
Das Programm läuft auf einem C166, und es werden keine 
Fließkommaoperationen unterstützt.


mfG
Bane

Autor: michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo.

im einfachsten fall hinterlegst du deine tabelle als zweidimensionales 
array und behandelst die zwischenwerte als geradenabschnitte.
um die genauigkeit zu erhöhen, kannst du die werte vor einer eventuellen 
division mit einem großen wert multiplizieren (bzw. linksschieben). 
bevor du das endergebnis ablegst, schiebst du den wert wieder nach 
rechts.

alles andere (z.b. spline-berechnung) dürfte auf einem C166 etwas 
schwierig werden, wenn der auch noch was anderes zu tun hat.

gruß

michael

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Standardbeispiel einer Berechnung über eine Tabelle sind die 
Winkelfunktionen, also sin, cos, ...

Hier würde ich mal nach Beispielen googeln

Ciao

Autor: Bane (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir jemand einen link oder ein Beispiel geben, wie das in C zu 
realisieren ist?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Bane wrote:
> Kann mir jemand einen link oder ein Beispiel geben, wie das in C zu
> realisieren ist?

Das Stichwort dazu lautet: "Lineare Interpolation".

Als Tabelle nimmst du ein Array. Je nachdem wie die Werte konkret
aussehen, ist das dann entweder ein 1-dimensionales oder ein
2-dimensionales Array.
Tabelle

  X-Werte    Y-Werte
   20         10
   30         50
Jetzt brauchst du zb den Wert für X = 25

Es gilt:
  DeltaX
 --------   = constant
  DeltaY

Also gilt auch
   30 - 20      X - 20
  ---------  = --------
   50 - 10      Y - 10
etwas umformen
         ( X - 20 ) * ( 50 - 10 )
Y - 10 = -------------------------
               30 - 20

           (X-20) * (50-10)
Y =  10 + ------------------
              30-20
oder, wenn wir mal die Zahlenwerte durch aussagekräftigere Bezeichnungen
ersetzen:

Begriffe:
  X          Wert zu dem der interpolierte Y Wert gesucht wird
  Y          gesuchter Wert
  X_Kleiner  X-Wert in der Tabelle, der kleiner als X ist
  X_Grosser  X-Wert in der Tabelle, der größer als X ist
  Y_Kleiner  Y-Wert der zu X_Kleiner gehört und aus der Tabelle kommt
  Y_Grosser  Y-Wert der zu X_Grosser gehört und aus der Tabelle kommt

(Im Beispiel sind:
    X           25         (das war ja die Vorgabe)
    X_Kleiner   20         (denn 20 ist der Wert in der Tabelle der
                            gerade kleiner als X ist)
    X_Grosser   30         (denn 30 ist der Wert in der Tabelle der
                            gerade grösser als X ist)
    Y_Kleiner   10         (der Wert der in der Tabelle bei X_Kleiner
                            steht)
    Y_Grosser   50         (der Wert der in der Tabelle bei X_Grosser
                            steht)


                 ( X - X_Kleiner ) * ( Y_Grosser - Y_Kleiner )
 Y = Y_Kleiner + ---------------------------------------------
                          ( X_Grosser - X_Kleiner )
Das ist deine Formel.

Setzen wir mal für X = 25 ein:
           (25-20) * (50-10)
Y =  10 + ------------------
              30-20
         5 * 40
Y = 10 + ------
           10

          200
Y = 10 + -----
          10

Y = 10 + 20

Y = 30
Bei einem X-Wert von 25 lautet also der Interpolierte Y Wert 30

Autor: Bane (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tolle Erklärung, Danke!!!!!!!

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich eine Tabelle mit 16 Werten interpolieren, wenn ich für x 
einen 16bit Wert (Dimmwert 0...65535) habe?

Hier meine Wertetabelle:
const unsigned int LUT[16]=  // Festwerte Y für Interpolation
{
  500, 1000, 1500, 2000, 2500, 3000, 3200, 3250, 3200, 3100, 3000, 2800, 2200, 1500, 800, 0
};

Meine Überlegung:
1.) 16bit Dimmwert auf einen 4bit Wert runter brechen

-> dimm_value_4 = dimm_value >> 12

Jetzt habe ich für 16 Y-Werte auch 16 X-Werte.
Wie aber kann ich nun den interpolierten Y-Wert für den Dimmwert von 
z.B. 20000 berechnen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
H. G. schrieb:

> 1.) 16bit Dimmwert auf einen 4bit Wert runter brechen
>
> -> dimm_value_4 = dimm_value >> 12

das ist gleichbedeutend mit einer Division durch 4096

> Jetzt habe ich für 16 Y-Werte auch 16 X-Werte.

passt.

> Wie aber kann ich nun den interpolierten Y-Wert für den Dimmwert von
> z.B. 20000 berechnen?

Welchen Teil meiner Ausführungen von 2007 hast du nicht verstanden?


20000 / 4096 = 4

du brauchst also von deiner Tabelle die Einträge 4 und 5
   0     1     2     3     4     5    6   .....

  500, 1000, 1500, 2000, 2500, 3000, 3200, 3250, 3200, 3100, 3000, 2800, ... 

also 2500 und 3000. Zwischen diesen beiden Werten muss dein gesuchter 
Wert liegen. Aber wo genau? Welcher X Wert wäre denn genau bei 4?
  4 * 4096 = 16384
Und bei 5?
  5 * 4096 = 20480

wenn also bei einem X-Wert von 16384 der zugehörige Y Wert 2500 ausmacht 
und bei einem X-Wert von 20480 der zugehörige Y Wert 3000 ausmacht, wie 
gross ist dann der Y-Wert, wenn dein X zahlenmässig 20000 ausmacht?
Und jetzt gehst du zurück zu den Ausführungen von 2007. Denn genau an 
diesem Punkt setzen die ein.

einfach mal ein bischen aufmalen, was es eigentlich zu rechnen gibt, in 
Form eines Diagramms. Dann wird alles plötzlich ganz einfach. Ja, ich 
weiß. In Zeiten von iPad und Konsorten ist es uncool  mal Papier und 
Belistift zur Hand zu nehmen und sich einen Überblick zu verschaffen, 
was man eigentlich machen will bzw. muss.

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, ich möchte den Y-Wert für meinen Dimmwert 20000 berechnen:

Ich setze für X = 20000 >> 12 = 6 ein:
        
           (6-5) * (3250-3000)
Y =  3000 + ------------------
                   7-5
    
Y = 3125

Bei einem X-Wert von 20000 lautet also der Interpolierte Y Wert 3125 ?

Bei einem X-Wert von 21000 würde ich das selbe Ergebnis erhalten, da 
21000 >> 12 auch 6 ist.

Ist das so richtig?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
H. G. schrieb:
> OK, ich möchte den Y-Wert für meinen Dimmwert 20000 berechnen:
>
> Ich setze für X = 20000 >> 12 = 6 ein:

Wie kommst du auf 6?

20000 / 4096 = 4

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
H. G. schrieb:
> OK, ich möchte den Y-Wert für meinen Dimmwert 20000 berechnen:
>
> Ich setze für X = 20000 >> 12 = 6 ein:
>
>
>            (6-5) * (3250-3000)
> Y =  3000 + ------------------
>                    7-5
> 
> Y = 3125
> 

nicht 6-5 und auch nicht 7-5

das korrekte Ergebnis der Division war 4
4 * 4096 -> 16384
5 * 4096 -> 20480
                 ( X - X_Kleiner ) * ( Y_Grosser - Y_Kleiner )
 Y = Y_Kleiner + ---------------------------------------------
                          ( X_Grosser - X_Kleiner )

ergo
            (20000 - 16384 ) * ( 3000 - 2500 )
y = 2500 + -----------------------------------
                 ( 20480 - 16384 )

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sieh dir mal die Zeichnung an.

Durch die Division hast du ermittelt, welcher Bereich deiner Daten 
überhaupt zuständig ist.
Und in die umgekehrte Richtung kannst du dir aus dieser Bereichsnummer 
wiederrum errechnen, welches die untere Grenze bzw. die obere Grenze für 
diesen Bereich ist. (in X, in Y kriegst du die Werte aus der Tabelle).

Hast du erst mal den Bereich identifiziert, dann lautet die 
Fragestellung: Gehe ich mit meinem Messwert, auf genau diese für diesen 
Bereich zuständige Gerade, wo treffe ich dort diese Gerade und welches 
ist dann der Wert, den ich dazu auf der Y-Achse ablese?
Und der Rest ist einfach nur ein bischen Dreiecksrechnen bzw. 
Strahlensatz. Die komplette Differenz in Y (violett markiert) verhält 
sich zur kompletten Differenz in X (ebenfalls violett markiert), so wie 
der orange Abstand in Y Richtung (vom Beginn des Bereichs an gerechnet) 
zum orangen Abstand in X Richtung (ebenfalls vom Beginn des Bereichs an 
gerechnet).

Das alles solltest du problemlos in der Formel wiederfinden.

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super erklärt! Danke, das hat mir sehr geholfen!

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.