Demo Glucose Service

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

BLE_Glucose_demo implements the Glucose Service which enables a collector device to connect and interact with.

There is a brief sample code edited with Android Studio for demo this BLE_Glucose_demo example, and it is public on github, everyone can clone it by this URL: https://github.com/Marcomissyou/BluetoothLeGlucose.git. It is convenient for you to development your BLE idea.

There is also provided apk file so you can download and install it directly then demo this code, but make sure your Android phone supports Bluetooth 4.0. /media/uploads/Marcomissyou/bleglucoseservice.apk

Committer:
Marcomissyou
Date:
Thu Jul 02 05:25:19 2015 +0000
Revision:
67:aa3a1bbed328
update to correctly BLE_Glucose_demo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Marcomissyou 67:aa3a1bbed328 1 /* mbed Microcontroller Library
Marcomissyou 67:aa3a1bbed328 2 * Copyright (c) 2006-2013 ARM Limited
Marcomissyou 67:aa3a1bbed328 3 *
Marcomissyou 67:aa3a1bbed328 4 * Licensed under the Apache License, Version 2.0 (the "License");
Marcomissyou 67:aa3a1bbed328 5 * you may not use this file except in compliance with the License.
Marcomissyou 67:aa3a1bbed328 6 * You may obtain a copy of the License at
Marcomissyou 67:aa3a1bbed328 7 *
Marcomissyou 67:aa3a1bbed328 8 * http://www.apache.org/licenses/LICENSE-2.0
Marcomissyou 67:aa3a1bbed328 9 *
Marcomissyou 67:aa3a1bbed328 10 * Unless required by applicable law or agreed to in writing, software
Marcomissyou 67:aa3a1bbed328 11 * distributed under the License is distributed on an "AS IS" BASIS,
Marcomissyou 67:aa3a1bbed328 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Marcomissyou 67:aa3a1bbed328 13 * See the License for the specific language governing permissions and
Marcomissyou 67:aa3a1bbed328 14 * limitations under the License.
Marcomissyou 67:aa3a1bbed328 15 */
Marcomissyou 67:aa3a1bbed328 16
Marcomissyou 67:aa3a1bbed328 17 #ifndef __BLE_GLUCOSE_SERVICE_H__
Marcomissyou 67:aa3a1bbed328 18 #define __BLE_GLUCOSE_SERVICE_H__
Marcomissyou 67:aa3a1bbed328 19
Marcomissyou 67:aa3a1bbed328 20 #include "BLE.h"
Marcomissyou 67:aa3a1bbed328 21 /**
Marcomissyou 67:aa3a1bbed328 22 * @class GlucoseService
Marcomissyou 67:aa3a1bbed328 23 * @brief BLE Glucose Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br>
Marcomissyou 67:aa3a1bbed328 24 * @This example can be demonstrated with Blood Pressure Android App downloaded from
Marcomissyou 67:aa3a1bbed328 25 * @https://github.com/Marcomissyou/BluetoothLeGlucose.git
Marcomissyou 67:aa3a1bbed328 26 * @Author: Marco.Hsu
Marcomissyou 67:aa3a1bbed328 27 * @Email: marco.missyou@gmail.com
Marcomissyou 67:aa3a1bbed328 28 */
Marcomissyou 67:aa3a1bbed328 29 static uint16_t SEQUENCE_NUMBER = 11111;
Marcomissyou 67:aa3a1bbed328 30 static uint16_t BASE_TIME_YEAR = 2015;
Marcomissyou 67:aa3a1bbed328 31 static uint8_t BASE_TIME_MONTH = 5;
Marcomissyou 67:aa3a1bbed328 32 static uint8_t BASE_TIME_DAY = 29;
Marcomissyou 67:aa3a1bbed328 33 static uint8_t BASE_TIME_HOURS = 17;
Marcomissyou 67:aa3a1bbed328 34 static uint8_t BASE_TIME_MINUTES = 30;
Marcomissyou 67:aa3a1bbed328 35 static uint8_t BASE_TIME_SECONDS = 45;
Marcomissyou 67:aa3a1bbed328 36
Marcomissyou 67:aa3a1bbed328 37 class GlucoseService {
Marcomissyou 67:aa3a1bbed328 38 public:
Marcomissyou 67:aa3a1bbed328 39 GlucoseService(BLEDevice &_ble, float GluMeasure, uint16_t GluFeature =2111):
Marcomissyou 67:aa3a1bbed328 40 ble(_ble),
Marcomissyou 67:aa3a1bbed328 41 GluReceiveBuffer(),
Marcomissyou 67:aa3a1bbed328 42 GluReceive_flag(),
Marcomissyou 67:aa3a1bbed328 43 GlucoseMeasurementValue(GluMeasure),
Marcomissyou 67:aa3a1bbed328 44 GlucoseFeatureValue(GluFeature),
Marcomissyou 67:aa3a1bbed328 45 GlucoseValue(GattCharacteristic::UUID_GLUCOSE_MEASUREMENT_CHAR, GlucoseMeasurementValue.getPointer(),
Marcomissyou 67:aa3a1bbed328 46 12, 12,GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
Marcomissyou 67:aa3a1bbed328 47 GlucoseFeature(GattCharacteristic::UUID_GLUCOSE_FEATURE_CHAR, &GluFeature),
Marcomissyou 67:aa3a1bbed328 48 GluControlPoint(GattCharacteristic::UUID_RECORD_ACCESS_CONTROL_POINT_CHAR, GluReceiveBuffer, 4, 4,
Marcomissyou 67:aa3a1bbed328 49 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)
Marcomissyou 67:aa3a1bbed328 50 {
Marcomissyou 67:aa3a1bbed328 51 setupService();
Marcomissyou 67:aa3a1bbed328 52 }
Marcomissyou 67:aa3a1bbed328 53
Marcomissyou 67:aa3a1bbed328 54 void updateGlucoseMeasurement(float GluMeasure) {
Marcomissyou 67:aa3a1bbed328 55 GlucoseMeasurementValue.updateGlucoseMeasurement(GluMeasure);
Marcomissyou 67:aa3a1bbed328 56 ble.updateCharacteristicValue(GlucoseValue.getValueAttribute().getHandle(), GlucoseMeasurementValue.getPointer(), 12);
Marcomissyou 67:aa3a1bbed328 57 }
Marcomissyou 67:aa3a1bbed328 58
Marcomissyou 67:aa3a1bbed328 59 virtual void onDataWritten(const GattWriteCallbackParams *params) {
Marcomissyou 67:aa3a1bbed328 60 if (params->handle == GluControlPoint.getValueAttribute().getHandle()) {
Marcomissyou 67:aa3a1bbed328 61 uint16_t bytesRead = params->len;
Marcomissyou 67:aa3a1bbed328 62 if (bytesRead <= 4) {
Marcomissyou 67:aa3a1bbed328 63 memcpy(GluReceiveBuffer, params->data, bytesRead);
Marcomissyou 67:aa3a1bbed328 64 GluReceive_flag = 1;
Marcomissyou 67:aa3a1bbed328 65 }
Marcomissyou 67:aa3a1bbed328 66 }
Marcomissyou 67:aa3a1bbed328 67 }
Marcomissyou 67:aa3a1bbed328 68
Marcomissyou 67:aa3a1bbed328 69 bool is_GluReceived(){
Marcomissyou 67:aa3a1bbed328 70 if(GluReceive_flag ==1){
Marcomissyou 67:aa3a1bbed328 71 return true;
Marcomissyou 67:aa3a1bbed328 72 }
Marcomissyou 67:aa3a1bbed328 73 return false;
Marcomissyou 67:aa3a1bbed328 74 }
Marcomissyou 67:aa3a1bbed328 75
Marcomissyou 67:aa3a1bbed328 76 uint8_t *getControlPoint(){
Marcomissyou 67:aa3a1bbed328 77 return GluReceiveBuffer;
Marcomissyou 67:aa3a1bbed328 78 }
Marcomissyou 67:aa3a1bbed328 79
Marcomissyou 67:aa3a1bbed328 80 void CleanFlag(){
Marcomissyou 67:aa3a1bbed328 81 GluReceive_flag = 0;
Marcomissyou 67:aa3a1bbed328 82 }
Marcomissyou 67:aa3a1bbed328 83
Marcomissyou 67:aa3a1bbed328 84 private:
Marcomissyou 67:aa3a1bbed328 85 void setupService(void) {
Marcomissyou 67:aa3a1bbed328 86 static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
Marcomissyou 67:aa3a1bbed328 87 if (serviceAdded) {
Marcomissyou 67:aa3a1bbed328 88 return;
Marcomissyou 67:aa3a1bbed328 89 }
Marcomissyou 67:aa3a1bbed328 90 GattCharacteristic *charTable[] = {&GlucoseValue, &GlucoseFeature, &GluControlPoint}; //, &GlucoseContext
Marcomissyou 67:aa3a1bbed328 91 GattService GluService(GattService::UUID_GLUCOSE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Marcomissyou 67:aa3a1bbed328 92 ble.addService(GluService);
Marcomissyou 67:aa3a1bbed328 93 serviceAdded = true;
Marcomissyou 67:aa3a1bbed328 94 ble.onDataWritten(this, &GlucoseService::onDataWritten);
Marcomissyou 67:aa3a1bbed328 95 }
Marcomissyou 67:aa3a1bbed328 96
Marcomissyou 67:aa3a1bbed328 97 //==========================================================================================================
Marcomissyou 67:aa3a1bbed328 98 private:
Marcomissyou 67:aa3a1bbed328 99 struct GlucoseMeasurementBytes {
Marcomissyou 67:aa3a1bbed328 100 static const unsigned FLAGS_BYTE_INDEX = 0;
Marcomissyou 67:aa3a1bbed328 101 static const unsigned TIME_OFFSET_PRESENT = 0;
Marcomissyou 67:aa3a1bbed328 102 static const unsigned GLUCOSE_CONCENTRATION_Type_Sample_Location = 1;
Marcomissyou 67:aa3a1bbed328 103 static const unsigned GLUCOSE_CONCENTRATION_UNIT = 1; // 0 = kg/L, 1 = mol/L
Marcomissyou 67:aa3a1bbed328 104 static const unsigned SENSOR_STATUS_ANNUNCIATION = 0;
Marcomissyou 67:aa3a1bbed328 105 static const unsigned CONTEXT_INFORMATION_FOLLOWS_FALSE = 0;
Marcomissyou 67:aa3a1bbed328 106 static const unsigned CONTEXT_INFORMATION_FOLLOWS_TRUE = 1;
Marcomissyou 67:aa3a1bbed328 107 static const unsigned VALUE_FORMAT_BITNUM = 0;
Marcomissyou 67:aa3a1bbed328 108 static const uint8_t VALUE_FORMAT_FLAG = 0;
Marcomissyou 67:aa3a1bbed328 109
Marcomissyou 67:aa3a1bbed328 110 // Initial setting Glucose measurement value
Marcomissyou 67:aa3a1bbed328 111 GlucoseMeasurementBytes(uint16_t GluMeasure) : GlucoseMeasurementValue() {
Marcomissyou 67:aa3a1bbed328 112 updateGlucoseMeasurement(GluMeasure);
Marcomissyou 67:aa3a1bbed328 113 }
Marcomissyou 67:aa3a1bbed328 114
Marcomissyou 67:aa3a1bbed328 115 void updateDataAndSequneceNumber(){
Marcomissyou 67:aa3a1bbed328 116 SEQUENCE_NUMBER++;
Marcomissyou 67:aa3a1bbed328 117 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+3], &BASE_TIME_YEAR, 2);
Marcomissyou 67:aa3a1bbed328 118 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+5], &BASE_TIME_MONTH, 1);
Marcomissyou 67:aa3a1bbed328 119 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+6], &BASE_TIME_DAY, 1);
Marcomissyou 67:aa3a1bbed328 120 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+7], &BASE_TIME_HOURS, 1);
Marcomissyou 67:aa3a1bbed328 121 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+8], &BASE_TIME_MINUTES, 1);
Marcomissyou 67:aa3a1bbed328 122 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+9], &BASE_TIME_SECONDS, 1);
Marcomissyou 67:aa3a1bbed328 123
Marcomissyou 67:aa3a1bbed328 124 }
Marcomissyou 67:aa3a1bbed328 125
Marcomissyou 67:aa3a1bbed328 126 void updateGlucoseMeasurement(float GluMeasure) {
Marcomissyou 67:aa3a1bbed328 127 GlucoseMeasurementValue[FLAGS_BYTE_INDEX] = (TIME_OFFSET_PRESENT << 0)|(GLUCOSE_CONCENTRATION_Type_Sample_Location << 1)
Marcomissyou 67:aa3a1bbed328 128 |(GLUCOSE_CONCENTRATION_UNIT << 2)|(SENSOR_STATUS_ANNUNCIATION << 3)
Marcomissyou 67:aa3a1bbed328 129 |(CONTEXT_INFORMATION_FOLLOWS_FALSE << 4);
Marcomissyou 67:aa3a1bbed328 130
Marcomissyou 67:aa3a1bbed328 131 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+1], &SEQUENCE_NUMBER, 2);
Marcomissyou 67:aa3a1bbed328 132 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+3], &BASE_TIME_YEAR, 2);
Marcomissyou 67:aa3a1bbed328 133 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+5], &BASE_TIME_MONTH, 1);
Marcomissyou 67:aa3a1bbed328 134 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+6], &BASE_TIME_DAY, 1);
Marcomissyou 67:aa3a1bbed328 135 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+7], &BASE_TIME_HOURS, 1);
Marcomissyou 67:aa3a1bbed328 136 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+8], &BASE_TIME_MINUTES, 1);
Marcomissyou 67:aa3a1bbed328 137 memcpy(&GlucoseMeasurementValue[FLAGS_BYTE_INDEX+9], &BASE_TIME_SECONDS, 1);
Marcomissyou 67:aa3a1bbed328 138 uint16_t GluMeasureData = ieee11073_float16(GluMeasure);
Marcomissyou 67:aa3a1bbed328 139 GlucoseMeasurementValue[FLAGS_BYTE_INDEX + 10] = (uint8_t)(GluMeasureData & 0xFF);
Marcomissyou 67:aa3a1bbed328 140 GlucoseMeasurementValue[FLAGS_BYTE_INDEX + 11] = (uint8_t)(GluMeasureData >> 8);
Marcomissyou 67:aa3a1bbed328 141 }
Marcomissyou 67:aa3a1bbed328 142
Marcomissyou 67:aa3a1bbed328 143 uint8_t *getPointer(void) {
Marcomissyou 67:aa3a1bbed328 144 return GlucoseMeasurementValue;
Marcomissyou 67:aa3a1bbed328 145 }
Marcomissyou 67:aa3a1bbed328 146
Marcomissyou 67:aa3a1bbed328 147 uint16_t ieee11073_float16(float GluMeasure) {
Marcomissyou 67:aa3a1bbed328 148 uint8_t exponent = 0;
Marcomissyou 67:aa3a1bbed328 149 uint16_t mantissa = (uint16_t)GluMeasure;
Marcomissyou 67:aa3a1bbed328 150 return ((exponent << 12)&0xF0) | (mantissa << 0) & 0x0FFF ;
Marcomissyou 67:aa3a1bbed328 151 }
Marcomissyou 67:aa3a1bbed328 152
Marcomissyou 67:aa3a1bbed328 153 uint8_t GlucoseMeasurementValue[14];
Marcomissyou 67:aa3a1bbed328 154 };
Marcomissyou 67:aa3a1bbed328 155
Marcomissyou 67:aa3a1bbed328 156 private:
Marcomissyou 67:aa3a1bbed328 157 BLEDevice &ble;
Marcomissyou 67:aa3a1bbed328 158 GlucoseMeasurementBytes GlucoseMeasurementValue;
Marcomissyou 67:aa3a1bbed328 159 GattCharacteristic GlucoseValue;
Marcomissyou 67:aa3a1bbed328 160 uint16_t GlucoseFeatureValue;
Marcomissyou 67:aa3a1bbed328 161 ReadWriteGattCharacteristic<uint16_t> GlucoseFeature;
Marcomissyou 67:aa3a1bbed328 162 uint8_t GluReceiveBuffer[4];
Marcomissyou 67:aa3a1bbed328 163 uint8_t GluReceive_flag;
Marcomissyou 67:aa3a1bbed328 164 GattCharacteristic GluControlPoint;
Marcomissyou 67:aa3a1bbed328 165 };
Marcomissyou 67:aa3a1bbed328 166 #endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/