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.

BloodPressureService.h

Committer:
tsungta
Date:
2017-04-20
Revision:
2:64cead334a4c
Parent:
1:fc03791a9842

File content as of revision 2:64cead334a4c:

#include "BLE.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;
    
};