BLE temperature profile using digital DS1820 or analog LM35 sensors

Dependencies:   DS1820

Revision:
0:637031152314
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 07 16:23:41 2015 +0000
@@ -0,0 +1,101 @@
+/*----------------------------------------------------------------------------
+LAB EXERCISE - BLE Thermometer
+ ----------------------------------------
+	In this exercise you will write a program which will turn your board into
+	a BLE thermometer. You will be able to check the temperature with any device
+	that can read BLE temperature readings.
+	
+	GOOD LUCK!
+ *----------------------------------------------------------------------------*/
+
+#include "mbed.h"
+#include "DS1820.h"
+#include "nRF51822n.h"
+
+nRF51822n   nrf;
+DS1820 probe(P0_20);
+//AnalogIn LM35(P0_2); // Uncomment for analog LM35 sensor from Maplin
+Ticker		oneSec;
+
+// LEDs for indication
+DigitalOut  oneSecLed(LED1);
+DigitalOut  adStateLed(LED2);
+
+const static char	deviceName[] = "** Temperature Sensor **";
+
+// Health Thermometer Service
+uint8_t             tempSensorPayload[5] = { 0, 0, 0, 0, 0 };
+GattService         tempSensorService (GattService::UUID_HEALTH_THERMOMETER_SERVICE);
+GattCharacteristic  tempSensorChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, 5, 5, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
+
+// Advertising data and parameters
+GapAdvertisingData   advData;
+GapAdvertisingData   scanResponse;
+GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );
+
+// Function constructors
+uint32_t quick_ieee11073_from_float(float temperature);
+void updateTemp(void);
+
+class GapEventHandler : public GapEvents {
+    // When a client device connects we need to turn off the advertising LED
+	virtual void onConnected(void){
+        adStateLed = 0;
+    }
+
+    // When a client device disconnects we need to start advertising again
+    virtual void onDisconnected(void) {
+        nrf.getGap().startAdvertising(advParams);
+        adStateLed = 1;
+    }
+};
+
+
+int main(void){
+	
+	// Start the one second ticker
+	oneSec.attach(updateTemp, 1);
+	
+    nrf.getGap().setEventHandler(new GapEventHandler());
+    
+	// Start the BLE radio
+    nrf.init();
+    nrf.reset();    
+
+    // Add GAP data, but don't start advertising
+    advData.addFlags((GapAdvertisingData::Flags)(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE));
+    advData.addData(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t*)deviceName, sizeof(deviceName));
+    advData.addAppearance(GapAdvertisingData::GENERIC_THERMOMETER);
+    nrf.getGap().setAdvertisingData(advData, scanResponse);
+
+    // Temperature Sensor Service
+    tempSensorService.addCharacteristic(tempSensorChar);
+    nrf.getGattServer().addService(tempSensorService);
+    
+    // Finally start advertising (can't start advertising before all services are added)
+    nrf.getGap().startAdvertising(advParams);
+    adStateLed = 1;
+
+    while(1){
+	}
+}
+
+// Update temperature
+void updateTemp(void){
+      oneSecLed = !oneSecLed;
+      
+      probe.convertTemperature(true, DS1820::all_devices); // initialise DS1820 digital temperature sensor
+      float temperature = probe.temperature();             // obtain reading 
+      //float temperature = ((LM35*3.3)-0.600)*100.0;      // for use with analog LM35 sensor from Maplin
+      uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
+      memcpy(tempSensorPayload+1, &temp_ieee11073, 4);
+      nrf.getGattServer().updateValue(tempSensorChar.handle, tempSensorPayload, sizeof(tempSensorPayload));
+}
+
+// Quick conversion to an IEEE11073 format
+uint32_t quick_ieee11073_from_float(float temperature){
+    uint8_t  exponent = 0xFF;
+    uint32_t mantissa = (uint32_t)(temperature*10);
+    return ( ((uint32_t)exponent) << 24) | mantissa;
+}
+