Pull request for i.a. sensor buffer template
Dependencies: BLE_API MPU6050 mbed nRF51822
Revision 10:eed92ffd0bba, committed 2018-11-15
- Comitter:
- JustinAtAlten
- Date:
- Thu Nov 15 15:13:52 2018 +0000
- Parent:
- 9:e9d6a9758cf7
- Child:
- 11:8c38e284e9f7
- Commit message:
- added sensor value buffer template, added a temperature bulk request service, and changed how the tickers are handled (to save memory).
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AppTime.cpp Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,15 @@ +#include "AppTime.h" + +#include "mbed.h" +#include "Timer.h" + +static Timer runTime; + +void AppTime::init(){ + runTime.start(); +} + +float AppTime::getTime(){ + return runTime; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AppTime.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,11 @@ +#ifndef APPTIME_H +#define APPTIME_H + +//AppTime: because time(NULL) always returns -1! + +namespace AppTime { + extern void init(); + extern float getTime(); +}; + +#endif /* APPTIME_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IO.cpp Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,15 @@ +#include "IO.h" + +// InterruptIn button(BUTTON_PIN); +AnalogIn battery(BATTERY_PIN); +MPU6050 mpu(MPU6050_SDA, MPU6050_SCL); +// InterruptIn motion_probe(p14); +#ifdef USE_SERIAL +Serial pc(UART_TX, UART_RX); +#endif /* USE_SERIAL */ + +DigitalOut blue(LED_BLUE); +DigitalOut green(LED_GREEN); +DigitalOut red(LED_RED); + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IO.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,45 @@ +#ifndef IO_H +#define IO_H + +#include "mbed.h" +#include "MPU6050.h" + +// #define USE_SERIAL + + +//---------------// + + +#define LED_GREEN p21 +#define LED_RED p22 +#define LED_BLUE p23 +// #define BUTTON_PIN p17 +#define BATTERY_PIN p1 + +#define MPU6050_SDA p12 +#define MPU6050_SCL p13 + +#define UART_TX p9 +#define UART_RX p11 +#define UART_CTS p8 +#define UART_RTS p10 + +// extern InterruptIn button; +extern AnalogIn battery; +extern MPU6050 mpu; +#ifdef USE_SERIAL +extern Serial pc; +#endif /* USE_SERIAL */ + +extern DigitalOut blue; +extern DigitalOut green; +extern DigitalOut red; + +#ifdef USE_SERIAL +#define LOG(...) { pc.printf(__VA_ARGS__); } +#else /* USE_SERIAL */ +#define LOG(...) { } +#endif /* USE_SERIAL */ + + +#endif /* IO_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MeasurementBufferTemplate.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,125 @@ +#ifndef MEASUREMENTBUFFERTEMPLATE_H +#define MEASUREMENTBUFFERTEMPLATE_H + +#include "AppTime.h" + +#define IncrementInRange(x, range) (((x+1) >= range) ? 0 : x+1) + + +template<typename T_BufferType, unsigned int T_BufferLength, unsigned int T_ReadingsInUpdate, unsigned int T_ReadInterval, T_BufferType (*T_MeasurementFunction)()> +class MeasurementBufferTemplate { +public: + struct BulkUpdate { + uint32_t requestedTime; //intended time of first sensor-reading, specified by request + uint32_t initialTime; //provided time of first sensor-reading + uint32_t sensorReadingInterval; // time difference between sensor-readings (seconds) + uint32_t numberOfReadings; + T_BufferType readings[T_ReadingsInUpdate]; + + BulkUpdate(const time_t & requestedTime=0, const time_t & initialTime=0, const time_t & sensorReadingInterval=0) : + requestedTime(requestedTime), + initialTime(initialTime), + sensorReadingInterval(sensorReadingInterval), + numberOfReadings(0) + { + + } + }; + +public: + MeasurementBufferTemplate() : + buffer(new T_BufferType[T_BufferLength]), + indexOfNewestReading(T_BufferLength-1), + timeOfLastReading(0), + nrSensorReadingsPerformed(0) + { + + } + + virtual ~MeasurementBufferTemplate(){ + delete [] buffer; + } + + T_BufferType performMeasurement(){ + //Get data + T_BufferType measurementData = T_MeasurementFunction(); + + //Update buffer and meta-data + indexOfNewestReading = IncrementInRange(indexOfNewestReading, T_BufferLength); + timeOfLastReading = AppTime::getTime(); + buffer[indexOfNewestReading] = measurementData; + + if(nrSensorReadingsPerformed < T_BufferLength){ //doesn't matter what the value is past this point, so only increment when relevant to prevent overflow + nrSensorReadingsPerformed++; + } + + return measurementData; + } + + BulkUpdate getBulkUpdate(const time_t & requestedTime){ + if(timeOfLastReading < requestedTime){ + //no data available yet for requested time + return BulkUpdate(requestedTime); + } + + //find sensor-reading from where to start copying data + float tDiff = timeOfLastReading - (float)requestedTime; + unsigned int periodsPassed = tDiff / T_ReadInterval; + + //if request is made for data that no longer exists (i.e. it was overwritten already), then just present the oldest data we have + if(periodsPassed >= T_BufferLength){ + periodsPassed = T_BufferLength-1; + } + + //If more sensor-readings are requested than have been read: adjust request to all readings that have been read + if(periodsPassed >= nrSensorReadingsPerformed){ + periodsPassed = nrSensorReadingsPerformed-1; + } + + //set time of initial sensorReading + float timePassed = periodsPassed * T_ReadInterval; + time_t initialTime = 0; + if(timePassed > timeOfLastReading){ + //Shouldn't happen + initialTime = 0; + } else { + initialTime = timeOfLastReading - timePassed; + } + + //find the startIndex of the stored data + int startIndex = (int)indexOfNewestReading - periodsPassed; // n+1 sensor-readings read for n = periodsPassed + if(startIndex < 0){ + //count backwards + startIndex = T_BufferLength - abs(startIndex); + //startIndex should now be >= 0, because (abs(startIndex) + 1) <= T_BufferLength + } + + //copy data to BulkUpdate + BulkUpdate ret(requestedTime, initialTime, T_ReadInterval); + unsigned int readIndex = startIndex; + for(unsigned int i=0; i < T_ReadingsInUpdate; i++){ + //Copy reading + ret.readings[i] = buffer[readIndex]; + ret.numberOfReadings++; + + //increment read index + readIndex = IncrementInRange(readIndex, T_BufferLength); + + if(readIndex == IncrementInRange(indexOfNewestReading, T_BufferLength)){ + //if this iteration just read the newest temperature-sensor-reading: stop + break; + } + } + + return ret; + } + +private: + T_BufferType * buffer; + unsigned int indexOfNewestReading; + float timeOfLastReading; + uint16_t nrSensorReadingsPerformed; +}; + + +#endif /* MEASUREMENTBUFFERTEMPLATE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ReadIntervals.cpp Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,36 @@ +#include "ReadIntervals.h" +#include <algorithm> + +int ReadIntervals::temperatureSensorPeriod_timeLeft = 0; +int ReadIntervals::batteryMonitorPeriod_timeLeft = 0; + + + +void ReadIntervals::updateTimeLeft(const int & tickerSleptTime){ + temperatureSensorPeriod_timeLeft -= tickerSleptTime; + batteryMonitorPeriod_timeLeft -= tickerSleptTime; +} + +int ReadIntervals::getTickerSleepTime(){ + if(temperatureSensorPeriod_timeLeft <= 0){ + temperatureSensorPeriod_timeLeft += TemperatureSensorPeriod; + } + if(batteryMonitorPeriod_timeLeft <= 0){ + batteryMonitorPeriod_timeLeft += BatteryMonitorPeriod; + } + + int ret = temperatureSensorPeriod_timeLeft; + ret = std::min<int>(ret, batteryMonitorPeriod_timeLeft); + + ret = std::max<int>(ret, 1); //assert that ret != 0 or lower + + return ret; +} + +bool ReadIntervals::temperatureSensorPeriodPassed(){ + return (temperatureSensorPeriod_timeLeft <= 0); +} +bool ReadIntervals::batteryMonitorPeriodPassed(){ + return (batteryMonitorPeriod_timeLeft <= 0); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ReadIntervals.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,22 @@ +#ifndef READINTERVALS_H +#define READINTERVALS_H + +namespace ReadIntervals { + // // + // All time-variables here are in seconds // + // // + + const unsigned int TemperatureSensorPeriod = 1; + const unsigned int BatteryMonitorPeriod = 60; + + extern int temperatureSensorPeriod_timeLeft; + extern int batteryMonitorPeriod_timeLeft; + + extern bool temperatureSensorPeriodPassed(); + extern bool batteryMonitorPeriodPassed(); + + extern void updateTimeLeft(const int & tickerSleptTime); + extern int getTickerSleepTime(); +}; + +#endif /* READINTERVALS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Util.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,82 @@ +#ifndef UTIL_H +#define UTIL_H + +#include <string> +// #include <vector> + +template<typename T_FromType, typename T_ToType> +inline void castArray(T_FromType * fromArray, T_ToType * toArray, const unsigned int & length){ + for(unsigned int i=0; i < length; i++){ + toArray[i] = fromArray[i]; + } +} + +// inline std::vector<std::string> split(std::string receivedMessage, const char & delimiter = ' '){ +// std::vector<std::string> ret; +// size_t wordEnd = receivedMessage.find_first_of(delimiter); +// while(wordEnd != std::string::npos){ +// std::string word = receivedMessage.substr(0, wordEnd); +// if(!word.empty()){ +// ret.push_back(word); +// } +// receivedMessage = receivedMessage.substr(wordEnd+1); +// wordEnd = receivedMessage.find_first_of(delimiter); +// } +// if(!receivedMessage.empty()){ +// ret.push_back(receivedMessage); +// } + +// return ret; +// } + + +inline char digitToChar(uint8_t digit){ + return ('0' + digit); //ascii value + digit value = ascii value +} + +inline std::string floatToString(float value, int maximumNumberOfDecimals = 5){ //Temporary solution to solve logging of float values + //First make sure buffer is big enough + std::string ret; + int integersLength = 0; + int valueInt = static_cast<int>(value); + + //integer part + if(valueInt){ + integersLength = 1; + } + while(valueInt /= 10){ //assuming decimal system + integersLength++; + value /= 10.0f; + } + + for(int i=0; i < integersLength; i++){ + uint8_t digit = (uint8_t) value; + ret += digitToChar(digit); + value -= digit; + value *= 10.0f; + } + + //decimal point + ret += "."; + + //decimal part + int decimalLength = 0; + while((value != 0.0f) && (decimalLength < maximumNumberOfDecimals)){ + uint8_t digit = (uint8_t) value; + ret += digitToChar(digit); + decimalLength++; + value -= digit; + value *= 10.0f; + } + + if((decimalLength == 0) && (decimalLength < maximumNumberOfDecimals)){ + ret += "0"; + } + ret += "f"; + + return ret; +} + +#define floatToCharArray(...) floatToString(__VA_ARGS__).c_str() + +#endif /* UTIL_H */
--- a/main.cpp Tue Oct 16 22:29:07 2018 +0200 +++ b/main.cpp Thu Nov 15 15:13:52 2018 +0000 @@ -1,5 +1,5 @@ - #include "mbed.h" +#include "mbed_mem_trace.h" #include "nrf51.h" #include "nrf51_bitfields.h" #include "MPU6050.h" @@ -12,27 +12,26 @@ #include "TemperatureService.h" #include "AccelerationService.h" - -#define LOG(...) { pc.printf(__VA_ARGS__); } - -#define LED_GREEN p21 -#define LED_RED p22 -#define LED_BLUE p23 -#define BUTTON_PIN p17 -#define BATTERY_PIN p1 +#include "ReadIntervals.h" +#include "Util.h" +#include "IO.h" +#include "MeasurementBufferTemplate.h" -#define MPU6050_SDA p12 -#define MPU6050_SCL p13 +//https://os.mbed.com/handbook/SDFileSystem +// http://os.mbed.com/users/mbed_official/code/SDFileSystem/ +// needs: https://os.mbed.com/teams/mbed-official/code/FATFileSystem/pull-request/4 +// #include "SDFileSystem.h" +//https://os.mbed.com/cookbook/SD-Card-File-System -#define UART_TX p9 -#define UART_RX p11 -#define UART_CTS p8 -#define UART_RTS p10 -/* Starting sampling rate. */ +/////////////////////////////////////// +// DEFINES // +/////////////////////////////////////// + +// Starting sampling rate. #define DEFAULT_MPU_HZ (100) - +// --- Device Information --- // #define MANUFACTURER "PM @ ALTEN" #define MODELNUMBER "IoT BLE" #define SERIALNUMBER "123456" @@ -40,178 +39,271 @@ #define FIRMWAREREVISION "1.0" #define SOFTWAREREVISION "1.0" -DigitalOut blue(LED_BLUE); -DigitalOut green(LED_GREEN); -DigitalOut red(LED_RED); +///////////////////////////////////////// +// CONSTANTS // +///////////////////////////////////////// + +// --- UUIDs --- // +const char acceleration128bitUUIDlist[] = { 0x53, 0xF8, 0x0E, 0x12, 0xAD, 0xBB, 0xF1, 0x38, 0xAC, 0x07, 0xD2, 0x3D, 0xF0, 0xE2, 0x34, 0x5D }; +const UUID uuidTempBulkService("11111111-1000-2222-3333-444455556666"); +const UUID uuidTempBulkCharRead("11111111-1001-2222-3333-444455556666"); -InterruptIn button(BUTTON_PIN); -AnalogIn battery(BATTERY_PIN); -Serial pc(UART_TX, UART_RX); -MPU6050 mpu(MPU6050_SDA, MPU6050_SCL); +// --- Temperature Buffer Data --- // +const unsigned int TemperatureBufferSize = 100; +const unsigned int TemperatureBulkUpdateSize = 6; + // https://devzone.nordicsemi.com/f/nordic-q-a/519/reading-a-subset-of-data-on-a-ble-server + // characteristic data max 512 bytes + // https://github.com/pieterm/bledemo#step-8-add-callback-function-on-data-written-event + // GattWriteCallbackParams + -InterruptIn motion_probe(p14); +///////////////////////////////////////////////////// +// FUNCTION DECLARATIONS // +///////////////////////////////////////////////////// + +uint16_t readTemperature(); -int read_none_count = 0; +//////////////////////////////////////// +// TYPEDEFS // +//////////////////////////////////////// + +typedef MeasurementBufferTemplate<uint16_t, TemperatureBufferSize, TemperatureBulkUpdateSize, ReadIntervals::TemperatureSensorPeriod, readTemperature> TemperatureBuffer; -BLEDevice ble; -UARTService *uartServicePtr; +///////////////////////////////////////// +// VARIABLES // +///////////////////////////////////////// -// variables to monitor the battery voltage -volatile float batteryVoltage = 100.0f; -volatile bool batteryVoltageChanged = false; +// --- Buffers --- // +TemperatureBuffer temperatureBuffer; +TemperatureBuffer::BulkUpdate tempUpdate; -volatile bool startMeasure = false; +// --- Timing --- // +Ticker ticker; + +// --- BLE --- // +GattCharacteristic * tempBulkUpdateCharacteristic; -volatile bool bleIsConnected = false; -volatile uint8_t tick_event = 0; +// --- Flags --- // +volatile bool batteryVoltageChanged = false; +volatile bool tempUpdateFlag = false; +volatile bool startMeasure = false; + +///////////////////////////////////////// +// FUNCTIONS // +///////////////////////////////////////// + -int16_t ax, ay, az; -int16_t gx, gy, gz; +uint16_t readTemperature(){ + //read temperature (raw) + int16_t tempRaw = mpu.getTempRaw(); + // convert into 0.1 degrees Celsius + tempRaw *= 10; + tempRaw += 5210; + tempRaw /= 340; + tempRaw += 350; -//char acceleration128bitUUIDlist[] = {0x5D,0x34,0xE2,0xF0 ,0x3D,0xD2 ,0x07,0xAC ,0x38,0xF1 ,0xBB,0xAD,0x12,0x0E,0xF8,0x53}; -char acceleration128bitUUIDlist[] = { 0x53, 0xF8, 0x0E, 0x12, 0xAD, 0xBB, 0xF1, 0x38, 0xAC, 0x07, 0xD2, 0x3D, 0xF0, 0xE2, 0x34, 0x5D }; + return tempRaw; +} void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { - LOG("Connected!\n"); - bleIsConnected = true; + LOG("Connected!\n"); + // bleIsConnected = true; } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams) { - LOG("Disconnected!\n"); - LOG("Restarting the advertising process\n"); - ble.startAdvertising(); - bleIsConnected = false; + LOG("Disconnected!\n"); + LOG("Restarting the advertising process\n"); + BLE & ble = BLE::Instance(BLE::DEFAULT_INSTANCE); + ble.gap().startAdvertising(); + // bleIsConnected = false; } void tick(void) { - green = !green; - startMeasure = true; // notify the main-loop to start measuring the MPU6050 + static int tickerSleepTime=0; + blue = !blue; + + //update time + ReadIntervals::updateTimeLeft(tickerSleepTime); + + //perform actions + if(ReadIntervals::temperatureSensorPeriodPassed()){ + green = !green; + startMeasure = true; // notify the main-loop to start measuring the MPU6050 + } + if(ReadIntervals::batteryMonitorPeriodPassed()){ + red = !red; + batteryVoltageChanged = true; + } + + //prep next ticker-sleep + tickerSleepTime = ReadIntervals::getTickerSleepTime(); + ticker.attach(tick, tickerSleepTime); } -// timer callback function to measure the ADC battery level -void batteryMonitorCallback(void) -{ - float sample; - - sample = battery.read(); - /* cannot use (uart.)printf() in a ISR like this. */ - batteryVoltage = sample; - batteryVoltageChanged = true; +// void detect(void) +// { +// LOG("Button pressed\n"); +// blue = !blue; +// } + +void setAdvertisingPayload(BLE & ble){ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + (const uint8_t *)acceleration128bitUUIDlist, sizeof(acceleration128bitUUIDlist)); } -void detect(void) -{ - LOG("Button pressed\n"); - blue = !blue; +void setScanResponsePayload(BLE & ble){ + uint8_t name[] = "iot aabbccddeeff"; + Gap::AddressType_t addr_type; + Gap::Address_t address; + ble_error_t error = ble.gap().getAddress(&addr_type, address); + if(error == BLE_ERROR_NONE){ + for(int i = 5; i >= 0; i--){ + char buffer[3]; + sprintf(buffer, "%02x", address[i]); + name[4 + ((5-i)*2)] = buffer[0]; + name[4 + ((5-i)*2) + 1] = buffer[1]; + } + } + + ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, + name, sizeof(name)); } +void onDataWritten(const GattWriteCallbackParams * context) +{ + if(context->handle == tempBulkUpdateCharacteristic->getValueHandle()){ + const time_t & newSelectedTime = *(time_t*)context->data; + tempUpdate = temperatureBuffer.getBulkUpdate(newSelectedTime); + tempUpdateFlag = true; + } +} + int main(void) { - blue = 1; - green = 1; - red = 1; + ///Start global timer + AppTime::init(); + + ///Initialize led values + blue = 0; + green = 1; + red = 1; + + wait(1); - pc.baud(115200); - - wait(1); - - LOG("---- Seeed Tiny BLE ----\n"); - - - LOG("MPU6050 testConnection \n"); - bool mpu6050TestResult = mpu.testConnection(); - if(mpu6050TestResult) { - LOG("MPU6050 test passed \n"); - } else { - LOG("MPU6050 test failed \n"); - } - - Ticker ticker; - ticker.attach(tick, 5); - - Ticker batteryMonitorTicker; - batteryMonitorTicker.attach(batteryMonitorCallback, 60.0f); +#ifdef USE_SERIAL + pc.baud(115200); +#endif /* USE_SERIAL */ + + LOG("---- Seeed Tiny BLE ----\n"); + + ///Initialize MPU6050 + LOG("MPU6050 testConnection \n"); + bool mpu6050TestResult = mpu.testConnection(); + if(mpu6050TestResult) { + LOG("MPU6050 test passed \n"); + } else { + LOG("MPU6050 test failed \n"); + } + + ///Initialize temperature buffer & update + uint16_t temperature = temperatureBuffer.performMeasurement(); + tempUpdate = temperatureBuffer.getBulkUpdate(0); - button.fall(detect); + ///Initialize ticker + ticker.attach(tick, ReadIntervals::TemperatureSensorPeriod); + + // button.fall(detect); + + ///Initialize BLE + LOG("Initialising the nRF51822\n"); + BLE & ble = BLE::Instance(BLE::DEFAULT_INSTANCE); + ble.init(); + ble.gap().onDisconnection(disconnectionCallback); + ble.gap().onConnection(connectionCallback); - LOG("Initialising the nRF51822\n"); - ble.init(); - ble.gap().onDisconnection(disconnectionCallback); - ble.gap().onConnection(connectionCallback); - - uint8_t name[] = "iot aabbccddeeff"; - - Gap::AddressType_t addr_type; - Gap::Address_t address; - ble_error_t error = ble.gap().getAddress(&addr_type, address); - if (error == BLE_ERROR_NONE) { - for (int i = 5; i >= 0; i--){ - char buffer[3]; - sprintf(buffer, "%02x", address[i]); - name[4 + ((5-i)*2)] = buffer[0]; - name[4 + ((5-i)*2) + 1] = buffer[1]; - } - } - LOG("name = %s\n", name); - - /* setup advertising */ - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, - (const uint8_t *)acceleration128bitUUIDlist, sizeof(acceleration128bitUUIDlist)); - ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, - name, sizeof(name)); - - DFUService dfu(ble); - UARTService uartService(ble); - uartServicePtr = &uartService; - //uartService.retargetStdout(); - BatteryService battery(ble); - DeviceInformationService deviceInfo(ble, MANUFACTURER, MODELNUMBER, SERIALNUMBER, HARDWAREREVISION, FIRMWAREREVISION, SOFTWAREREVISION); - TemperatureService tempService(ble); - AccelerationService accelerationService(ble); + // -> Initialize BLE - custom services + tempBulkUpdateCharacteristic = new GattCharacteristic(uuidTempBulkCharRead, NULL, 1, sizeof(tempUpdate), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); + GattService tempBulkService(uuidTempBulkService, &tempBulkUpdateCharacteristic, 1); + ble.gattServer().addService(tempBulkService); + ble.gattServer().onDataWritten(onDataWritten); + + // -> Initialize BLE - advertising and scan payloads + setAdvertisingPayload(ble); + setScanResponsePayload(ble); + + // -> Initialize BLE - generic services + DFUService dfu(ble); + UARTService uartService(ble); + BatteryService batteryService(ble); + DeviceInformationService deviceInfo(ble, MANUFACTURER, MODELNUMBER, SERIALNUMBER, HARDWAREREVISION, FIRMWAREREVISION, SOFTWAREREVISION); + TemperatureService tempService(ble); + AccelerationService accelerationService(ble); + + // -> Initialize BLE - start advertising + ble.gap().setAdvertisingInterval(160); // 100ms; in multiples of 0.625ms. + ble.gap().startAdvertising(); + + tempService.updateTemperature(temperature); + + while(true) { + ble.waitForEvent(); + + // update battery level after the level is measured + if(batteryVoltageChanged == true) { + float batteryVoltage = battery.read(); + // LOG("VBat: %4.3f, ADC: %4.3f, Vadc: %4.3f\n", batteryVoltage*2.0f, batteryVoltage, batteryVoltage*3.3f); + LOG("VBat: %s, ADC: %s, Vadc: %s\n", floatToCharArray(batteryVoltage*2.0f), floatToCharArray(batteryVoltage), floatToCharArray(batteryVoltage*3.3f)); + batteryService.updateBatteryLevel((uint8_t)(batteryVoltage*100.0f)); // input is 0-1.0 of 3.3V -> *100 = percentage of 3.3V + batteryVoltageChanged = false; + } - ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ - ble.gap().startAdvertising(); - - while (true) { - ble.waitForEvent(); - - // update battery level after the level is measured - if (batteryVoltageChanged == true) { - LOG("VBat: %4.3f, ADC: %4.3f, Vadc: %4.3f\n", batteryVoltage*2.0f, batteryVoltage, batteryVoltage*3.3f); - battery.updateBatteryLevel((uint8_t)(batteryVoltage*100.0f)); // input is 0-1.0 of 3.3V -> *100 = percentage of 3.3V - batteryVoltageChanged = false; - } - else if (startMeasure == true) { - //float a[3]; - //mpu.getAccelero(a); - //LOG("Acceleration %.2f;%.2f;%.2f\n", a[0], a[1], a[2]); + if(startMeasure == true) { + //uartService.write("test\n", 5); + //float a[3]; + //mpu.getAccelero(a); + //LOG("Acceleration %.2f;%.2f;%.2f\n", a[0], a[1], a[2]); - int a[3]; - mpu.getAcceleroRaw(a); - accelerationService.addAcceleration((int16_t*)a); - //LOG("Acceleration %d;%d;%d\n", a[0], a[1], a[2]); - LOG("Acceleration 0x%x;0x%x;0x%x\n", a[0], a[1], a[2]); - - float temp = mpu.getTemp(); - LOG("Temp = %.01f\n", temp); - int16_t tempRaw = mpu.getTempRaw(); - // convert into 0.1 degrees Celsius - tempRaw *= 10; - tempRaw += 5210; - tempRaw /= 340; - tempRaw += 350; - // update BLE tmperature - tempService.updateTemperature(tempRaw); - - startMeasure = false; - } - } + ///Acceleration + //read accelerometer data + int a[3]; + mpu.getAcceleroRaw(a); + //convert to format accepted by accelerionService + int16_t a_16[3]; + castArray(a, a_16, 3); //cannot simply cast 'a' to int16_t*, memory won't move accordingly + // update BLE acceleration + accelerationService.addAcceleration(a_16); + LOG("Acceleration 0x%x;0x%x;0x%x\n", a[0], a[1], a[2]); + + ///Temperature + uint16_t temperature = temperatureBuffer.performMeasurement(); + tempService.updateTemperature(temperature); + + ///Reset measure flag + startMeasure = false; + } + + if(tempUpdateFlag){ + ble_error_t err = ble.gattServer().write(tempBulkUpdateCharacteristic->getValueHandle(), (const uint8_t*)&tempUpdate, sizeof(tempUpdate)); + LOG("err:[%d]\n", err); + LOG("rT:[%d]\n", tempUpdate.requestedTime); + LOG("iT:[%d]\n", tempUpdate.initialTime); + LOG("nR:[%d]\n", tempUpdate.numberOfReadings); + LOG("pT:[%s]\n", floatToCharArray(tempUpdate.sensorReadingInterval)); + // LOG("pT:[%f]\n", tempUpdate.sensorReadingInterval); + for(unsigned int i=0; i < tempUpdate.numberOfReadings; i++){ + LOG("%#010x\n", tempUpdate.readings[i]); + } + tempUpdateFlag = false; + } + } } +
--- a/mbed.bld Tue Oct 16 22:29:07 2018 +0200 +++ b/mbed.bld Thu Nov 15 15:13:52 2018 +0000 @@ -1,1 +1,1 @@ -https://os.mbed.com/users/mbed_official/code/mbed/builds/e95d10626187 \ No newline at end of file +https://os.mbed.com/users/mbed_official/code/mbed/builds/aa5281ff4a02 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_config.h Thu Nov 15 15:13:52 2018 +0000 @@ -0,0 +1,36 @@ +/* + * mbed SDK + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Automatically generated configuration file. +// DO NOT EDIT, content will be overwritten. + +#ifndef __MBED_CONFIG_DATA__ +#define __MBED_CONFIG_DATA__ + +// Configuration parameters +#define MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE 9600 // set by library:platform +#define MBED_CONF_PLATFORM_FORCE_NON_COPYABLE_ERROR 0 // set by library:platform +#define MBED_CONF_PLATFORM_STDIO_BAUD_RATE 115200 // set by application[*] +#define MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES 1 // set by application[*] +#define MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT 1 // set by library:platform +// Macros +#define MBED_HEAP_STATS_ENABLED 1 // defined by application +#define MBED_MEM_TRACING_ENABLED 1 // defined by application +#define MBED_STACK_STATS_ENABLED 1 // defined by application + +#endif +