Graduation Thesis, use Nucleo and X-Nucleo BLE

Dependencies:   PulseSensor GSM Thermometer KalmanFilter

Files at this revision

API Documentation at this revision

Comitter:
DuyLionTran
Date:
Sat Jun 23 18:12:35 2018 +0000
Parent:
24:bee84b48322a
Commit message:
* version 1.4.4 23-06-2018 Added max30100 still developing

Changed in this revision

Application/ble_healthcare_service.h Show annotated file Show diff for this revision Revisions of this file
Application/main.cpp Show annotated file Show diff for this revision Revisions of this file
GSM.lib Show diff for this revision Revisions of this file
MAX30100.lib Show annotated file Show diff for this revision Revisions of this file
--- a/Application/ble_healthcare_service.h	Mon Jun 18 07:38:54 2018 +0000
+++ b/Application/ble_healthcare_service.h	Sat Jun 23 18:12:35 2018 +0000
@@ -265,11 +265,9 @@
     HeartRateValueBytes                                hrmValueByte;
 
     ReadOnlyGattCharacteristic<TemperatureValueBytes>  tempMeasurement;
-//    ReadOnlyGattCharacteristic<uint8_t>                tempLocation;
     ReadWriteGattCharacteristic<uint8_t>               tempLocation;
 
     GattCharacteristic                                 hrmRate;
-//    ReadOnlyGattCharacteristic<uint8_t>                hrmLocation;   
     ReadWriteGattCharacteristic<uint8_t>               hrmLocation;
     
     ReadWriteGattCharacteristic<uint8_t>               controlState;
--- 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);
     
--- a/GSM.lib	Mon Jun 18 07:38:54 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://os.mbed.com/teams/components/code/GSM/#24671d8aa0c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX30100.lib	Sat Jun 23 18:12:35 2018 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/AVELARDEV/code/MAX30100/#010b908e2187