Graduation Thesis, use Nucleo and X-Nucleo BLE

Dependencies:   PulseSensor GSM Thermometer KalmanFilter

Revision:
25:8621ebb6ea0c
Parent:
23:720a27ce4567
--- a/Application/main.cpp	Mon Jun 18 07:38:54 2018 +0000
+++ b/Application/main.cpp	Sat Jun 23 18:12:35 2018 +0000
@@ -12,15 +12,16 @@
   * version 1.0     03-09-2018  Some minor bugs fixed
   * version 1.0.5   03-09-2018  Some minor bugs fixed
   * version 1.3.7   04-06-2018  Some minor bugs fixed
+  * version 1.4.4   23-06-2018  Added max30100 still developing
  
 /* ======================== INCLUDES ========================= */
 #include <events/mbed_events.h>
 #include <mbed.h>
 #include "ble/BLE.h"
 #include "ble_healthcare_service.h"
-#include "GSM.h"
 #include "LM35.h"
 #include "PulseSensor.h"
+#include "MAX30100_PulseOximeter.h"
 #include "KalmanFilterPulse.h"
  
 /* ======================== DEFINES ========================== */
@@ -30,12 +31,26 @@
 #define START_SEND_INT_TEMP     13
 #define START_SEND_FLOAT_TEMP   10
 #define STOP_SEND_TEMP          20
+
+#define SAMPLE_HEARTRATE        16
+#define AVERAGE_HEARTRATE       8
+#define REPORTING_PERIOS        3125  /* 1/16 s */
+
 /* ======================= VARIABLES ========================= */
 /* GLOBAL VARIABLES */
-static float    currentTemperature  = 36.9;
-static uint16_t currentHRMCounter;
+static float    processedTemperature  = 36.9;
+static uint16_t processedHRMCounter;
 static float    sendCombinedTempAndHR;
 static uint16_t sendCombinedHRAndTemp;
+
+bool                 isEmptyavgHR                      = true;
+bool                 startCalculatingStandardDeviation = true;
+std::vector<float>   valuesHeartRate;
+std::vector<uint8_t> valuesSpO2;
+ 
+uint8_t avgHRIndex      = 0;    
+float avgHR[AVERAGE_HEARTRATE] = {0};
+uint16_t avgHeartRate;
  
 /* PRIVATE VARIABLES */
 uint8_t cnt;
@@ -57,9 +72,20 @@
 uint8_t hrmPosition = HealthCareService::HealthCareService::HRM_LOCATION_FINGER;                                       
  
 /* STRUCTS/CLASSESS */
+typedef struct {
+    float    heartRate;
+    float    SpO2;
+} message_t;
+
 HealthCareService       *HealthCareServicePtr;
+
+MemoryPool<message_t, 32> mpool;
+Queue<message_t, 32> queue;
+
+Thread              thread;
+PulseOximeter       pox; 
  
-static EventQueue   eventQueue(EVENTS_EVENT_SIZE * 20);
+static EventQueue   eventQueue(EVENTS_EVENT_SIZE * 32);
 Serial              serial(USBTX, USBRX);
 KalmanFilterPulse   kalman(0.5, 10, 1);
 KalmanFilterPulse   kalman1(2, 10, 0.1);
@@ -72,12 +98,14 @@
 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context);
  
 void sendDataToProcessing(char symbol, int data);
+void onBeatDetected();
+void beatEvent();
 void updatePayload(void);
 void main_event(void);
 void periodicCallback(void);
  
-PulseSensor sensor(PULSE_SENSOR_PIN, sendDataToProcessing, 10);
-LM35Therm   lm35(THERM_SENSOR_PIN, 7.15);
+PulseSensor sensor(PULSE_SENSOR_PIN, sendDataToProcessing, 20);
+LM35Therm   lm35(THERM_SENSOR_PIN, 4.56);
 
 /* ==================== FUNCTION DETAILS ===================== */
 /* Restart Advertising on disconnection */
@@ -95,7 +123,7 @@
     {
         filtedData = kalman.kalmanUpdate(data);
         filtedData = kalman.kalmanUpdate(filtedData);
-        currentHRMCounter = filtedData/1;
+        processedHRMCounter = filtedData/1;
         printf("%c%d %d\r\n", symbol, data,(uint8_t)(filtedData/1));
     }  
 }
@@ -134,17 +162,15 @@
     /* Do blocking calls or whatever is necessary for sensor polling.
        In our case, we simply update the Temperature measurement. */
     /* TODO Read temperature */
-//    currentTemperature = (currentTemperature + 0.16 > 42.79) ? 35.69 : currentTemperature + 1.18;
     lm35.getAverageValue();
-    currentTemperature = kalman1.kalmanUpdate(lm35.getTempInC());
-    currentTemperature = kalman1.kalmanUpdate(currentTemperature);    
+    processedTemperature = kalman1.kalmanUpdate(lm35.getTempInC());
+    processedTemperature = kalman1.kalmanUpdate(processedTemperature);    
     
     /* TODO Read Heart Rate */
-//    currentHRMCounter  = (currentHRMCounter + 1 > 120) ? 75 : (currentHRMCounter + HRM_increasement);
     /* Updated in callback function */
     
     /* Some little tricks here to make the temperature decimal and fractional parts different from the send codes */
-    intTemperatureValuex100 = currentTemperature * 100;
+    intTemperatureValuex100 = processedTemperature * 100;
     fractionalTemperature   = intTemperatureValuex100 % 100;
     decimalTemperature      = intTemperatureValuex100 / 100;
     if ((fractionalTemperature == START_SEND_INT_TEMP)   || 
@@ -159,28 +185,26 @@
     /* TODO Update Service data */
     updatePayload();
     
-    /* sendCombinedTempAndHR = (currentTemperature * 100)* 1000 + currentHRMCounter */
-    sendCombinedTempAndHR  = currentTemperature * 1000; /* Temperature float to int conversion */
-    sendCombinedTempAndHR  = sendCombinedTempAndHR + (float)(currentHRMCounter/100.0); 
-    
-    
+    /* sendCombinedTempAndHR = (processedTemperature * 100)* 1000 + processedHRMCounter */
+    sendCombinedTempAndHR  = intTemperatureValuex100 * 10.0; /* Temperature float to int conversion */
+    sendCombinedTempAndHR  = sendCombinedTempAndHR + (float)(processedHRMCounter/100.0); 
     
     switch (startSendFloat) {
-        case 0: sendCombinedHRAndTemp  = currentHRMCounter * 100;
+        case 0: sendCombinedHRAndTemp  = processedHRMCounter * 100;
                 sendCombinedHRAndTemp  = sendCombinedHRAndTemp + (uint8_t)START_SEND_INT_TEMP; 
         break;
         
-        case 1: /* sendCombinedHRAndTemp = (currentHRMCounter * 100) + decimalTemperature */
+        case 1: /* sendCombinedHRAndTemp = (processedHRMCounter * 100) + decimalTemperature */
                 /* Because the maximum size of HRM Value is 2 bytes */
-                sendCombinedHRAndTemp  = currentHRMCounter * 100;
+                sendCombinedHRAndTemp  = processedHRMCounter * 100;
                 sendCombinedHRAndTemp  = sendCombinedHRAndTemp + (uint8_t)decimalTemperature; 
         break;
                 
-        case 2: sendCombinedHRAndTemp  = currentHRMCounter * 100;
+        case 2: sendCombinedHRAndTemp  = processedHRMCounter * 100;
                 sendCombinedHRAndTemp  = sendCombinedHRAndTemp + (uint8_t)START_SEND_FLOAT_TEMP; 
         break;
         
-        case 3: sendCombinedHRAndTemp  = currentHRMCounter * 100;
+        case 3: sendCombinedHRAndTemp  = processedHRMCounter * 100;
                 sendCombinedHRAndTemp  = sendCombinedHRAndTemp + (uint8_t)fractionalTemperature; 
         break;
                 
@@ -188,8 +212,8 @@
     }   
 //    printf("sendCombinedTempAndHR %d\r\n", sendCombinedTempAndHR);
 //    printf("sendCombinedTempAndHR %.2f\r\n\r\n", (float)sendCombinedTempAndHR);
-//    printf("currentHRMCounter %d\r\n", currentHRMCounter);
-//    printf("currentTemperature %d\r\n", (uint8_t)currentTemperature);
+//    printf("processedHRMCounter %d\r\n", processedHRMCounter);
+//    printf("processedTemperature %d\r\n", (uint8_t)processedTemperature);
 //    printf("sendCombinedHRAndTemp %d\r\n", sendCombinedHRAndTemp);
     
     if (isConnectedToDevice) 
@@ -203,6 +227,68 @@
         startSendFloat = 0;
     }
 }
+
+void beatEvent()
+{
+    float       heartRate;
+    float       rawHeartRate;
+    uint8_t     spO2;
+    uint16_t    rawSpO2;
+    uint8_t     counterMAX30100  = 0;
+    bool        newValueMAX30100 = false;
+    uint32_t    loopCount = 0;
+    printf("Thread\r\n");
+    while (1)
+    {
+        pox.update();
+        if (loopCount >= REPORTING_PERIOS) 
+        {
+            heartRate = pox.getHeartRate();
+            spO2 = pox.getSpO2();
+            
+            if(heartRate != 0 && spO2 != 0) 
+            {
+                printf("Heart rate: %f",heartRate);
+                printf("   bpm / SpO2: %d%\r\n", spO2);
+                valuesHeartRate.push_back(heartRate);
+                valuesSpO2.push_back(spO2);
+                counterMAX30100++;
+            }
+            else
+            {
+                printf("No finger\r\n");
+            }
+            
+            if(counterMAX30100 == SAMPLE_HEARTRATE) {
+                rawHeartRate = 0;
+                rawSpO2 = 0;
+                for(int i = 0; i < SAMPLE_HEARTRATE; i++){
+                    rawHeartRate += valuesHeartRate[i];
+                    rawSpO2 += valuesSpO2[i];        
+                }
+                
+                rawHeartRate /= SAMPLE_HEARTRATE;
+                rawSpO2 /= SAMPLE_HEARTRATE;
+                
+                counterMAX30100 = 0;
+                valuesHeartRate.clear();
+                valuesSpO2.clear();
+                newValueMAX30100 = true;
+            }
+            loopCount = 0;
+        }
+        if (newValueMAX30100)
+        {
+             message_t *message = mpool.alloc();
+             message->heartRate = rawHeartRate;
+             message->SpO2      = rawSpO2;
+             printf("Send vales %.2f %.2f \r\n", rawHeartRate, rawSpO2);
+             queue.put(message);                     
+             newValueMAX30100 = false;
+        } 
+        loopCount++;                    
+    }
+}
  
 void periodicCallback(void) 
 {
@@ -277,8 +363,8 @@
     ble.gap().onDisconnection(&disconnectionCallback);
     ble.gattServer().onDataWritten(onDataWrittenCallback);
     
-    HealthCareServicePtr = new HealthCareService(ble, currentTemperature, htsPosition, 
-                                                      currentHRMCounter, hrmPosition,
+    HealthCareServicePtr = new HealthCareService(ble, processedTemperature, htsPosition, 
+                                                      processedHRMCounter, hrmPosition,
                                                       initial_HRMIncreasement);
  
     /* setup advertising */
@@ -323,6 +409,17 @@
 {
     serial.baud(115200);
     printf("\r\n BODY WIRELESS SENSOR NETWORK\r\n");
+    
+//    if(!pox.begin())
+//    {
+//        printf("No sensor detected\r\n");
+//    }
+//    else
+//    {
+//        printf("Sensor found\r\n");
+//    }
+//    thread.start(callback(beatEvent));    
+    
     /* call periodicCallback every 500ms */
     eventQueue.call_every(1000, periodicCallback);