Graduation Thesis, use Nucleo and X-Nucleo BLE
Dependencies: PulseSensor GSM Thermometer KalmanFilter
Revision 25:8621ebb6ea0c, committed 2018-06-23
- 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
diff -r bee84b48322a -r 8621ebb6ea0c Application/ble_healthcare_service.h --- 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;
diff -r bee84b48322a -r 8621ebb6ea0c Application/main.cpp --- 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);
diff -r bee84b48322a -r 8621ebb6ea0c GSM.lib --- 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
diff -r bee84b48322a -r 8621ebb6ea0c MAX30100.lib --- /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