Pull request for i.a. sensor buffer template

Dependencies:   BLE_API MPU6050 mbed nRF51822

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;
+		}
+	}
 }
 
+