#pragma once #include #include "data.h" const int mySD_CS=13; const int mySD_SCLK=14; const int mySD_MISO=2; const int mySD_MOSI=15; /* we write fixed-length CSV lines because, at some point in the future, I may need to seek "10 measurements back" or something like that; also, it's easier to read */ // 12345, 12345, 12345, 12345, 123456, 123456, 123456, 123456, 12345\n const char csvHeader[]=" secs, co2, temp, humid, pm1, pm2.5, pm4, pm10, batt\n"; const char csvFormat[]="% 5lu, % 5u, % 5.1f, % 5.1f, % 6.1f, % 6.1f, % 6.1f, % 6.1f, % 5.2f\n"; const size_t lineLength=66; class DataLog { private: File logfile; char line[100]; uint8_t linesSinceLastFlush; uint8_t flushThreshold; public: DataLog(uint8_t ft=4) : flushThreshold(ft) {} void start() { bool sdok=SD.begin(mySD_CS, mySD_MOSI, mySD_MISO, mySD_SCLK); Serial.print("# sdok: ");Serial.println(sdok); logfile = SD.open("quality.csv",FILE_WRITE); Serial.print("# file: ");Serial.println(logfile.name()); uint32_t fileSize = logfile.size(); logfile.seek(fileSize); if (fileSize == 0) { logfile.write((uint8_t*)csvHeader, lineLength); } linesSinceLastFlush=1; } void show(const SensorData *data) { snprintf( line, lineLength+1, // zero terminator! csvFormat, millis()/1000, data->co2, data->temperature, data->humidity, data->pm.mc_1p0, max(0.0f,data->pm.mc_2p5 - data->pm.mc_1p0), max(0.0f,data->pm.mc_4p0 - data->pm.mc_2p5), max(0.0f,data->pm.mc_10p0 - data->pm.mc_4p0), data->batteryVoltage ); size_t written=logfile.write((uint8_t *)line,lineLength); Serial.print("# ");Serial.write(line); Serial.print("# written: ");Serial.println(written); if (++linesSinceLastFlush > flushThreshold) { logfile.flush(); linesSinceLastFlush=0; Serial.println("# flushed"); } } };