Pull request for i.a. sensor buffer template
Dependencies: BLE_API MPU6050 mbed nRF51822
Diff: MeasurementBufferTemplate.h
- 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 */