For Blood Pressure Demo

BLE_BloodPressure_demo implements Blood Pressure Service which enables a collector device to connect and interact with it. the service spec can be found here. User can download the APP 'nRF Connect' or 'nRF Toolbox' available in both App Store and Google Play to scan the adverting and connect to the module.

Revision:
0:546d7178e278
Child:
1:fc03791a9842
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BloodPressureService.h	Fri May 29 07:26:36 2015 +0000
@@ -0,0 +1,111 @@
+#include "BLEDevice.h"
+//#include "Gap.h"
+
+/*
+* @This example can be demonstrated with Blood Pressure Android App downloaded from
+* @https://github.com/Marcomissyou/BluetoothLeBooldPressure.git
+* @Author: Marco.Hsu  
+* @Email: marco.missyou@gmail.com 
+*/
+class BloodPressureService {
+public:
+    BloodPressureService(BLEDevice &_ble, float Systolic, float Diastolic, float mean_arterial, uint16_t BloodFeature):
+        ble(_ble),
+        BloodPressureValue(Systolic, Diastolic, mean_arterial),
+        BloodFeatureValue(BloodFeature),
+        //GlucoseFeatureValue(GluFeature),
+        BloodPressureGatt(GattCharacteristic::UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR, BloodPressureValue.getPointer(),
+                sizeof(uint8_t), BloodPressureStruc::MAX_VALUE_BYTES, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE),
+        BloodFeature(GattCharacteristic::UUID_BLOOD_PRESSURE_FEATURE_CHAR, &BloodFeatureValue) {
+            setupService();
+        }
+
+    void updateBloodPressureMeasurement(float Systolic, float Diastolic, float mean_arterial) {
+        BloodPressureValue.uploadBloodPressureValue(Systolic, Diastolic, mean_arterial);
+        ble.updateCharacteristicValue(BloodPressureGatt.getValueAttribute().getHandle(), BloodPressureValue.getPointer(), 6);
+    }
+    
+    
+
+private:
+    void setupService(void) {
+        static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
+        if (serviceAdded) {
+            return;
+        }
+
+        GattCharacteristic *charTable[] = {&BloodPressureGatt, &BloodFeature};
+        GattService         BloodService(GattService::UUID_BLOOD_PRESSURE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(BloodService);
+        serviceAdded = true;
+
+    }
+
+//==========================================================================================================
+private:
+struct BloodPressureStruc {
+        static const unsigned MAX_VALUE_BYTES  = 8; 
+        static const unsigned FLAGS_BYTE_INDEX = 0;
+        
+        static const unsigned Blood_Pressure_Units_Flag = 0;    // 0 in units of mmHg, 1 in units of kPa
+        static const unsigned Time_Stamp_Flag = 0;              //
+        static const unsigned Pulse_Rate_Flag = 0;
+        static const unsigned User_ID_Flag = 0;
+        static const unsigned Measurement_Status_Flag = 0;
+         
+        static const unsigned VALUE_FORMAT_BITNUM = 0;
+        static const uint8_t  VALUE_FORMAT_FLAG   = 0;
+        
+        // Initial setting Blood Pressure measurement value
+        BloodPressureStruc(float Systolic, float Diastolic, float mean_arterial) : BloodPressureValue() { 
+            uploadBloodPressureValue(Systolic, Diastolic, mean_arterial);
+        }
+        
+        // function to update Blood Pressure measurement value in unit of mmHg
+        void uploadBloodPressureValue(float Systolic, float Diastolic, float mean_arterial) {
+            uint16_t ieee11073_Systolic = ieee11073_float16(Systolic);
+            uint16_t ieee11073_Diastolic = ieee11073_float16(Diastolic);
+            uint16_t ieee11073_mean_arterial = ieee11073_float16(mean_arterial);
+            BloodPressureValue[FLAGS_BYTE_INDEX]    = (Blood_Pressure_Units_Flag << 0)|(Time_Stamp_Flag << 1)|
+                                                      (Pulse_Rate_Flag << 2)|(User_ID_Flag << 3)|(Measurement_Status_Flag << 4);
+            //memcpy(&BloodPressureValue[FLAGS_BYTE_INDEX], &ieee11073_Systolic, 2);
+            //memcpy(&BloodPressureValue[FLAGS_BYTE_INDEX+2], &ieee11073_Diastolic, 2);
+            //memcpy(&BloodPressureValue[FLAGS_BYTE_INDEX+4], &ieee11073_mean_arterial, 2);
+            BloodPressureValue[FLAGS_BYTE_INDEX + 1] = (uint8_t)(ieee11073_Systolic &0xff); 
+            BloodPressureValue[FLAGS_BYTE_INDEX + 2] = (uint8_t)(ieee11073_Systolic >> 8); 
+            BloodPressureValue[FLAGS_BYTE_INDEX + 3] = (uint8_t)(ieee11073_Diastolic &0xff); 
+            BloodPressureValue[FLAGS_BYTE_INDEX + 4] = (uint8_t)(ieee11073_Diastolic >> 8); 
+            BloodPressureValue[FLAGS_BYTE_INDEX + 5] = (uint8_t)(ieee11073_mean_arterial &0xff); 
+            BloodPressureValue[FLAGS_BYTE_INDEX + 6] = (uint8_t)(ieee11073_mean_arterial >>8); 
+        }
+
+
+        uint8_t       *getPointer(void) {
+            return BloodPressureValue;
+        }
+        
+        const uint8_t *getPointer(void) const {
+            return BloodPressureValue;
+        }
+        
+        uint16_t ieee11073_float16(float BloodPressure) {
+            uint8_t  exponent = 0; 
+            uint16_t mantissa = (uint16_t)BloodPressure;
+            return ((exponent << 12)&0xF0) | (mantissa << 0) & 0x0FFF ;
+        }
+private:
+        uint8_t BloodPressureValue[MAX_VALUE_BYTES];
+};
+
+        
+private:
+    BLEDevice           &ble;
+    
+    BloodPressureStruc          BloodPressureValue;
+    GattCharacteristic          BloodPressureGatt;  // data carrier 
+
+    uint16_t                    BloodFeatureValue;
+    ReadOnlyGattCharacteristic<uint16_t>  BloodFeature;
+    
+};
\ No newline at end of file