|
|
|
#include "DataLogger.h"
|
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#include <Preferences.h>
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
DataLogger DataLogger::mainLogger;
|
|
|
|
|
|
|
|
DataLogger::DataLogger()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
DataLogger::~DataLogger()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataLogger::open()
|
|
|
|
{
|
|
|
|
if(isOpen()) return;
|
|
|
|
|
|
|
|
lastLogTime = -std::numeric_limits<float>::max();
|
|
|
|
currentTime = 0.0f;
|
|
|
|
|
|
|
|
Preferences preferences;
|
|
|
|
preferences.begin("vm-log", false);
|
|
|
|
uint16_t logFileIndex = preferences.getUShort("next", 1);
|
|
|
|
preferences.putUShort("next", logFileIndex + 1);
|
|
|
|
preferences.end();
|
|
|
|
|
|
|
|
// clear existing files until we have enough free space
|
|
|
|
{
|
|
|
|
const unsigned long requiredSpace = 300000; // in bytes
|
|
|
|
unsigned long totalSpace = SPIFFS.totalBytes();
|
|
|
|
auto logFolder = SPIFFS.open("/log");
|
|
|
|
auto oldFile = logFolder.openNextFile();
|
|
|
|
while(oldFile && SPIFFS.usedBytes() + requiredSpace > totalSpace)
|
|
|
|
{
|
|
|
|
Serial.print("Deleting old log file: ");
|
|
|
|
Serial.println(oldFile.name());
|
|
|
|
|
|
|
|
SPIFFS.remove(oldFile.name());
|
|
|
|
oldFile = logFolder.openNextFile();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char fileName[32];
|
|
|
|
sprintf(fileName, "/log/L%05d.csv", logFileIndex);
|
|
|
|
|
|
|
|
file = SPIFFS.open(fileName, FILE_WRITE);
|
|
|
|
if(!isOpen()) Serial.println("DataLogger: failed to open file");
|
|
|
|
|
|
|
|
if(!file.print("time,speed,battery voltage,battery output current,temperature,altitude\n")) Serial.println("DataLogger: failed to write to file");
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataLogger::close()
|
|
|
|
{
|
|
|
|
if(!isOpen()) return;
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataLogger::log(unsigned long timeMilliseconds, const Entry& entry)
|
|
|
|
{
|
|
|
|
if(lastLogTime == -std::numeric_limits<float>::max()) lastTimeMilliseconds = timeMilliseconds;
|
|
|
|
currentTime += (float)utils::elapsed(lastTimeMilliseconds, timeMilliseconds) / 1000.0f;
|
|
|
|
lastTimeMilliseconds = timeMilliseconds;
|
|
|
|
|
|
|
|
if((lastEntry.isDifferent(entry) || currentTime >= lastLogTime + 20.0f) && currentTime >= lastLogTime + 0.2f)
|
|
|
|
{
|
|
|
|
char line[128];
|
|
|
|
sprintf(line, "%.3f,%.3f,%.3f,%.3f,%.1f,%.1f\n", currentTime, entry.speed, entry.batteryVoltage, entry.batteryOutputCurrent, entry.temperature, entry.altitude);
|
|
|
|
file.print(line);
|
|
|
|
|
|
|
|
if(currentTime >= lastFlushTime + 10.0f)
|
|
|
|
{
|
|
|
|
// we need to flush often enough, because the system is typically powered off right after arrival to destination
|
|
|
|
file.flush();
|
|
|
|
lastFlushTime = currentTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastEntry = entry;
|
|
|
|
lastLogTime = currentTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DataLogger::isOpen()
|
|
|
|
{
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* DataLogger::currentLogFileName()
|
|
|
|
{
|
|
|
|
return isOpen() ? file.name() : "";
|
|
|
|
}
|