pow Funktion ohne math.h auf Mikrocontroller in C umsetzen?



  • Wie gesagt, lineare Interpolation. Du müsstest die beiden nächstgelegenen Stützstellen finden, in dem Fall 800 und 900, und dann den gewichteten Mittelwert bilden. Bei 850 wäre das einfach (126,452 + 171,453)/2. Bei 840 wäre es 0,6*126,452 + 0,4*171,453.

    Wenn deine Stützstellen unregelmäßig angeordnet sind wie in deinem Beispiel, musst du erstmal irgendwie suchen, was die beiden nächstgelegenen Stellen sind, per binärer Suche zum Beispiel. Wenn sie äquidistant liegen, kannst du die Indizes auch einfach ausrechnen.



  • Danke für die Tips, hier scheint jetzt wieder das Problem zu sein, dass ich nicht so große Felder für sagen wir mal mit 100 Werten anlegen kann.
    Mein Code ist folgender:

    int get_value(int x)
    {
    /* NOTE: xs MUST be sorted */
    static const int xs[] = {0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600, 3800, 4000, 4200, 4400, 4600, 4800, 5000, 5200, 5400, 5600, 5800, 6000, 6200, 6400, 6600, 6800, 7000, 7200, 7400, 7600, 7800, 8000, 8200, 8400, 8600, 8800, 9000, 9200, 9400, 9600, 9800, 10000};
        static const int ys[] = {18, 18, 18, 19, 20, 21, 22, 24, 27, 30, 33, 38, 42, 48, 54, 60, 68, 76, 85, 95, 105, 116, 128, 141, 155, 170, 185, 202, 219, 237, 257, 277, 298, 321, 344, 369, 394, 421, 448, 477, 507, 538, 570, 603, 638, 674, 710, 749, 788, 828, 870};
    
        /* number of elements in the array */
        static const int count = sizeof(xs)/sizeof(xs[0]);
    
        int i;
        int dx, dy;
    
        if (x < xs[0]) {
            /* x is less than the minimum element
             * handle error here if you want */
            return ys[0]; /* return minimum element */
        }
    
        if (x > xs[count-1]) {
            return ys[count-1]; /* return maximum */
        }
    
        /* find i, such that xs[i] <= x < xs[i+1] */
        for (i = 0; i < count-1; i++) {
            if (xs[i+1] > x) {
                break;
            }
        }
    
        /* interpolate */
        dx = xs[i+1] - xs[i];
        dy = ys[i+1] - ys[i];
        return ys[i] + (x - xs[i]) * dy / dx;
    }
    

    Sobald ich die Felder mit mehr als 4 Werten fülle, kommt folgender Fehler:

    ?ASlink-Error-Could not get 534 consecutive bytes in internal RAM for area DSEG. at 1: warning 119: don't know what to do with file ' '. file extension unsupported make: *** [test.hex] Error 1 make: Target `all' not remade because of errors.

    Also ist scheinbar zuwenig zusammenhängender Speicher vorhanden. Wenn ich die beiden Felder aus der Funktion heraus verschiebe scheint es zu funktionieren. Allerdings scheint am Code etwas falsch zu sein, da jetzt immer ein gleicher Wert ausgegeben wird und nie ein der Spannung entsprechender.



  • "mit mehr als 4 Werten" heißt nichtmal

    static const int xs[] = {1, 2, 3, 4, 5};
    

    würde funktionieren? Das wären ja je nach Wortgröße gerade mal 20 oder 40 Bytes für xs und ys, hast du soviel nicht frei?



  • Naja ich glaube eher das er die daten im r/w bereich ablegt wenns in der funktion ist, anstatt im read-only bereich.
    Wenn ich die beiden xs und ys außerhalb der Funktion anlege, geht es. Aber irgendwas scheint mit der Lookup Tabelle selbst noch nicht zu funktionieren. Kannst du da einen Fehler entdecken?
    Vielen Dank schonmal für deine bisherige Hilfe Bashar und an die anderen.



  • Was stimmt denn nicht? Der Code sieht eigentlich OK aus.

    Naja ich glaube eher das er die daten im r/w bereich ablegt wenns in der funktion ist, anstatt im read-only bereich.

    Komischer Compiler, ich seh gar keinen Grund, bei static const zwischen globalen und funktionslokalen Variablen zu unterscheiden, aber gut zu wissen.



  • Das Problem ist, das diese Funktion aus irgendeinen Grund nicht zu funktionieren scheint. Lasse ich die Funktion weg, werden mir meine Werte in gewohnter Art augegeben. Sobald ich diese Werte der Funktion (siehe oben) übergebe, kommt egal welcher Druck anliegt immer ein konstanter Wert Wert raus.



  • Und welcher? Und was heißt "in gewohnter Art"? Das ist ein bisschen dürftig als Problembeschreibung ...



  • Sorry, mit gewohnter Art meine ich das eben Werte von wie 0, 1600 usw. ausgegeben werden. Also quasi die Werte von xs. Da mein Sensor aber keine konstante Kennlinie aufweist müssten diese Werte eigentlich mit einer Formel (die dann durch lookup Tabelle ersetzt wurde abgelöst wurde) umgerechnet und dann diese Werte ausgegeben werden.



  • Es läuft, danke ich hab den Fehler gefunden. Vielen Dank an alle Antworten von euch. 🙂



  • Könntest du auch schreiben was der Fehler (Lösung) war?
    Damit Andere mit dem selben fehler hier dann auch die Lösung finden.



  • Also den Code den ich hier gepostet habe, der funktioniert einwandfrei. Der Fehler lag in einer anderen Datei die mit dem hier besprochenen Problem nichts zu tun hatte.


Anmelden zum Antworten