BLE temperature profile using digital DS1820 or analog LM35 sensors

Dependencies:   DS1820

main.cpp

Committer:
gkroussos
Date:
2015-03-07
Revision:
0:637031152314

File content as of revision 0:637031152314:

/*----------------------------------------------------------------------------
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;
}