Pull request for i.a. sensor buffer template
Dependencies: BLE_API MPU6050 mbed nRF51822
Diff: main.cpp
- Revision:
- 10:eed92ffd0bba
- Parent:
- 9:e9d6a9758cf7
--- 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; + } + } } +