Mean Meadian Filter implementieren



  • Hallo,

    aus diesem Projekt möchte ich den mean median filter extrahieren und selber nutzen: https://morf.lv/implementing-pulse-oximeter-using-max30100/ der Github Code hierzu: https://github.com/xcoder123/MAX30100

    Die entsprechenden Stellen aus der Header und CPP Datei hab ich herauskopiert und kann diesen im VS kompellieren:

    Header

    #include <Arduino.h>
    #include "SPO2_Filter.h"
    
    
    float MAX30100::meanDiff(float M, meanDiffFilter_t* filterValues)
    
    
    {
      float avg = 0;
    
      filterValues->sum -= filterValues->values[filterValues->index];
      filterValues->values[filterValues->index] = M;
      filterValues->sum += filterValues->values[filterValues->index];
    
      filterValues->index++;
      filterValues->index = filterValues->index % MEAN_FILTER_SIZE;
    
      if(filterValues->count < MEAN_FILTER_SIZE)
        filterValues->count++;
    
      avg = filterValues->sum / filterValues->count;
      return avg - M;
    }
    

    CPP

    
    #include <Arduino.h>
    #include "SPO2_Filter.h"
    
    
    
    // DC removal //
    
    
    float MAX30100::meanDiff(float M, meanDiffFilter_t* filterValues)
    
    
    {
      float avg = 0;
    
      filterValues->sum -= filterValues->values[filterValues->index];
      filterValues->values[filterValues->index] = M;
      filterValues->sum += filterValues->values[filterValues->index];
    
      filterValues->index++;
      filterValues->index = filterValues->index % MEAN_FILTER_SIZE;
    
      if(filterValues->count < MEAN_FILTER_SIZE)
        filterValues->count++;
    
      avg = filterValues->sum / filterValues->count;
      return avg - M;
    }
    

    Wie nutze ich aber nun den Code für meinen Sketch? In meinem Basissketch habe ich einen Sensowert den ich über particlesensor.getIR oder getRed abrufe. Ich muss demnach ein Objekt der Klasse MAX30100 erzeugen und dann die Funktion meanDiff aufrufen? Und mein particlesensor.getIR() ist dann mein filterValues oder? Wie sieht es dann aber mit den anderen Variablen "float M, meanDiffFilter_t*" aus? Das eine ist ja mein Zeiger und das andere einfach eine Variable.

    Also zuerst würde ich wie gesagt ein Objekt erzeugen:

    MAX30100 meinObjekt;

    Dann würde ich die Funktion aufrufen:

    meinObjekt.meanDiff(float M, meanDiffFilter_t* filterValues);

    den filter Values würde ich nun mit particleSensor.getRed() definieren:

    particleSensor.meanDiff(float M, meanDiffFilter_t* particleSensor.getRed());

    Was mache ich mit particleSensor.getRed() ? Oder ist das Blödsinn und ich muss eine Funktion "setfilterValues" erzeugen (in der CPP) und dann setze ich den filterValues in der ino auf getRed?

    Kennt sich da jemand aus?

    Hier hab ich noch folgende Zeile gefunden:

      float meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
    
    

    Da wird mEn die Funktion meanDiff aufgerufen und einmal der Filterwert gesetzt (der zuvor durch den DC Folter ging) und der &meanDiffIR ist ein Zeiger?



  • Ich hätte mir das so igw vorgestellt:

    
    #include <Arduino.h>
    #include "SPO2_Filter.h"
    
    
    
    // DC removal //
    
    
    float MAX30100::meanDiff(float M, meanDiffFilter_t* filterValues)
    
    
    
    {
      float avg = 0;
    
      filterValues->sum -= filterValues->values[filterValues->index];
      filterValues->values[filterValues->index] = M;
      filterValues->sum += filterValues->values[filterValues->index];
    
      filterValues->index++;
      filterValues->index = filterValues->index % MEAN_FILTER_SIZE;
    
      if(filterValues->count < MEAN_FILTER_SIZE)
        filterValues->count++;
    
      avg = filterValues->sum / filterValues->count;
      return avg - M;
    }
    
    
    void MAX30100::setfilterValues(uint16_t sw)
    
    {
    
     filterValues = sw; 
    
    }
    
    
    
    #ifndef SPO2_Filter_H
    #define SPO2_Filter_H
    
    #include <Arduino.h>
    #include <Wire.h>
    #include <math.h>
    
    
    #define MEAN_FILTER_SIZE        15  
    
    
    struct meanDiffFilter_t
    {
      float values[MEAN_FILTER_SIZE];
      byte index;
      float sum;
      byte count;
    };
    
    
    
    class MAX30100 
    {
      public:
      float meanDiff(float M, meanDiffFilter_t* filterValues);
    
      float filterValues; 
    
      void setfilterValues(uint16_t filterValues);
    
    
    private:
      meanDiffFilter_t meanDiffIR;
    
    
    };
    
    
    
    #endif
    
    
    /*!
     * @file basicRead.ino
     * @brief Output readings of red light and IR 
     * @n This library supports mainboards: ESP8266, FireBeetle-M0, UNO, ESP32, Leonardo, Mega2560
     * @copyright  Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
     * @licence     The MIT License (MIT)
     * @author [YeHangYu](hangyu.ye@dfrobot.com)
     * @version  V0.1
     * @date  2020-05-29
     * @url https://github.com/DFRobot/DFRobot_MAX30102
     */
    
    #include "DFRobot_MAX30102.h"
    #include "SPO2_Filter.h"
    
    DFRobot_MAX30102 particleSensor;
    
    MAX30100 erstesObjekt;
    
    
    /*
    Macro definition opions in sensor configuration 
    sampleAverage: SAMPLEAVG_1 SAMPLEAVG_2 SAMPLEAVG_4 
                   SAMPLEAVG_8 SAMPLEAVG_16 SAMPLEAVG_32
    ledMode:       MODE_REDONLY  MODE_RED_IR  MODE_MULTILED
    sampleRate:    PULSEWIDTH_69 PULSEWIDTH_118 PULSEWIDTH_215 PULSEWIDTH_411
    pulseWidth:    SAMPLERATE_50 SAMPLERATE_100 SAMPLERATE_200 SAMPLERATE_400
                   SAMPLERATE_800 SAMPLERATE_1000 SAMPLERATE_1600 SAMPLERATE_3200
    adcRange:      ADCRANGE_2048 ADCRANGE_4096 ADCRANGE_8192 ADCRANGE_16384
    */
    void setup()
    {
      //Init serial 
      Serial.begin(115200);
      /*!
       *@brief Init sensor 
       *@param pWire IIC bus pointer object and construction device, can both pass or not pass parameters (Wire in default)
       *@param i2cAddr Chip IIC address (0x57 in default)
       *@return true or false
       */
      while (!particleSensor.begin()) {
        Serial.println("MAX30102 was not found");
        delay(1000);
      }
    
      /*!
       *@brief Use macro definition to configure sensor
       *@param ledBrightness LED brightness, default value: 0x1F(6.4mA), Range: 0~255(0=Off, 255=50mA)
       *@param sampleAverage Average multiple samples then draw once, reduce data throughput, default 4 samples average
       *@param ledMode LED mode, default to use red light and IR at the same time 
       *@param sampleRate Sampling rate, default 400 samples every second 
       *@param pulseWidth Pulse width: the longer the pulse width, the wider the detection range. Default to be Max range
       *@param adcRange Measurement Range, default 4096 (nA), 15.63(pA) per LSB
       */
      particleSensor.sensorConfiguration(/*ledBrightness=*/0x1F, /*sampleAverage=*/SAMPLEAVG_4, \
                                      /*ledMode=*/MODE_MULTILED, /*sampleRate=*/SAMPLERATE_400, \
                                      /*pulseWidth=*/PULSEWIDTH_411, /*adcRange=*/ADCRANGE_4096);
    }
    
    void loop()
    {
      //Print result
      Serial.print("R=");
      /*!
       *@brief Get red value
       *@return Red light reading 
       */
    
    
      Serial.print(particleSensor.getIR());
      Serial.println();
      delay(100);
    
       //erstesObjekt.meanDiff(float , meanDiffFilter_t* particleSensor.getIR());
    
    
    
    erstesObjekt.setfilterValues(particleSensor.getRed());
    
     Serial.print(erstesObjekt.meanDiff());
    
    
    
    
    }
    
    

    Jetzt habe ich aber noch einen Error beim serial print meines Wertes: " Serial.print(erstesObjekt.meanDiff());"

    too few arguments in function callC/C++(165)
    
    

    Das erkläre ich mir durch die Parameter die ich hier nicht definiert habe:

    "float MAX30100::meanDiff(float M, meanDiffFilter_t* filterValues)"

    Die müsste ich nun aus der () rausnehmen und darunter definieren, dann müsste das klappen, oder?


Anmelden zum Antworten