Filter über Struct und Zeiger in Sketch



  • Hallo,

    ich möchte den Filter (die Filter) aus diesem Tutorial in meinen ESP Sketch integrieren: https://morf.lv/implementing-pulse-oximeter-using-max30100/

    Zunächst geht es um den: butterworthFilter_t

    Hier der Code aus dem Tutorial:

    struct butterworthFilter_t
    {
      float v[2];
      float result;
    };
    void MAX30100::lowPassButterworthFilter( float x, butterworthFilter_t * filterResult )
    {  
      filterResult->v[0] = filterResult->v[1];
    
      //Fs = 100Hz and Fc = 10Hz
      filterResult->v[1] = (2.452372752527856026e-1 * x) + (0.50952544949442879485 * filterResult->v[0]);
    
      //Fs = 100Hz and Fc = 4Hz
      //filterResult->v[1] = (1.367287359973195227e-1 * x) + (0.72654252800536101020 * filterResult->v[0]); //Very precise butterworth filter 
    
      filterResult->result = filterResult->v[0] + filterResult->v[1];
    }
    

    Die ganze Libary plus Beispiel gibt es auf Github:

    https://github.com/xcoder123/MAX30100

    Jetzt zu meiner Frage:

    Ich habe hier eine structur butterworthFilter_t, darin habe ich nun result als Variable und als Array v[2] vom Typ float (da der Index bei 0 anfängt sind es also v[0] und v[1]).

    Weiters ist "void MAX30100::lowPassButterworthFilter( float x, butterworthFilter_t * filterResult )" dies meine Funktion in der ich die Variable float x lade, sowie meine structur butterworthFilter_t bei der nun der Zeiger * filterResult zugeordnet wird und in meiner Libary (.cpp/ oder .h?) müsste noch der Zeiger filterResult definiert sein, oder? Oder ist filterResult eine structur? (Das meinte jemand, aber mit -> zeige ich ja auf v[0], [1] oder result, ein Zeiger kann ja keine structur sein, oder? Ich finde weder eine structur noch einen definierten Zeiger, der müsste ja in etwa so aussehen? > filterResult = (int) malloc(sizeof(int));) und nun könnte ich die Daten über filterResult (irgend eine Adresse); &filterResult (Adresse des Zeigers) oder *filterResult der Wert auf dem dieser zeigt, abrufen, richtig?)

    Würde mich sehr freuen, wenn mir da wer weiterhelfen kann (hab erst heute angefangen mich mit Zeiger und Strukturen zu befassen, so ganz habe ich es noch nicht durchblickt).

    LG

    PS: Hier ist noch restlicher Code den ich rausgesucht habe:

    ".h

    class MAX30100 
    {
      public:
        MAX30100( Mode mode = DEFAULT_OPERATING_MODE, 
                  SamplingRate samplingRate = DEFAULT_SAMPLING_RATE, 
                  LEDPulseWidth pulseWidth = DEFAULT_LED_PULSE_WIDTH, 
                  LEDCurrent IrLedCurrent = DEFAULT_IR_LED_CURRENT,
                  bool highResMode = true,
                  bool debug = false 
                 );
    
    
    void lowPassButterworthFilter( float x, butterworthFilter_t * filterResult );
    
      private:
    
        butterworthFilter_t lpbFilterIR;
    
    
    };
    
    
    
    struct butterworthFilter_t
    {
      float v[2];
      float result;
    };
    

    .cpp

    lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &lpbFilterIR );
      
    
    float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
    
    
    
    
    
    lpbFilterIR.v[0] = 0;
    lpbFilterIR.v[1] = 0;
    lpbFilterIR.result = 0;"
    

    MFG



  • @Arduinofrage Vielleicht wird es klarer, wenn du den * an den Variablennamen bindest:

    void MAX30100::lowPassButterworthFilter(float x, butterworthFilter_t *filterResult)

    Da ist schon mal der Zeiger.

    Beim Aufruf der Funktion (Zeile 1 .cpp) ist an der Stelle &lpbFilterIR
    Also mit Adressoperator.

    lpbFilterIR ist in Zeile 17 der .h als struct definiert.



  • @DirkB sagte in Filter über Struct und Zeiger in Sketch:

    @Arduinofrage Vielleicht wird es klarer, wenn du den * an den Variablennamen bindest:

    void MAX30100::lowPassButterworthFilter(float x, butterworthFilter_t *filterResult)

    Da ist schon mal der Zeiger.

    Beim Aufruf der Funktion (Zeile 1 .cpp) ist an der Stelle &lpbFilterIR
    Also mit Adressoperator.

    lpbFilterIR ist in Zeile 17 der .h als struct definiert.

    Danke, das mit dem Zeiger * ist nun klar. Aber beim lowPassButterworthFilter und dem &lpbFilterIR bin ich mich noch nicht sicher. Was genau macht &lpbFilterIR ?

    Hier ist noch weiterer Code dazu:

     fifo_t rawData = readFIFO();  
      
      dcFilterIR = dcRemoval( (float)rawData.rawIR, dcFilterIR.w, ALPHA );
      dcFilterRed = dcRemoval( (float)rawData.rawRed, dcFilterRed.w, ALPHA );
    
      float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
      lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &lpbFilterIR );
    
      irACValueSqSum += dcFilterIR.result * dcFilterIR.result;
      redACValueSqSum += dcFilterRed.result * dcFilterRed.result;
      samplesRecorded++;
    


  • @Arduinofrage sagte in Filter über Struct und Zeiger in Sketch:

    Was genau macht &lpbFilterIR ?

    Schau mal bitte nach wo lpbFilterIR definiert ist. Das sieht etwas merkwürdig aus, da der Präfix lp auf einen Pointer hinweist.

    Eigentlich hätte ich folgendes erwartet:

    float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
    butterworthFilter_t FilterIR;
    
    lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &FilterIR );
    


  • @Quiche-Lorraine sagte in Filter über Struct und Zeiger in Sketch:

    @Arduinofrage sagte in Filter über Struct und Zeiger in Sketch:

    Was genau macht &lpbFilterIR ?

    Schau mal bitte nach wo lpbFilterIR definiert ist. Das sieht etwas merkwürdig aus, da der Präfix lp auf einen Pointer hinweist.

    Eigentlich hätte ich folgendes erwartet:

    float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
    butterworthFilter_t FilterIR;
    
    lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &FilterIR );
    

    Finde ich ehrlich gesagt leider nicht? Hier wäre der Code: https://github.com/xcoder123/MAX30100/blob/master/MAX30100.cpp



  • @Arduinofrage sagte in Filter über Struct und Zeiger in Sketch:

    lpbFilterIR

    Ich habe diesen in der Klassendefinition von MAX30100 gefunden. Sieht ok aus, das Präfix des Namens ist aber definitiv verwirrend. Da steht nämlich lpbFilterIR und das könnte man als long pointer to bool verstehen.

    Egal die Definition stimmt, denn da steht:

    butterworthFilter_t lpbFilterIR;
    

    Wenn du die Funktion lowPassButterworthFilter mit dem Parameter &lpbFilterIR aufrufst, so übergibt du der Funktion die Addresse deiner butterworthFilter_t Instanz. Die Funktion berechnet dann die Filter-Funktion und schreibt diese Ergebnisse an die von dir angegebene Adresse.



  • @Arduinofrage sagte in Filter über Struct und Zeiger in Sketch:

    Finde ich ehrlich gesagt leider nicht?

    Kleiner Tipp für die nächsten Male und um unnötige Fragen zu vermeiden: GitHub hat auch eine Suchfunktion und kann jetzt auch Referenzen zur Definitionsstelle folgen.



  • Im Prinzip kann ich mir die Codes ja wie folgt in eine eigene .h und cpp kopieren, richtig?

    Header Datei

    class Filter 
    {
      public:
    
      Filter( ); //// der Default-Konstruktor
    
    void lowPassButterworthFilter( float x, butterworthFilter_t * filterResult ); //Funktion mit Parametern
    
      private:
    
        butterworthFilter_t lpbFilterIR;
    
    };
    
    struct butterworthFilter_t // Struktur mit 2 Variablen
    {
      float v[2];
      float result;
    };
    

    .cpp

    lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &lpbFilterIR );
      
    float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
    
    lpbFilterIR.v[0] = 0;
    lpbFilterIR.v[1] = 0;
    lpbFilterIR.result = 0;"
    

    Filter ist nun meine Klasse. Eine Klasse wird in der Header deklariert und in der .cpp implementiert und sie besteht aus:

    Konstruktoren, Destruktoren, Memberfunktionen und Membervariablen

    lowPassButterworthFilter ist eine Funktion der Klasse Filter, float x, butterworthfilter_t und *filterResult sind Parameter der Funktion lowPassButterworthFilter. Filter (); ist nun mein Default-Konstruktor.

    butterworthFilter_t ist eine Struktur mit den Variablen float v[2]; float result;

    stimmt das nun soweit? Ich hoffe mal, jetzt bin ich mir bei " butterworthFilter_t lpbFilterIR;" aber immer noch nicht sicher. Ist das nun auch ein Konstruktor?

    In meinem Sketch muss ich nun auf X mein Signal legen ( x = Signal) und zuvor die Funktion aufrufen mit
    :

    void Filter::lowPassButterworthFilter( float x, butterworthFilter_t * filterResult )
    {  
      filterResult->v[0] = filterResult->v[1];
    
      //Fs = 100Hz and Fc = 10Hz
      filterResult->v[1] = (2.452372752527856026e-1 * x) + (0.50952544949442879485 * filterResult->v[0]);
    
      filterResult->result = filterResult->v[0] + filterResult->v[1];
    }
    

    Geht das in die richtige Richtung?



  • @Arduinofrage sagte in Filter über Struct und Zeiger in Sketch:

    Im Prinzip kann ich mir die Codes ja wie folgt in eine eigene .h und cpp kopieren, richtig?

    Für deinen speziellen Fall, in welchem deine Lib aus nur einem Dateipaar (.cpp/.h) besteht, würde ich die Dateien einfach in dein Projektverzeichnis kopieren und nutzen.

    Geht das in die richtige Richtung?

    Ich vermute mal ja. Du solltest aber etwas vorsichtig sein und es testen. Hierzu empfehle ich dir eine Datenreihe aufzunehmen, die Daten durch den Filter zu jagen und beide Datenreihen zu visualisieren. Du könntest z.B. die Datenreihen in eine GnuPlot Datei schreiben.


Anmelden zum Antworten