Pull request for i.a. sensor buffer template

Dependencies:   BLE_API MPU6050 mbed nRF51822

Revision:
10:eed92ffd0bba
--- /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 */