BLE Temperature Service Mobile and Ubiquitous Computing Module Birkbeck College
main.cpp@0:dd0fea342ad2, 2015-03-08 (annotated)
- Committer:
- gkroussos
- Date:
- Sun Mar 08 19:42:20 2015 +0000
- Revision:
- 0:dd0fea342ad2
BLE Temperature Service ; Mobile and Ubiquitous Computing Module; Birkbeck College
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gkroussos | 0:dd0fea342ad2 | 1 | /*---------------------------------------------------------------------------- |
gkroussos | 0:dd0fea342ad2 | 2 | LAB EXERCISE - BLE Thermometer |
gkroussos | 0:dd0fea342ad2 | 3 | ---------------------------------------- |
gkroussos | 0:dd0fea342ad2 | 4 | In this exercise you will write a program which will turn your board into |
gkroussos | 0:dd0fea342ad2 | 5 | a BLE thermometer. You will be able to check the temperature with any device |
gkroussos | 0:dd0fea342ad2 | 6 | that can read BLE temperature readings. |
gkroussos | 0:dd0fea342ad2 | 7 | |
gkroussos | 0:dd0fea342ad2 | 8 | GOOD LUCK! |
gkroussos | 0:dd0fea342ad2 | 9 | *----------------------------------------------------------------------------*/ |
gkroussos | 0:dd0fea342ad2 | 10 | |
gkroussos | 0:dd0fea342ad2 | 11 | #include "mbed.h" |
gkroussos | 0:dd0fea342ad2 | 12 | #include "DS1820.h" |
gkroussos | 0:dd0fea342ad2 | 13 | #include "nRF51822n.h" |
gkroussos | 0:dd0fea342ad2 | 14 | |
gkroussos | 0:dd0fea342ad2 | 15 | nRF51822n nrf; |
gkroussos | 0:dd0fea342ad2 | 16 | DS1820 probe(P0_20); |
gkroussos | 0:dd0fea342ad2 | 17 | //AnalogIn LM35(P0_2); // Uncomment for analog LM35 sensor from Maplin |
gkroussos | 0:dd0fea342ad2 | 18 | Ticker oneSec; |
gkroussos | 0:dd0fea342ad2 | 19 | |
gkroussos | 0:dd0fea342ad2 | 20 | // LEDs for indication |
gkroussos | 0:dd0fea342ad2 | 21 | DigitalOut oneSecLed(LED1); |
gkroussos | 0:dd0fea342ad2 | 22 | DigitalOut adStateLed(LED2); |
gkroussos | 0:dd0fea342ad2 | 23 | |
gkroussos | 0:dd0fea342ad2 | 24 | const static char deviceName[] = "** Temperature Sensor **"; |
gkroussos | 0:dd0fea342ad2 | 25 | |
gkroussos | 0:dd0fea342ad2 | 26 | // Health Thermometer Service |
gkroussos | 0:dd0fea342ad2 | 27 | uint8_t tempSensorPayload[5] = { 0, 0, 0, 0, 0 }; |
gkroussos | 0:dd0fea342ad2 | 28 | // Add the temperature sensor service and characteristics |
gkroussos | 0:dd0fea342ad2 | 29 | // <Write your code here> |
gkroussos | 0:dd0fea342ad2 | 30 | |
gkroussos | 0:dd0fea342ad2 | 31 | |
gkroussos | 0:dd0fea342ad2 | 32 | // Function constructors |
gkroussos | 0:dd0fea342ad2 | 33 | uint32_t quick_ieee11073_from_float(float temperature); |
gkroussos | 0:dd0fea342ad2 | 34 | void updateTemp(void); |
gkroussos | 0:dd0fea342ad2 | 35 | |
gkroussos | 0:dd0fea342ad2 | 36 | class GapEventHandler : public GapEvents { |
gkroussos | 0:dd0fea342ad2 | 37 | // When a client device connects we need to turn off the advertising LED |
gkroussos | 0:dd0fea342ad2 | 38 | virtual void onConnected(void){ |
gkroussos | 0:dd0fea342ad2 | 39 | adStateLed = 0; |
gkroussos | 0:dd0fea342ad2 | 40 | } |
gkroussos | 0:dd0fea342ad2 | 41 | |
gkroussos | 0:dd0fea342ad2 | 42 | // When a client device disconnects we need to start advertising again |
gkroussos | 0:dd0fea342ad2 | 43 | virtual void onDisconnected(void) { |
gkroussos | 0:dd0fea342ad2 | 44 | nrf.getGap().startAdvertising(advParams); |
gkroussos | 0:dd0fea342ad2 | 45 | adStateLed = 1; |
gkroussos | 0:dd0fea342ad2 | 46 | } |
gkroussos | 0:dd0fea342ad2 | 47 | }; |
gkroussos | 0:dd0fea342ad2 | 48 | |
gkroussos | 0:dd0fea342ad2 | 49 | |
gkroussos | 0:dd0fea342ad2 | 50 | int main(void){ |
gkroussos | 0:dd0fea342ad2 | 51 | |
gkroussos | 0:dd0fea342ad2 | 52 | // Start the one second ticker |
gkroussos | 0:dd0fea342ad2 | 53 | oneSec.attach(updateTemp, 1); |
gkroussos | 0:dd0fea342ad2 | 54 | |
gkroussos | 0:dd0fea342ad2 | 55 | nrf.getGap().setEventHandler(new GapEventHandler()); |
gkroussos | 0:dd0fea342ad2 | 56 | |
gkroussos | 0:dd0fea342ad2 | 57 | // Start the BLE radio |
gkroussos | 0:dd0fea342ad2 | 58 | nrf.init(); |
gkroussos | 0:dd0fea342ad2 | 59 | nrf.reset(); |
gkroussos | 0:dd0fea342ad2 | 60 | |
gkroussos | 0:dd0fea342ad2 | 61 | // Add GAP data, but don't start advertising |
gkroussos | 0:dd0fea342ad2 | 62 | advData.addFlags((GapAdvertisingData::Flags)(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE)); |
gkroussos | 0:dd0fea342ad2 | 63 | advData.addData(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t*)deviceName, sizeof(deviceName)); |
gkroussos | 0:dd0fea342ad2 | 64 | advData.addAppearance(GapAdvertisingData::GENERIC_THERMOMETER); |
gkroussos | 0:dd0fea342ad2 | 65 | nrf.getGap().setAdvertisingData(advData, scanResponse); |
gkroussos | 0:dd0fea342ad2 | 66 | |
gkroussos | 0:dd0fea342ad2 | 67 | // Temperature Sensor Service |
gkroussos | 0:dd0fea342ad2 | 68 | // Add the characteristic to the tempSensorService and add the service to the GATT server |
gkroussos | 0:dd0fea342ad2 | 69 | // <Write your code here> |
gkroussos | 0:dd0fea342ad2 | 70 | |
gkroussos | 0:dd0fea342ad2 | 71 | // Finally start advertising (can't start advertising before all services are added) |
gkroussos | 0:dd0fea342ad2 | 72 | nrf.getGap().startAdvertising(advParams); |
gkroussos | 0:dd0fea342ad2 | 73 | adStateLed = 1; |
gkroussos | 0:dd0fea342ad2 | 74 | |
gkroussos | 0:dd0fea342ad2 | 75 | while(1){ |
gkroussos | 0:dd0fea342ad2 | 76 | } |
gkroussos | 0:dd0fea342ad2 | 77 | } |
gkroussos | 0:dd0fea342ad2 | 78 | |
gkroussos | 0:dd0fea342ad2 | 79 | // Update temperature |
gkroussos | 0:dd0fea342ad2 | 80 | void updateTemp(void){ |
gkroussos | 0:dd0fea342ad2 | 81 | oneSecLed = !oneSecLed; |
gkroussos | 0:dd0fea342ad2 | 82 | |
gkroussos | 0:dd0fea342ad2 | 83 | probe.convertTemperature(true, DS1820::all_devices); // initialise DS1820 digital temperature sensor |
gkroussos | 0:dd0fea342ad2 | 84 | float temperature = probe.temperature(); // obtain reading |
gkroussos | 0:dd0fea342ad2 | 85 | //float temperature = ((LM35*3.3)-0.600)*100.0; // for use with analog LM35 sensor from Maplin |
gkroussos | 0:dd0fea342ad2 | 86 | uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature); |
gkroussos | 0:dd0fea342ad2 | 87 | memcpy(tempSensorPayload+1, &temp_ieee11073, 4); |
gkroussos | 0:dd0fea342ad2 | 88 | nrf.getGattServer().updateValue(tempSensorChar.handle, tempSensorPayload, sizeof(tempSensorPayload)); |
gkroussos | 0:dd0fea342ad2 | 89 | } |
gkroussos | 0:dd0fea342ad2 | 90 | |
gkroussos | 0:dd0fea342ad2 | 91 | // Quick conversion to an IEEE11073 format |
gkroussos | 0:dd0fea342ad2 | 92 | uint32_t quick_ieee11073_from_float(float temperature){ |
gkroussos | 0:dd0fea342ad2 | 93 | uint8_t exponent = 0xFF; |
gkroussos | 0:dd0fea342ad2 | 94 | uint32_t mantissa = (uint32_t)(temperature*10); |
gkroussos | 0:dd0fea342ad2 | 95 | return ( ((uint32_t)exponent) << 24) | mantissa; |
gkroussos | 0:dd0fea342ad2 | 96 | } |
gkroussos | 0:dd0fea342ad2 | 97 |