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