Forum: Mikrocontroller und Digitale Elektronik Tabelle Interpolieren


von Bane (Gast)


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

von michael (Gast)


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

von Willi W. (williwacker)


Lesenswert?

Standardbeispiel einer Berechnung über eine Tabelle sind die 
Winkelfunktionen, also sin, cos, ...

Hier würde ich mal nach Beispielen googeln

Ciao

von Bane (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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.
1
Tabelle
2
3
  X-Werte    Y-Werte
4
   20         10
5
   30         50
Jetzt brauchst du zb den Wert für X = 25

Es gilt:
1
  DeltaX
2
 --------   = constant
3
  DeltaY

Also gilt auch
1
   30 - 20      X - 20
2
  ---------  = --------
3
   50 - 10      Y - 10
etwas umformen
1
         ( X - 20 ) * ( 50 - 10 )
2
Y - 10 = -------------------------
3
               30 - 20
4
5
           (X-20) * (50-10)
6
Y =  10 + ------------------
7
              30-20
oder, wenn wir mal die Zahlenwerte durch aussagekräftigere Bezeichnungen
ersetzen:

Begriffe:
1
  X          Wert zu dem der interpolierte Y Wert gesucht wird
2
  Y          gesuchter Wert
3
  X_Kleiner  X-Wert in der Tabelle, der kleiner als X ist
4
  X_Grosser  X-Wert in der Tabelle, der größer als X ist
5
  Y_Kleiner  Y-Wert der zu X_Kleiner gehört und aus der Tabelle kommt
6
  Y_Grosser  Y-Wert der zu X_Grosser gehört und aus der Tabelle kommt
7
8
(Im Beispiel sind:
9
    X           25         (das war ja die Vorgabe)
10
    X_Kleiner   20         (denn 20 ist der Wert in der Tabelle der
11
                            gerade kleiner als X ist)
12
    X_Grosser   30         (denn 30 ist der Wert in der Tabelle der
13
                            gerade grösser als X ist)
14
    Y_Kleiner   10         (der Wert der in der Tabelle bei X_Kleiner
15
                            steht)
16
    Y_Grosser   50         (der Wert der in der Tabelle bei X_Grosser
17
                            steht)
18
19
20
                 ( X - X_Kleiner ) * ( Y_Grosser - Y_Kleiner )
21
 Y = Y_Kleiner + ---------------------------------------------
22
                          ( X_Grosser - X_Kleiner )
Das ist deine Formel.

Setzen wir mal für X = 25 ein:
1
           (25-20) * (50-10)
2
Y =  10 + ------------------
3
              30-20
4
         5 * 40
5
Y = 10 + ------
6
           10
7
8
          200
9
Y = 10 + -----
10
          10
11
12
Y = 10 + 20
13
14
Y = 30
Bei einem X-Wert von 25 lautet also der Interpolierte Y Wert 30

von Bane (Gast)


Lesenswert?

Tolle Erklärung, Danke!!!!!!!

von H. G. (ledi)


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:
1
const unsigned int LUT[16]=  // Festwerte Y für Interpolation
2
{
3
  500, 1000, 1500, 2000, 2500, 3000, 3200, 3250, 3200, 3100, 3000, 2800, 2200, 1500, 800, 0
4
};

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?

von Karl H. (kbuchegg)


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
1
   0     1     2     3     4     5    6   .....
2
3
  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.

von H. G. (ledi)


Lesenswert?

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

Ich setze für X = 20000 >> 12 = 6 ein:
1
        
2
           (6-5) * (3250-3000)
3
Y =  3000 + ------------------
4
                   7-5
5
    
6
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?

von Karl H. (kbuchegg)


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

von Karl H. (kbuchegg)


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:
>
>
1
>            (6-5) * (3250-3000)
2
> Y =  3000 + ------------------
3
>                    7-5
4
> 
5
> Y = 3125
6
>

nicht 6-5 und auch nicht 7-5

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

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

von Karl H. (kbuchegg)


Angehängte Dateien:

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.

von H. G. (ledi)


Lesenswert?

Super erklärt! Danke, das hat mir sehr geholfen!

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.