Pull request for i.a. sensor buffer template

Dependencies:   BLE_API MPU6050 mbed nRF51822

MeasurementBufferTemplate.h

Committer:
JustinAtAlten
Date:
2018-11-15
Revision:
11:8c38e284e9f7
Parent:
10:eed92ffd0bba

File content as of revision 11:8c38e284e9f7:

#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 */