Interrupt

Dependencies:   BLE_API BLE_Driver I2C_Driver MAX30100 PROCESAMIENTO_DATOS_SP02 mbed nRF51822 millis

Fork of MAX30100_FirstTry by TESIS SATUROMETRICA

Committer:
Ferszt
Date:
Tue May 30 01:00:34 2017 +0000
Revision:
5:c2ce7b743efa
Parent:
3:98ca4bf2e74a
Ultima prueba

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ferszt 0:882170680817 1 #include "mbed.h"
Ferszt 1:33d65d13c46a 2 #include "Ticker.h"
Ferszt 0:882170680817 3 #include "BLE_Driver.h"
Ferszt 1:33d65d13c46a 4 #include "MAX30100.h"
Ferszt 1:33d65d13c46a 5 #include "I2C_Driver.h"
Ferszt 1:33d65d13c46a 6 #include "PROCESAMIENTO_SPO2_FC.h"
Ferszt 5:c2ce7b743efa 7 #include "millis.h"
Ferszt 1:33d65d13c46a 8
Ferszt 1:33d65d13c46a 9 #define nRF51DK
Ferszt 1:33d65d13c46a 10 //#define nRF52DK
Ferszt 1:33d65d13c46a 11
Ferszt 1:33d65d13c46a 12
Ferszt 1:33d65d13c46a 13 #ifdef nRF52DK
Ferszt 1:33d65d13c46a 14 #define SCL 28
Ferszt 1:33d65d13c46a 15 #define SDA 29
Ferszt 1:33d65d13c46a 16 #endif
Ferszt 1:33d65d13c46a 17
Ferszt 1:33d65d13c46a 18 #ifdef nRF51DK
Ferszt 1:33d65d13c46a 19 #define SCL 7
Ferszt 1:33d65d13c46a 20 #define SDA 6
Ferszt 1:33d65d13c46a 21 #endif
Ferszt 0:882170680817 22
Ferszt 1:33d65d13c46a 23 //**************************
Ferszt 1:33d65d13c46a 24 int muestras_RED[200];
Ferszt 1:33d65d13c46a 25 int muestras_IR[200];
Ferszt 1:33d65d13c46a 26 int samples_index = 0;
cesarcazal 2:065060bb55f2 27 int max_min_period[2];
Ferszt 1:33d65d13c46a 28 int pico_pico,cresta, valle, cantidad;
Ferszt 1:33d65d13c46a 29 float frecuencia,periodo;
Ferszt 1:33d65d13c46a 30
Ferszt 1:33d65d13c46a 31 int index, aux1, nmuestra;
Ferszt 1:33d65d13c46a 32
Ferszt 3:98ca4bf2e74a 33 char show[10];
cesarcazal 2:065060bb55f2 34
Ferszt 1:33d65d13c46a 35 //******************
Ferszt 5:c2ce7b743efa 36 #define PULSE_MIN_THRESHOLD 100 //300 is good for finger, but for wrist you need like 20, and there is shitloads of noise
Ferszt 5:c2ce7b743efa 37 #define PULSE_MAX_THRESHOLD 2000
Ferszt 5:c2ce7b743efa 38 #define PULSE_GO_DOWN_THRESHOLD 1
Ferszt 1:33d65d13c46a 39
Ferszt 5:c2ce7b743efa 40 #define PULSE_BPM_SAMPLE_SIZE 10 //Moving average size
Ferszt 5:c2ce7b743efa 41 struct dcFilter_t {
Ferszt 5:c2ce7b743efa 42 float w;
Ferszt 5:c2ce7b743efa 43 float result;
Ferszt 5:c2ce7b743efa 44 };
Ferszt 5:c2ce7b743efa 45
Ferszt 5:c2ce7b743efa 46 struct meanDiffFilter_t
Ferszt 5:c2ce7b743efa 47 {
Ferszt 5:c2ce7b743efa 48 float values[15];
Ferszt 5:c2ce7b743efa 49 uint8_t index;
Ferszt 5:c2ce7b743efa 50 float sum;
Ferszt 5:c2ce7b743efa 51 uint8_t count;
Ferszt 5:c2ce7b743efa 52 };
Ferszt 5:c2ce7b743efa 53
Ferszt 5:c2ce7b743efa 54 struct butterworthFilter_t
Ferszt 5:c2ce7b743efa 55 {
Ferszt 5:c2ce7b743efa 56 float v[2];
Ferszt 5:c2ce7b743efa 57 float result;
Ferszt 5:c2ce7b743efa 58 };
Ferszt 5:c2ce7b743efa 59
Ferszt 5:c2ce7b743efa 60 typedef enum PulseStateMachine {
Ferszt 5:c2ce7b743efa 61 PULSE_IDLE,
Ferszt 5:c2ce7b743efa 62 PULSE_TRACE_UP,
Ferszt 5:c2ce7b743efa 63 PULSE_TRACE_DOWN
Ferszt 5:c2ce7b743efa 64 } PulseStateMachine;
Ferszt 5:c2ce7b743efa 65
Ferszt 5:c2ce7b743efa 66 dcFilter_t dcFilterIR;
Ferszt 5:c2ce7b743efa 67 meanDiffFilter_t meanDiffIR;
Ferszt 5:c2ce7b743efa 68 butterworthFilter_t lpbFilterIR;
Ferszt 5:c2ce7b743efa 69 float prev_w = 0;
Ferszt 5:c2ce7b743efa 70 uint32_t lastBeatThreshold;
Ferszt 5:c2ce7b743efa 71 uint8_t currentPulseDetectorState;
Ferszt 5:c2ce7b743efa 72 float currentBPM;
Ferszt 5:c2ce7b743efa 73 float valuesBPM[PULSE_BPM_SAMPLE_SIZE];
Ferszt 5:c2ce7b743efa 74 float valuesBPMSum;
Ferszt 5:c2ce7b743efa 75 uint8_t valuesBPMCount;
Ferszt 5:c2ce7b743efa 76 uint8_t bpmIndex;
Ferszt 5:c2ce7b743efa 77 //**************************
Ferszt 3:98ca4bf2e74a 78 InterruptIn SMPRDY(p0);
Ferszt 3:98ca4bf2e74a 79 DigitalOut LIVE_LED(p21, 1);
Ferszt 3:98ca4bf2e74a 80 DigitalOut CONECT_LED(p22, 1);
Ferszt 3:98ca4bf2e74a 81 DigitalOut TEST_LED(p23, 1);
Ferszt 3:98ca4bf2e74a 82 DigitalOut LED(p24, 1);
Ferszt 3:98ca4bf2e74a 83 //DigitalIn TEST_BUTTON(p17,PullUp);
Ferszt 1:33d65d13c46a 84
Ferszt 1:33d65d13c46a 85 Ticker Flasher;
Ferszt 1:33d65d13c46a 86 MAX30100 sensor;
Ferszt 0:882170680817 87
Ferszt 0:882170680817 88 void callbackBLE(int event) {
Ferszt 0:882170680817 89 switch (event){
Ferszt 1:33d65d13c46a 90 case 1: CONECT_LED = 1; break;
Ferszt 1:33d65d13c46a 91 case 2: CONECT_LED = 0; break;
Ferszt 0:882170680817 92 default: break;
Ferszt 0:882170680817 93 }
Ferszt 0:882170680817 94 }
Ferszt 0:882170680817 95
Ferszt 0:882170680817 96 void periodicCallback(void){
Ferszt 0:882170680817 97 LIVE_LED =! LIVE_LED;
Ferszt 0:882170680817 98 }
Ferszt 0:882170680817 99
Ferszt 1:33d65d13c46a 100 void store_Samples(void){
Ferszt 1:33d65d13c46a 101 if (samples_index == 200){
cesarcazal 2:065060bb55f2 102 periodo = valores(muestras_IR,max_min_period);
Ferszt 1:33d65d13c46a 103 frecuencia=60/(periodo*0.02);
Ferszt 1:33d65d13c46a 104 samples_index = 0;
Ferszt 1:33d65d13c46a 105 sprintf(show, "%f", frecuencia);
Ferszt 1:33d65d13c46a 106 putBLE(show);
Ferszt 1:33d65d13c46a 107 putBLE("\n");
Ferszt 1:33d65d13c46a 108 }
Ferszt 1:33d65d13c46a 109 else{
Ferszt 5:c2ce7b743efa 110 //muestras_RED[samples_index] = sensor.RED;
Ferszt 5:c2ce7b743efa 111 muestras_IR[samples_index] = lpbFilterIR.result;
Ferszt 5:c2ce7b743efa 112 //sprintf(show, "%d", muestras_IR[samples_index]);
Ferszt 5:c2ce7b743efa 113 //putBLE(show);
Ferszt 5:c2ce7b743efa 114 //putBLE("\n");
Ferszt 1:33d65d13c46a 115 samples_index++;
Ferszt 1:33d65d13c46a 116 }
Ferszt 1:33d65d13c46a 117 }
Ferszt 3:98ca4bf2e74a 118
Ferszt 3:98ca4bf2e74a 119 void sample(void){
Ferszt 3:98ca4bf2e74a 120 LED = 0;
Ferszt 3:98ca4bf2e74a 121 sensor.readSensor();
Ferszt 3:98ca4bf2e74a 122 sprintf(show, "%d", sensor.IR);
Ferszt 3:98ca4bf2e74a 123 putBLE(show);
Ferszt 3:98ca4bf2e74a 124 putBLE("\n");
Ferszt 3:98ca4bf2e74a 125 }
Ferszt 5:c2ce7b743efa 126
Ferszt 5:c2ce7b743efa 127 /***************************************************************************/
Ferszt 5:c2ce7b743efa 128
Ferszt 5:c2ce7b743efa 129 dcFilter_t DCfilter(float x, float prev, float alpha)
Ferszt 5:c2ce7b743efa 130 {
Ferszt 5:c2ce7b743efa 131 dcFilter_t filtered;
Ferszt 5:c2ce7b743efa 132 filtered.w = x + alpha * prev;
Ferszt 5:c2ce7b743efa 133 filtered.result = filtered.w - prev;
Ferszt 5:c2ce7b743efa 134 prev_w = filtered.w;
Ferszt 5:c2ce7b743efa 135 return filtered;
Ferszt 5:c2ce7b743efa 136 }
Ferszt 5:c2ce7b743efa 137
Ferszt 5:c2ce7b743efa 138 float meanDiff(float M, meanDiffFilter_t* filterValues)
Ferszt 5:c2ce7b743efa 139 {
Ferszt 5:c2ce7b743efa 140 float avg = 0;
Ferszt 5:c2ce7b743efa 141
Ferszt 5:c2ce7b743efa 142 filterValues->sum -= filterValues->values[filterValues->index];
Ferszt 5:c2ce7b743efa 143 filterValues->values[filterValues->index] = M;
Ferszt 5:c2ce7b743efa 144 filterValues->sum += filterValues->values[filterValues->index];
Ferszt 5:c2ce7b743efa 145
Ferszt 5:c2ce7b743efa 146 filterValues->index++;
Ferszt 5:c2ce7b743efa 147 filterValues->index = filterValues->index % 15;
Ferszt 5:c2ce7b743efa 148
Ferszt 5:c2ce7b743efa 149 if(filterValues->count < 15)
Ferszt 5:c2ce7b743efa 150 filterValues->count++;
Ferszt 5:c2ce7b743efa 151
Ferszt 5:c2ce7b743efa 152 avg = filterValues->sum / filterValues->count;
Ferszt 5:c2ce7b743efa 153 return avg - M;
Ferszt 5:c2ce7b743efa 154 }
Ferszt 5:c2ce7b743efa 155
Ferszt 5:c2ce7b743efa 156 void lowPassButterworthFilter( float x, butterworthFilter_t * filterResult )
Ferszt 5:c2ce7b743efa 157 {
Ferszt 5:c2ce7b743efa 158 filterResult->v[0] = filterResult->v[1];
Ferszt 5:c2ce7b743efa 159
Ferszt 5:c2ce7b743efa 160 //Fs = 100Hz and Fc = 10Hz
Ferszt 5:c2ce7b743efa 161 filterResult->v[1] = (2.452372752527856026e-1 * x) + (0.50952544949442879485 * filterResult->v[0]);
Ferszt 5:c2ce7b743efa 162
Ferszt 5:c2ce7b743efa 163 //Fs = 100Hz and Fc = 4Hz
Ferszt 5:c2ce7b743efa 164 //filterResult->v[1] = (1.367287359973195227e-1 * x) + (0.72654252800536101020 * filterResult->v[0]); //Very precise butterworth filter
Ferszt 5:c2ce7b743efa 165
Ferszt 5:c2ce7b743efa 166 filterResult->result = filterResult->v[0] + filterResult->v[1];
Ferszt 5:c2ce7b743efa 167 }
Ferszt 5:c2ce7b743efa 168
Ferszt 5:c2ce7b743efa 169 bool detectPulse(float sensor_value)
Ferszt 5:c2ce7b743efa 170 {
Ferszt 5:c2ce7b743efa 171 static float prev_sensor_value = 0;
Ferszt 5:c2ce7b743efa 172 static uint8_t values_went_down = 0;
Ferszt 5:c2ce7b743efa 173 static uint32_t currentBeat = 0;
Ferszt 5:c2ce7b743efa 174 static uint32_t lastBeat = 0;
Ferszt 5:c2ce7b743efa 175
Ferszt 5:c2ce7b743efa 176 if(sensor_value > PULSE_MAX_THRESHOLD)
Ferszt 5:c2ce7b743efa 177 {
Ferszt 5:c2ce7b743efa 178 currentPulseDetectorState = PULSE_IDLE;
Ferszt 5:c2ce7b743efa 179 prev_sensor_value = 0;
Ferszt 5:c2ce7b743efa 180 lastBeat = 0;
Ferszt 5:c2ce7b743efa 181 currentBeat = 0;
Ferszt 5:c2ce7b743efa 182 values_went_down = 0;
Ferszt 5:c2ce7b743efa 183 lastBeatThreshold = 0;
Ferszt 5:c2ce7b743efa 184 return false;
Ferszt 5:c2ce7b743efa 185 }
Ferszt 5:c2ce7b743efa 186
Ferszt 5:c2ce7b743efa 187 switch(currentPulseDetectorState)
Ferszt 5:c2ce7b743efa 188 {
Ferszt 5:c2ce7b743efa 189 case PULSE_IDLE:
Ferszt 5:c2ce7b743efa 190 if(sensor_value >= PULSE_MIN_THRESHOLD) {
Ferszt 5:c2ce7b743efa 191 currentPulseDetectorState = PULSE_TRACE_UP;
Ferszt 5:c2ce7b743efa 192 values_went_down = 0;
Ferszt 5:c2ce7b743efa 193 }
Ferszt 5:c2ce7b743efa 194 break;
Ferszt 5:c2ce7b743efa 195
Ferszt 5:c2ce7b743efa 196 case PULSE_TRACE_UP:
Ferszt 5:c2ce7b743efa 197 if(sensor_value > prev_sensor_value)
Ferszt 5:c2ce7b743efa 198 {
Ferszt 5:c2ce7b743efa 199 currentBeat = millis();
Ferszt 5:c2ce7b743efa 200 lastBeatThreshold = sensor_value;
Ferszt 5:c2ce7b743efa 201 }
Ferszt 5:c2ce7b743efa 202 else
Ferszt 5:c2ce7b743efa 203 {
Ferszt 5:c2ce7b743efa 204
Ferszt 5:c2ce7b743efa 205 uint32_t beatDuration = currentBeat - lastBeat;
Ferszt 5:c2ce7b743efa 206 lastBeat = currentBeat;
Ferszt 5:c2ce7b743efa 207
Ferszt 5:c2ce7b743efa 208 float rawBPM = 0;
Ferszt 5:c2ce7b743efa 209 if(beatDuration > 0)
Ferszt 5:c2ce7b743efa 210 rawBPM = 60000.0 / (float)beatDuration;
Ferszt 5:c2ce7b743efa 211 // if(debug == true)
Ferszt 5:c2ce7b743efa 212 // Serial.println(rawBPM);
Ferszt 5:c2ce7b743efa 213
Ferszt 5:c2ce7b743efa 214 //This method sometimes glitches, it's better to go through whole moving average everytime
Ferszt 5:c2ce7b743efa 215 //IT's a neat idea to optimize the amount of work for moving avg. but while placing, removing finger it can screw up
Ferszt 5:c2ce7b743efa 216 //valuesBPMSum -= valuesBPM[bpmIndex];
Ferszt 5:c2ce7b743efa 217 //valuesBPM[bpmIndex] = rawBPM;
Ferszt 5:c2ce7b743efa 218 //valuesBPMSum += valuesBPM[bpmIndex];
Ferszt 5:c2ce7b743efa 219
Ferszt 5:c2ce7b743efa 220 valuesBPM[bpmIndex] = rawBPM;
Ferszt 5:c2ce7b743efa 221 valuesBPMSum = 0;
Ferszt 5:c2ce7b743efa 222 for(int i=0; i<PULSE_BPM_SAMPLE_SIZE; i++)
Ferszt 5:c2ce7b743efa 223 {
Ferszt 5:c2ce7b743efa 224 valuesBPMSum += valuesBPM[i];
Ferszt 5:c2ce7b743efa 225 }
Ferszt 5:c2ce7b743efa 226
Ferszt 5:c2ce7b743efa 227 /* if(debug == true)
Ferszt 5:c2ce7b743efa 228 {
Ferszt 5:c2ce7b743efa 229 Serial.print("CurrentMoving Avg: ");
Ferszt 5:c2ce7b743efa 230 for(int i=0; i<PULSE_BPM_SAMPLE_SIZE; i++)
Ferszt 5:c2ce7b743efa 231 {
Ferszt 5:c2ce7b743efa 232 Serial.print(valuesBPM[i]);
Ferszt 5:c2ce7b743efa 233 Serial.print(" ");
Ferszt 5:c2ce7b743efa 234 }
Ferszt 5:c2ce7b743efa 235
Ferszt 5:c2ce7b743efa 236 Serial.println(" ");
Ferszt 5:c2ce7b743efa 237 }*/
Ferszt 5:c2ce7b743efa 238
Ferszt 5:c2ce7b743efa 239 bpmIndex++;
Ferszt 5:c2ce7b743efa 240 bpmIndex = bpmIndex % PULSE_BPM_SAMPLE_SIZE;
Ferszt 5:c2ce7b743efa 241
Ferszt 5:c2ce7b743efa 242 if(valuesBPMCount < PULSE_BPM_SAMPLE_SIZE)
Ferszt 5:c2ce7b743efa 243 valuesBPMCount++;
Ferszt 5:c2ce7b743efa 244
Ferszt 5:c2ce7b743efa 245 currentBPM = valuesBPMSum / valuesBPMCount;
Ferszt 5:c2ce7b743efa 246 //sprintf(show, "%f", currentBPM);
Ferszt 5:c2ce7b743efa 247 //putBLE(show);
Ferszt 5:c2ce7b743efa 248 //putBLE("\n");
Ferszt 5:c2ce7b743efa 249 /* if(debug == true)
Ferszt 5:c2ce7b743efa 250 {
Ferszt 5:c2ce7b743efa 251 Serial.print("AVg. BPM: ");
Ferszt 5:c2ce7b743efa 252 Serial.println(currentBPM);
Ferszt 5:c2ce7b743efa 253 }*/
Ferszt 5:c2ce7b743efa 254
Ferszt 5:c2ce7b743efa 255
Ferszt 5:c2ce7b743efa 256 currentPulseDetectorState = PULSE_TRACE_DOWN;
Ferszt 5:c2ce7b743efa 257
Ferszt 5:c2ce7b743efa 258 return true;
Ferszt 5:c2ce7b743efa 259 }
Ferszt 5:c2ce7b743efa 260 break;
Ferszt 5:c2ce7b743efa 261
Ferszt 5:c2ce7b743efa 262 case PULSE_TRACE_DOWN:
Ferszt 5:c2ce7b743efa 263 if(sensor_value < prev_sensor_value)
Ferszt 5:c2ce7b743efa 264 {
Ferszt 5:c2ce7b743efa 265 values_went_down++;
Ferszt 5:c2ce7b743efa 266 }
Ferszt 5:c2ce7b743efa 267
Ferszt 5:c2ce7b743efa 268
Ferszt 5:c2ce7b743efa 269 if(sensor_value < PULSE_MIN_THRESHOLD)
Ferszt 5:c2ce7b743efa 270 {
Ferszt 5:c2ce7b743efa 271 currentPulseDetectorState = PULSE_IDLE;
Ferszt 5:c2ce7b743efa 272 }
Ferszt 5:c2ce7b743efa 273 break;
Ferszt 5:c2ce7b743efa 274 }
Ferszt 5:c2ce7b743efa 275
Ferszt 5:c2ce7b743efa 276 prev_sensor_value = sensor_value;
Ferszt 5:c2ce7b743efa 277 return false;
Ferszt 5:c2ce7b743efa 278 }
Ferszt 5:c2ce7b743efa 279
Ferszt 5:c2ce7b743efa 280 /***************************************************************************/
Ferszt 5:c2ce7b743efa 281
Ferszt 0:882170680817 282 int main(void){
Ferszt 5:c2ce7b743efa 283 millisStart();
Ferszt 5:c2ce7b743efa 284 dcFilterIR.w = 0;
Ferszt 5:c2ce7b743efa 285 dcFilterIR.result = 0;
Ferszt 5:c2ce7b743efa 286 meanDiffIR.index = 0;
Ferszt 5:c2ce7b743efa 287 meanDiffIR.sum = 0;
Ferszt 5:c2ce7b743efa 288 meanDiffIR.count = 0;
Ferszt 5:c2ce7b743efa 289 lpbFilterIR.v[0] = 0;
Ferszt 5:c2ce7b743efa 290 lpbFilterIR.v[1] = 0;
Ferszt 5:c2ce7b743efa 291 lpbFilterIR.result = 0;
Ferszt 5:c2ce7b743efa 292 valuesBPM[0] = 0;
Ferszt 5:c2ce7b743efa 293 valuesBPMSum = 0;
Ferszt 5:c2ce7b743efa 294 valuesBPMCount = 0;
Ferszt 5:c2ce7b743efa 295 bpmIndex = 0;
Ferszt 5:c2ce7b743efa 296
Ferszt 5:c2ce7b743efa 297 /* irACValueSqSum = 0;
Ferszt 5:c2ce7b743efa 298 redACValueSqSum = 0;
Ferszt 5:c2ce7b743efa 299 samplesRecorded = 0;
Ferszt 5:c2ce7b743efa 300 pulsesDetected = 0;
Ferszt 5:c2ce7b743efa 301 currentSaO2Value = 0;
Ferszt 5:c2ce7b743efa 302 */
Ferszt 5:c2ce7b743efa 303 lastBeatThreshold = 0;
Ferszt 5:c2ce7b743efa 304
Ferszt 5:c2ce7b743efa 305 currentPulseDetectorState = PULSE_IDLE;
Ferszt 5:c2ce7b743efa 306
Ferszt 5:c2ce7b743efa 307 float meanDiffResIR;
Ferszt 3:98ca4bf2e74a 308 SMPRDY.fall(&sample);
Ferszt 0:882170680817 309 Flasher.attach(periodicCallback, 1);
Ferszt 1:33d65d13c46a 310 ini_i2c(SCL, SDA);
Ferszt 1:33d65d13c46a 311 sensor.begin(pw1600, i17, sr50 );
Ferszt 0:882170680817 312 iniBLE("Sigfried");
Ferszt 0:882170680817 313 while(1){
Ferszt 5:c2ce7b743efa 314 sensor.readSensor();
Ferszt 5:c2ce7b743efa 315 dcFilterIR = DCfilter((float)sensor.IR, dcFilterIR.w, 0.95);
Ferszt 5:c2ce7b743efa 316 meanDiffResIR = meanDiff( dcFilterIR.result, &meanDiffIR);
Ferszt 5:c2ce7b743efa 317 lowPassButterworthFilter( meanDiffResIR/*-dcFilterIR.result*/, &lpbFilterIR );
Ferszt 5:c2ce7b743efa 318 detectPulse( lpbFilterIR.result );
Ferszt 3:98ca4bf2e74a 319 //store_Samples();
Ferszt 5:c2ce7b743efa 320 sprintf(show, "%f", sensor.IR);
Ferszt 5:c2ce7b743efa 321 putBLE(show);
Ferszt 5:c2ce7b743efa 322 putBLE("\n");
Ferszt 3:98ca4bf2e74a 323 //wait(0.019);
Ferszt 0:882170680817 324 }
Ferszt 0:882170680817 325 }
Ferszt 0:882170680817 326
Ferszt 1:33d65d13c46a 327