Originally from Donal's blog article. http://mbed.org/users/donalm/code/BLE_Health_Thermometer_Blog/ Changed low freq. clock source from XTAL to IRC.

Dependencies:   BLE_API_Native_IRC TMP102 mbed

Fork of BLE_Health_Thermometer_Blog by Donal Morrissey

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2014 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "TMP102.h"
00019 #include "nRF51822n.h"
00020 
00021 nRF51822n   nrf;                               /* BLE radio driver */
00022 TMP102      healthThemometer(p22, p20, 0x90);  /* The TMP102 connected to our board */
00023 
00024 /* LEDs for indication: */
00025 DigitalOut  oneSecondLed(LED1);        /* LED1 is toggled every second. */
00026 DigitalOut  advertisingStateLed(LED2); /* LED2 is on when we are advertising, otherwise off. */
00027 
00028 
00029 /* Health Thermometer Service */ 
00030 uint8_t             thermTempPayload[5] = { 0, 0, 0, 0, 0 };
00031 GattService         thermService (GattService::UUID_HEALTH_THERMOMETER_SERVICE);
00032 GattCharacteristic  thermTemp (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
00033                                5, 5, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
00034 
00035 /* Battery Level Service */
00036 uint8_t            batt = 100;     /* Battery level */
00037 uint8_t            read_batt = 0; /* Variable to hold battery level reads */
00038 GattService        battService ( GattService::UUID_BATTERY_SERVICE );
00039 GattCharacteristic battLevel   ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 1, 1,
00040                                  GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
00041                                  GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
00042 
00043 
00044 /* Advertising data and parameters */
00045 GapAdvertisingData   advData;
00046 GapAdvertisingData   scanResponse;
00047 GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );
00048 
00049 uint16_t             uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE,
00050                                       GattService::UUID_BATTERY_SERVICE};
00051 
00052 uint32_t quick_ieee11073_from_float(float temperature);
00053 void updateServiceValues(void);
00054 
00055 /**************************************************************************/
00056 /*!
00057     @brief  This custom class can be used to override any GapEvents
00058             that you are interested in handling on an application level.
00059 */
00060 /**************************************************************************/
00061 class GapEventHandler : public GapEvents
00062 {
00063     //virtual void onTimeout(void) {}   
00064      
00065     virtual void onConnected(void)
00066     {
00067         advertisingStateLed = 0;
00068     }
00069 
00070     /* When a client device disconnects we need to start advertising again. */
00071     virtual void onDisconnected(void)
00072     {
00073         nrf.getGap().startAdvertising(advParams);
00074         advertisingStateLed = 1;
00075     }
00076 };
00077 
00078 /**************************************************************************/
00079 /*!
00080     @brief  Program entry point
00081 */
00082 /**************************************************************************/
00083 int main(void)
00084 {
00085     
00086     /* Setup blinky led */
00087     oneSecondLed=1;
00088     
00089     /* Setup an event handler for GAP events i.e. Client/Server connection events. */
00090     nrf.getGap().setEventHandler(new GapEventHandler());
00091     
00092     /* Initialise the nRF51822 */
00093     nrf.init();
00094 
00095     /* Make sure we get a clean start */
00096     nrf.reset();    
00097 
00098     /* Add BLE-Only flag and complete service list to the advertising data */
00099     advData.addFlags(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00100     advData.addData(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, 
00101                    (uint8_t*)uuid16_list, sizeof(uuid16_list));
00102     advData.addAppearance(GapAdvertisingData::GENERIC_THERMOMETER);
00103     nrf.getGap().setAdvertisingData(advData, scanResponse);
00104 
00105     /* Health Thermometer Service */
00106     thermService.addCharacteristic(thermTemp);
00107     nrf.getGattServer().addService(thermService);
00108     
00109     /* Add the Battery Level service */
00110     battService.addCharacteristic(battLevel);
00111     nrf.getGattServer().addService(battService);
00112 
00113     /* Start advertising (make sure you've added all your data first) */
00114     nrf.getGap().startAdvertising(advParams);
00115     advertisingStateLed = 1;
00116 
00117     for (;;)
00118     {
00119         /* Now that we're live, update the battery level & temperature characteristics */
00120         updateServiceValues();
00121         wait(1);
00122     }
00123 }
00124 
00125 /**************************************************************************/
00126 /*!
00127     @brief  Ticker callback to switch advertisingStateLed state
00128 */
00129 /**************************************************************************/
00130 void updateServiceValues(void)
00131 {
00132       /* Toggle the one second LEDs */
00133       oneSecondLed = !oneSecondLed;
00134       
00135       /* Update battery level */
00136       nrf.getGattServer().updateValue(battLevel.handle, (uint8_t*)&batt, sizeof(batt));
00137       /* Decrement the battery level. */
00138       batt <=50 ? batt=100 : batt--;;
00139       
00140       /* Update the temperature. Note that we need to convert to an ieee11073 format float. */
00141       float temperature = healthThemometer.read();
00142       uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
00143       memcpy(thermTempPayload+1, &temp_ieee11073, 4);
00144       nrf.getGattServer().updateValue(thermTemp.handle, thermTempPayload, sizeof(thermTempPayload));
00145 }
00146 
00147 /**
00148  * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
00149  * @param temperature The temperature as a float.
00150  * @return The temperature in 11073-20601 FLOAT-Type format.
00151  */
00152 uint32_t quick_ieee11073_from_float(float temperature)
00153 {
00154     uint8_t  exponent = 0xFF; //exponent is -1
00155     uint32_t mantissa = (uint32_t)(temperature*10);
00156     
00157     return ( ((uint32_t)exponent) << 24) | mantissa;
00158 }
00159