Interrupt

Dependencies:   BLE_API BLE_Driver I2C_Driver MAX30100 PROCESAMIENTO_DATOS_SP02 mbed nRF51822 millis

Fork of MAX30100_FirstTry by TESIS SATUROMETRICA

Files at this revision

API Documentation at this revision

Comitter:
Ferszt
Date:
Tue May 30 01:00:34 2017 +0000
Parent:
4:cd1706e84a57
Commit message:
Ultima prueba

Changed in this revision

PROCESAMIENTO_DATOS_SP02.lib Show annotated file Show diff for this revision Revisions of this file
mainbletest.cpp Show annotated file Show diff for this revision Revisions of this file
millis.lib Show annotated file Show diff for this revision Revisions of this file
--- a/PROCESAMIENTO_DATOS_SP02.lib	Tue Mar 28 23:17:44 2017 +0000
+++ b/PROCESAMIENTO_DATOS_SP02.lib	Tue May 30 01:00:34 2017 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/teams/TESIS-SATUROMETRICA/code/PROCESAMIENTO_DATOS_SP02/#7e5b24227d0a
+http://developer.mbed.org/teams/TESIS-SATUROMETRICA/code/PROCESAMIENTO_DATOS_SP02/#ce356ed18c86
--- a/mainbletest.cpp	Tue Mar 28 23:17:44 2017 +0000
+++ b/mainbletest.cpp	Tue May 30 01:00:34 2017 +0000
@@ -4,6 +4,7 @@
 #include "MAX30100.h"
 #include "I2C_Driver.h"
 #include "PROCESAMIENTO_SPO2_FC.h"
+#include "millis.h"
 
 #define nRF51DK
 //#define nRF52DK
@@ -32,7 +33,48 @@
 char show[10];
 
 //******************
+#define PULSE_MIN_THRESHOLD         100 //300 is good for finger, but for wrist you need like 20, and there is shitloads of noise
+#define PULSE_MAX_THRESHOLD         2000
+#define PULSE_GO_DOWN_THRESHOLD     1
 
+#define PULSE_BPM_SAMPLE_SIZE       10 //Moving average size
+struct dcFilter_t {
+  float w;
+  float result;
+};
+
+struct meanDiffFilter_t
+{
+  float values[15];
+  uint8_t index;
+  float sum;
+  uint8_t count;
+};
+
+struct butterworthFilter_t
+{
+  float v[2];
+  float result;
+};
+
+typedef enum PulseStateMachine {
+    PULSE_IDLE,
+    PULSE_TRACE_UP,
+    PULSE_TRACE_DOWN
+} PulseStateMachine;
+
+dcFilter_t dcFilterIR;
+meanDiffFilter_t meanDiffIR;
+butterworthFilter_t lpbFilterIR;
+float prev_w = 0;
+uint32_t lastBeatThreshold;
+uint8_t currentPulseDetectorState;
+float currentBPM;
+float valuesBPM[PULSE_BPM_SAMPLE_SIZE];
+float valuesBPMSum;
+uint8_t valuesBPMCount;
+uint8_t bpmIndex;
+//**************************
 InterruptIn SMPRDY(p0);
 DigitalOut LIVE_LED(p21, 1);
 DigitalOut CONECT_LED(p22, 1);
@@ -65,11 +107,11 @@
         putBLE("\n");
         }
     else{
-        muestras_RED[samples_index] = sensor.RED;
-        muestras_IR[samples_index] = sensor.IR;
-        sprintf(show, "%d", muestras_IR[samples_index]);
-        putBLE(show);
-        putBLE("\n");
+        //muestras_RED[samples_index] = sensor.RED;
+        muestras_IR[samples_index] = lpbFilterIR.result;
+        //sprintf(show, "%d", muestras_IR[samples_index]);
+        //putBLE(show);
+        //putBLE("\n");
         samples_index++;
         }
 }
@@ -81,15 +123,203 @@
     putBLE(show);
     putBLE("\n");
     }
+
+/***************************************************************************/
+    
+dcFilter_t DCfilter(float x, float prev, float alpha)
+{
+    dcFilter_t filtered;
+    filtered.w = x + alpha * prev;
+    filtered.result = filtered.w - prev;
+    prev_w = filtered.w;
+    return filtered;
+}
+
+float 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 % 15;
+
+  if(filterValues->count < 15)
+    filterValues->count++;
+
+  avg = filterValues->sum / filterValues->count;
+  return avg - M;
+}
+
+void 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];
+}
+
+bool detectPulse(float sensor_value)
+{
+  static float prev_sensor_value = 0;
+  static uint8_t values_went_down = 0;
+  static uint32_t currentBeat = 0;
+  static uint32_t lastBeat = 0;
+
+  if(sensor_value > PULSE_MAX_THRESHOLD)
+  {
+    currentPulseDetectorState = PULSE_IDLE;
+    prev_sensor_value = 0;
+    lastBeat = 0;
+    currentBeat = 0;
+    values_went_down = 0;
+    lastBeatThreshold = 0;
+    return false;
+  }
+
+  switch(currentPulseDetectorState)
+  {
+    case PULSE_IDLE:
+      if(sensor_value >= PULSE_MIN_THRESHOLD) {
+        currentPulseDetectorState = PULSE_TRACE_UP;
+        values_went_down = 0;
+      }
+      break;
+
+    case PULSE_TRACE_UP:
+      if(sensor_value > prev_sensor_value)
+      {
+        currentBeat = millis();
+        lastBeatThreshold = sensor_value;
+      }
+      else
+      {
+
+        uint32_t beatDuration = currentBeat - lastBeat;
+        lastBeat = currentBeat;
+
+        float rawBPM = 0;
+        if(beatDuration > 0)
+          rawBPM = 60000.0 / (float)beatDuration;
+//        if(debug == true) 
+//          Serial.println(rawBPM);
+
+        //This method sometimes glitches, it's better to go through whole moving average everytime
+        //IT's a neat idea to optimize the amount of work for moving avg. but while placing, removing finger it can screw up
+        //valuesBPMSum -= valuesBPM[bpmIndex];
+        //valuesBPM[bpmIndex] = rawBPM;
+        //valuesBPMSum += valuesBPM[bpmIndex];
+
+        valuesBPM[bpmIndex] = rawBPM;
+        valuesBPMSum = 0;
+        for(int i=0; i<PULSE_BPM_SAMPLE_SIZE; i++)
+        {
+          valuesBPMSum += valuesBPM[i];
+        }
+
+/*        if(debug == true) 
+        {
+          Serial.print("CurrentMoving Avg: ");
+          for(int i=0; i<PULSE_BPM_SAMPLE_SIZE; i++)
+          {
+            Serial.print(valuesBPM[i]);
+            Serial.print(" ");
+          }
+  
+          Serial.println(" ");
+        }*/
+
+        bpmIndex++;
+        bpmIndex = bpmIndex % PULSE_BPM_SAMPLE_SIZE;
+
+        if(valuesBPMCount < PULSE_BPM_SAMPLE_SIZE)
+          valuesBPMCount++;
+
+        currentBPM = valuesBPMSum / valuesBPMCount;
+        //sprintf(show, "%f", currentBPM);
+        //putBLE(show);
+        //putBLE("\n");
+/*        if(debug == true) 
+        {
+          Serial.print("AVg. BPM: ");
+          Serial.println(currentBPM);
+        }*/
+
+
+        currentPulseDetectorState = PULSE_TRACE_DOWN;
+
+        return true;
+      }
+      break;
+
+    case PULSE_TRACE_DOWN:
+      if(sensor_value < prev_sensor_value)
+      {
+        values_went_down++;
+      }
+
+
+      if(sensor_value < PULSE_MIN_THRESHOLD)
+      {
+        currentPulseDetectorState = PULSE_IDLE;
+      }
+      break;
+  }
+
+  prev_sensor_value = sensor_value;
+  return false;
+}
+
+/***************************************************************************/
+
 int main(void){
+    millisStart();
+    dcFilterIR.w = 0;
+    dcFilterIR.result = 0;
+    meanDiffIR.index = 0;
+    meanDiffIR.sum = 0;
+    meanDiffIR.count = 0;
+    lpbFilterIR.v[0] = 0;
+    lpbFilterIR.v[1] = 0;
+    lpbFilterIR.result = 0;
+    valuesBPM[0] = 0;
+    valuesBPMSum = 0;
+    valuesBPMCount = 0;
+    bpmIndex = 0;
+
+/*    irACValueSqSum = 0;
+    redACValueSqSum = 0;
+    samplesRecorded = 0;
+    pulsesDetected = 0;
+    currentSaO2Value = 0;
+*/
+    lastBeatThreshold = 0;
+
+    currentPulseDetectorState = PULSE_IDLE;  
+  
+    float meanDiffResIR;
     SMPRDY.fall(&sample);
     Flasher.attach(periodicCallback, 1);
     ini_i2c(SCL, SDA);
     sensor.begin(pw1600, i17, sr50 );
     iniBLE("Sigfried");
     while(1){
-        //sensor.readSensor();
+        sensor.readSensor();
+        dcFilterIR = DCfilter((float)sensor.IR, dcFilterIR.w, 0.95);
+        meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
+        lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &lpbFilterIR );
+        detectPulse( lpbFilterIR.result );
         //store_Samples();
+        sprintf(show, "%f", sensor.IR);
+        putBLE(show);
+        putBLE("\n");
         //wait(0.019);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/millis.lib	Tue May 30 01:00:34 2017 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/hudakz/code/millis/#ac7586424119