From 4314b6864375650f57e2c380e9337524033bd37e Mon Sep 17 00:00:00 2001 From: Joe Finney Date: Wed, 23 Sep 2015 22:15:44 +0100 Subject: [PATCH] microbit: First implementation of Temperature Service --- inc/MicroBit.h | 2 + inc/MicroBitCompass.h | 12 +++++ inc/MicroBitConfig.h | 6 +++ inc/MicroBitTemperatureService.h | 45 ++++++++++++++++ source/CMakeLists.txt | 1 + source/MicroBit.cpp | 4 ++ source/MicroBitCompass.cpp | 25 +++++++++ source/ble-services/MicroBitIOPinService.cpp | 6 +-- .../MicroBitTemperatureService.cpp | 54 +++++++++++++++++++ 9 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 inc/MicroBitTemperatureService.h create mode 100644 source/ble-services/MicroBitTemperatureService.cpp diff --git a/inc/MicroBit.h b/inc/MicroBit.h index d8af98b..ba061e0 100644 --- a/inc/MicroBit.h +++ b/inc/MicroBit.h @@ -40,6 +40,7 @@ #include "MicroBitMagnetometerService.h" #include "MicroBitButtonService.h" #include "MicroBitIOPinService.h" +#include "MicroBitTemperatureService.h" #include "ExternalEvents.h" // MicroBit::flags values @@ -117,6 +118,7 @@ class MicroBit MicroBitMagnetometerService *ble_magnetometer_service; MicroBitButtonService *ble_button_service; MicroBitIOPinService *ble_io_pin_service; + MicroBitTemperatureService *ble_temperature_service; /** * Constructor. diff --git a/inc/MicroBitCompass.h b/inc/MicroBitCompass.h index b89e0e9..52a0cef 100644 --- a/inc/MicroBitCompass.h +++ b/inc/MicroBitCompass.h @@ -36,6 +36,8 @@ #define MAG_CTRL_REG1 0x10 #define MAG_CTRL_REG2 0x11 +#define MICROBIT_COMPASS_TEMPERATURE_SENSE_PERIOD 1000 + /** * Configuration options */ @@ -56,6 +58,7 @@ extern const MAG3110SampleRateConfig MAG3110SampleRate[]; #define MICROBIT_COMPASS_EVT_CAL_START 2 #define MICROBIT_COMPASS_EVT_CAL_END 3 #define MICROBIT_COMPASS_EVT_DATA_UPDATE 4 +#define MICROBIT_COMPASS_EVT_TEMPERATURE_UPDATE 5 /* * Status Bits @@ -77,6 +80,7 @@ struct CompassSample int16_t x; int16_t y; int16_t z; + int16_t temperature; CompassSample() { @@ -102,6 +106,8 @@ class MicroBitCompass : public MicroBitComponent uint16_t address; // I2C address of the magnetmometer. uint16_t samplePeriod; // The time between samples, in millseconds. unsigned long eventStartTime; // used to store the current system clock when async calibration has started + unsigned long temperatureSampleTime; // used to store the current system clock when async calibration has started + uint8_t temperature; // the current die temperture of the compass chip. public: @@ -208,6 +214,12 @@ class MicroBitCompass : public MicroBitComponent */ int getZ(); + /** + * Reads the currently die temperature of the compass. + * @return The temperature, in degrees celsius. + */ + int getTemperature(); + /** * Perform the asynchronous calibration of the compass. * This will fire MICROBIT_COMPASS_EVT_CAL_START and MICROBIT_COMPASS_EVT_CAL_END when finished. diff --git a/inc/MicroBitConfig.h b/inc/MicroBitConfig.h index 686f3d2..c919598 100644 --- a/inc/MicroBitConfig.h +++ b/inc/MicroBitConfig.h @@ -187,6 +187,12 @@ #define MICROBIT_BLE_IO_PIN_SERVICE 1 #endif +// This enables live access to the die temperature sensors on the micro:bit. +// Set '1' to enable. +#ifndef MICROBIT_BLE_TEMPERATURE_SERVICE +#define MICROBIT_BLE_TEMPERATURE_SERVICE 1 +#endif + // Defines the maximum length strong that can be written to the // display over BLE. #ifndef MICROBIT_BLE_MAXIMUM_SCROLLTEXT diff --git a/inc/MicroBitTemperatureService.h b/inc/MicroBitTemperatureService.h new file mode 100644 index 0000000..0720d3c --- /dev/null +++ b/inc/MicroBitTemperatureService.h @@ -0,0 +1,45 @@ +#ifndef MICROBIT_TEMPERATURE_SERVICE_H +#define MICROBIT_TEMPERATURE_SERVICE_H + +#include "MicroBit.h" + +// UUIDs for our service and characteristics +extern const uint8_t MicroBitTemperatureServiceUUID[]; +extern const uint8_t MicroBitTemperatureServiceDataUUID[]; + + +/** + * Class definition for a MicroBit BLE Temperture Service. + * Provides access to live temperature data via BLE. + */ +class MicroBitTemperatureService +{ + public: + + /** + * Constructor. + * Create a representation of the TempertureService + * @param _ble The instance of a BLE device that we're running on. + */ + MicroBitTemperatureService(BLEDevice &_ble); + + /** + * Temperature update callback + */ + void temperatureUpdate(MicroBitEvent e); + + private: + + // Bluetooth stack we're running on. + BLEDevice &ble; + + // memory for our 8 bit temperature characteristic. + int8_t temperatureDataCharacteristicBuffer; + + // Handles to access each characteristic when they are held by Soft Device. + GattAttribute::Handle_t temperatureDataCharacteristicHandle; +}; + + +#endif + diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 40c3713..974df59 100755 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -35,6 +35,7 @@ set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES "ble-services/MicroBitMagnetometerService.cpp" "ble-services/MicroBitButtonService.cpp" "ble-services/MicroBitIOPinService.cpp" + "ble-services/MicroBitTemperatureService.cpp" ) if (YOTTA_CFG_MICROBIT_CONFIGFILE) diff --git a/source/MicroBit.cpp b/source/MicroBit.cpp index 9971a35..7b64b54 100644 --- a/source/MicroBit.cpp +++ b/source/MicroBit.cpp @@ -137,6 +137,10 @@ void MicroBit::init() ble_io_pin_service = new MicroBitIOPinService(*ble); #endif +#if CONFIG_ENABLED(MICROBIT_BLE_TEMPERATURE_SERVICE) + ble_temperature_service = new MicroBitTemperatureService(*ble); +#endif + // Setup advertising. ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)MICROBIT_BLE_DEVICE_NAME, sizeof(MICROBIT_BLE_DEVICE_NAME)); diff --git a/source/MicroBitCompass.cpp b/source/MicroBitCompass.cpp index 2d05ae8..019904f 100644 --- a/source/MicroBitCompass.cpp +++ b/source/MicroBitCompass.cpp @@ -28,6 +28,8 @@ MicroBitCompass::MicroBitCompass(uint16_t id, uint16_t address) : average(), sam //initialise eventStartTime to 0 this->eventStartTime = 0; + this->temperatureSampleTime = 0; + this->temperature = 0; // Enable automatic reset after each sample; writeCommand(MAG_CTRL_REG2, 0xA0); @@ -183,6 +185,20 @@ void MicroBitCompass::idleTick() MicroBitEvent e(id, MICROBIT_COMPASS_EVT_DATA_UPDATE); } } + + // Update the temperature value if needed + if (temperatureSampleTime == 0 || temperatureSampleTime > ticks) + { + uint8_t data; + + readCommand(MAG_DIE_TEMP, &data, 1); + temperature = data; + + temperatureSampleTime = ticks + MICROBIT_COMPASS_TEMPERATURE_SENSE_PERIOD; + + // Indicate that a new sample is available + MicroBitEvent e(id, MICROBIT_COMPASS_EVT_TEMPERATURE_UPDATE); + } } /** @@ -294,6 +310,15 @@ int MicroBitCompass::whoAmI() return (int)data; } +/** + * Reads the currently die temperature of the compass. + * @return The temperature, in degrees celsius. + */ +int MicroBitCompass::getTemperature() +{ + return temperature; +} + /** * Perform a calibration of the compass. * This will fire MICROBIT_COMPASS_EVT_CAL_START. diff --git a/source/ble-services/MicroBitIOPinService.cpp b/source/ble-services/MicroBitIOPinService.cpp index a882204..d178641 100644 --- a/source/ble-services/MicroBitIOPinService.cpp +++ b/source/ble-services/MicroBitIOPinService.cpp @@ -248,15 +248,15 @@ const uint8_t MicroBitIOPinServiceUUID[] = { }; const uint8_t MicroBitIOPinServiceIOConfigurationUUID[] = { - 0xe9,0x5d,0x58,0x99,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + 0xe9,0x5d,0xb9,0xfe,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 }; const uint8_t MicroBitIOPinServiceADConfigurationUUID[] = { - 0xe9,0x5d,0x8d,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + 0xe9,0x5d,0x58,0x99,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 }; const uint8_t MicroBitIOPinServiceDataUUID[] = { - 0xe9,0x5d,0xc5,0x8c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + 0xe9,0x5d,0x8d,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 }; MicroBitPin * const MicroBitIOPins[] = { diff --git a/source/ble-services/MicroBitTemperatureService.cpp b/source/ble-services/MicroBitTemperatureService.cpp new file mode 100644 index 0000000..6012696 --- /dev/null +++ b/source/ble-services/MicroBitTemperatureService.cpp @@ -0,0 +1,54 @@ +/** + * Class definition for the custom MicroBit Temperature Service. + * Provides a BLE service to remotely read the state of the temperature, and configure its behaviour. + */ + +#include "MicroBit.h" +#include "ble/UUID.h" + +#include "MicroBitTemperatureService.h" + +/** + * Constructor. + * Create a representation of the TemperatureService + * @param _ble The instance of a BLE device that we're running on. + */ +MicroBitTemperatureService::MicroBitTemperatureService(BLEDevice &_ble) : + ble(_ble) +{ + // Create the data structures that represent each of our characteristics in Soft Device. + GattCharacteristic temperatureDataCharacteristic(MicroBitTemperatureServiceDataUUID, (uint8_t *)temperatureDataCharacteristicBuffer, 0, + sizeof(temperatureDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + + // Initialise our characteristic values. + temperatureDataCharacteristicBuffer = 0; + + GattCharacteristic *characteristics[] = {&temperatureDataCharacteristic}; + GattService service(MicroBitTemperatureServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); + + ble.addService(service); + + temperatureDataCharacteristicHandle = temperatureDataCharacteristic.getValueHandle(); + ble.updateCharacteristicValue(temperatureDataCharacteristicHandle, (const uint8_t *)&temperatureDataCharacteristicBuffer, sizeof(temperatureDataCharacteristicBuffer)); + + uBit.MessageBus.listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_TEMPERATURE_UPDATE, this, &MicroBitTemperatureService::temperatureUpdate, MESSAGE_BUS_LISTENER_NONBLOCKING | MESSAGE_BUS_LISTENER_URGENT); +} + +/** + * Temperature update callback + */ +void MicroBitTemperatureService::temperatureUpdate(MicroBitEvent e) +{ + temperatureDataCharacteristicBuffer = uBit.compass.getTemperature(); + ble.gattServer().notify(temperatureDataCharacteristicHandle,(uint8_t *)temperatureDataCharacteristicBuffer, sizeof(temperatureDataCharacteristicBuffer)); +} + +const uint8_t MicroBitTemperatureServiceUUID[] = { + 0xe9,0x5d,0x61,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 +}; + +const uint8_t MicroBitTemperatureServiceDataUUID[] = { + 0xe9,0x5d,0x8a,0x38,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 +}; + +