Reading data from SD to recover system

Hello,

I am quite new to programing, especialy in C and C++. I am struggling to find solution to next problem. I am building system that measures force in my home project. Every measurement is stored to SD card that can be than transfered to computer for later use. System is normally powered by wall power, but in case of power loss I have to recover the data so the system can proceed from last point. Battery is not an option.

I have build struct that stores 2 values at the moment (it will have more in the future). I would like to read lasn N measurements/lines and store those measurements in separate array of the file so I can use last N measurements for moving average. Data is stored as binary. I know I could build array variable in to the struct but I feel that is waste of space and resources.

Can someone help me out?

That is my struct:

struct springDataStruct
{
  int32_t cycles;
  int32_t measurement;
}springData;

That is how I am able to read last line of the file and store it to struct.

void readSpringDataFile()
{
  springDataFile = SD.open(springDataFileName, FILE_READ);
  springDataFile.seek(springDataFile.size() - sizeof(springDataStruct));
  springDataFile.read((uint8_t *)&springData, sizeof(springData));
  springDataFile.close();
}

I could loop over last N lines with that but opening and closing file is a waste of time and I think that there is a better option out there.

If your average is calculated from the last N measurements, then you could simply load the last N measurements and re-calculate the running average on boot. Hard to give better advice since the code for averaging and saving data is missing.

So this is the code for appending to file:

void appendSpringDataFile()
{
  springDataFile = SD.open(springDataFileName, FILE_APPEND);
  springDataFile.write((uint8_t *)&springData, sizeof(springDataStruct));
  springDataFile.close();
}

I am using basic averaging:

int32_t getArrayAverage(int32_t forceTrendDataPoints)
{
  // get current average
  int32_t sum=0;
  for (int16_t i = 0; i < forceTrendDataPoints; i++)
  {
    sum = sum + forceTrend[i];
  }
  return (int32_t)sum/forceTrendDataPoints;
}

If that helps in any way.

No, I cannot see what forceTrend and forceTrendDataPoints are. Snippets are just a waste of ppl's time..

Oh sorry, I did not understand what you meant.

const int32_t forceTrendDataPoints = 100;
int32_t forceTrend[forceTrendDataPoints];
int32_t currentForceTrend;

That are my variables.

  • forceTrendDataPoints - lenght of array for moving average calculation
  • forceTrend - array of stored data
  • currentForceTrend - moving average value

You can go back multiple records:

 springDataFile.seek(springDataFile.size() - sizeof(springDataStruct) * RecordsToAverage);