John Greene / Mbed OS MAX30101_HR_SPO2

Dependencies:   MAX30101 max32630fthr

Fork of MAX30101_Demo_Plot_Algorithm by John Greene

Revision:
9:affd4e6372a0
Parent:
8:a1538e8a3fd9
Child:
10:fcfa9adc99a9
--- a/main.cpp	Tue Sep 26 16:45:15 2017 +0000
+++ b/main.cpp	Sun Oct 15 19:22:36 2017 +0000
@@ -35,6 +35,12 @@
 #include "mbed.h"
 #include "max32630fthr.h"
 #include "MAX30101.h"
+#include "algorithm.h"
+
+//equals 3*number of LEDS used
+#define DIV_SAMPLE 6 
+//sets the number of samples sent to the heart rate and SPO2 calculation 
+#define CALC_SAMPLE 500
 
 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
 
@@ -75,32 +81,132 @@
     uint16_t idx, readBytes;
     int32_t opSample;
     uint32_t sample;
-    while(1) {
-
-        if( rc == 0 ) {
+    uint32_t redData[500];//set array to max fifo size 
+    uint32_t irData[500];//set array to max fifo size 
+    int r=0; //counter for redData position 
+    int ir=0; //counter for irData position
+    int c=0; //counter to print values
+    int i =0; //second counter 
+    int32_t spo2 =0;
+    int8_t spo2Valid = 0;
+    int32_t heartRate = 0;
+    int8_t heartRateValid = 0;
+    int32_t numSamples = 0;
+    uint32_t fifoIR[MAX30101::MAX_FIFO_BYTES];
+    uint32_t fifoRED[MAX30101::MAX_FIFO_BYTES];
+    
+    
+    while(1) 
+    {
+       
+        
+        if( rc == 0 ) 
+        {
             
             // Check if op_sensor interrupt asserted
-            if(op_sensorIntFlag) {
-                
+            if(op_sensorIntFlag) 
+            {
+                pc.printf("Entered op_sensorIntFlag check\r\n");
                 op_sensorIntFlag = 0;                       // Lower interrupt flag
                 rc = op_sensor.getInterruptStatus(ints);    // Read interrupt status 
                 
                 // Check if FIFO almost full interrupt asserted
-                if((rc == 0) && (ints.bits.a_full)) {
-                    
+                if((rc == 0) && (ints.bits.a_full)) 
+                {
+                    pc.printf("about to read fifo\r\n");
                     // Read FIFO 
-                    rc = op_sensor.readFIFO(MAX30101::OneLedChannel, fifoData, readBytes);     
+                    rc = op_sensor.readFIFO(MAX30101::TwoLedChannels, fifoData, readBytes);     
                     
-                    if(rc == 0) {
+                    numSamples = readBytes/DIV_SAMPLE; //calcualtes number of smaples read 
+                    
+                    if(rc == 0) 
+                    {
                         
                         // Convert read bytes into samples
-                        for(idx = 0; idx < readBytes; idx+=3) {
+                        for(idx = 0, c=0, i=0; idx < readBytes; idx+=3) 
+                        {
+                            //pc.printf("In sample adjustment \r\n");
                             sample = (fifoData[idx]<<16) | (fifoData[idx+1]<<8) | (fifoData[idx+2]);
                             opSample = sample << 14;           // Sign extends sample 
                             opSample = opSample >> 14;
-                            pc.printf("%i\r\n", opSample);     // Print results
+                            if(idx%2==0)
+                            {
+                                //pc.printf("end red allocation\r\n");
+                                redData[r] = opSample;//saves to buff for calculations 
+                                fifoRED[i] = opSample;//saves to buff to print values just obtained 
+                                r++;
+                                i++;
+                                
+                            }
+                            else
+                            {
+                                //pc.printf("end ir allocation\r\n");
+                                irData[ir] = opSample; //saves to buff for calculations 
+                                fifoIR[c] = opSample;//saves to buff to print values just obtained 
+                                ir++;
+                                c++;
+                                
+                            }
+                            pc.printf("Red count = %i\r\n IR count = %i\r\n",r,ir);
+                            //pc.printf("idx = %i and readbytes = %i\r\n", idx,readBytes);
+                            
                         }
                         
+                        if(r>=200 & ir>=200)//checks to make sure there are 200 samples in data buffers 
+                        {
+                            pc.printf("In Calculation Function\r\n");
+                            //calculate heart rate and spo2
+                            maxim_heart_rate_and_oxygen_saturation( irData, CALC_SAMPLE, 
+                            redData, &spo2, &spo2Valid, &heartRate, &heartRateValid);
+                            
+                             for(c=100;c<200;c++)//dump first hundred samples after calculations 
+                            {
+                                redData[c-100]=redData[c];
+                                irData[c-100]=irData[c];
+
+                            }
+                            r=50;
+                            ir=50;
+                            
+                            
+                        }
+
+                        
+                        
+                        pc.printf("Read Samples %i\r\n",numSamples);
+                        //prints the Red LED data 
+                        pc.printf("RED LED DATA\r\n");
+                        for(c=0; c<numSamples; c++)
+                        {
+                            pc.printf("%i\r\n",fifoRED[c]);  
+                        }
+                        
+                        //prints the IR LED data 
+                        pc.printf("IR LED DATA\r\n");
+                        for(c=0; c<numSamples; c++)
+                        {
+                            pc.printf("%i\r\n",fifoIR[c]);  
+                        }
+                        
+                        if(spo2Valid==1)
+                        {
+                            pc.printf("SPO2 = %i\r\n",spo2);
+                            spo2Valid=0;
+                        }
+                        else
+                        {
+                           pc.printf("SPO2 calculation waiting for enough samples\r\n");
+                        }
+                        if(heartRateValid==1)
+                        {
+                            pc.printf("Heart Rate = %i\r\n",heartRate);
+                            heartRateValid=0;
+                        }else
+                        {
+                            pc.printf("Heart rate calculation waiting for enough samples\r\n");
+                        }
+                        
+                        
                     }
                 }
             }
@@ -138,8 +244,8 @@
     if(rc == 0)
     {
         ints.all = 0;
-        ints.bits.die_temp = 1;     // Enable FIFO almost full interrupt
-        ints.bits.a_full = 1;       // Enable internal die temp. interrupt
+        ints.bits.die_temp = 1;     // Enable internal die temp. interrupt
+        ints.bits.a_full = 1;       // Enable FIFO almost full interrupt
         rc = op_sensor.enableInterrupts(ints);
     }
     
@@ -148,7 +254,7 @@
     if(rc == 0)
     {
         fifoConfig.all = 0;
-        fifoConfig.bits.fifo_a_full = 15;                               // Max level of 15 samples 
+        fifoConfig.bits.fifo_a_full = 15;                               // Max level of 15 samples  
         fifoConfig.bits.sample_average = MAX30101::AveragedSamples_8;   // Average 8 samples
         rc = op_sensor.setFIFOConfiguration(fifoConfig);
     }
@@ -156,24 +262,29 @@
     MAX30101::SpO2Configuration_u spo2Config;
     if(rc == 0)
     {
-        spo2Config.all = 0;
-        spo2Config.bits.spo2_sr = MAX30101::SR_3200_Hz;     // SpO2 SR = 1600Hz
+        spo2Config.all = 0;                                 // sets smallest LSB size 
+        spo2Config.bits.spo2_sr = MAX30101::SR_3200_Hz;     // SpO2 SR = 3200Hz
         spo2Config.bits.led_pw = MAX30101::PW_3;            // 18-bit ADC resolution
         rc = op_sensor.setSpO2Configuration(spo2Config);
     }
     
-    //Set LED1 drive current
+    //Set LED drive currents
     if(rc == 0)
     {
         // Heart Rate only, 1 LED channel, Pulse amp. = 0x1F
         rc = op_sensor.setLEDPulseAmplitude(MAX30101::LED1_PA, 0x1F);
+        //To include SPO2, 2 LED channel, Pulse amp. 0x1F
+        if(rc==0)
+        {
+            rc = op_sensor.setLEDPulseAmplitude(MAX30101::LED2_PA, 0x1F);
+        }
     }
        
     //Set operating mode
     modeConfig.all = 0;
     if(rc == 0)
     {
-        modeConfig.bits.mode = MAX30101::HeartRateMode;     // Heart-rate only
+        modeConfig.bits.mode = MAX30101::SpO2Mode;     // Sets SPO2 Mode 
         rc = op_sensor.setModeConfiguration(modeConfig);
     }