#include "FS.h"
#include <LittleFS.h>
/* You only need to format LittleFS the first time you run a
test or else use the LITTLEFS plugin to create a partition
https://github.com/lorol/arduino-esp32littlefs-plugin
If you test two partitions, you need to use a custom
partition.csv file, see in the sketch folder */
#define FORMAT_LITTLEFS_IF_FAILED true
uint32_t count = 0;
uint16_t line = 0;
uint16_t newline = 2;
uint32_t stamp = 0;
float avg = 0.0;
bool begin = true;
char output [4096];
char buffer [4096];
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\r\n", dirname);
File root = fs.open(dirname);
if (!root) {
Serial.println("- failed to open directory");
return;
}
if (!root.isDirectory()) {
Serial.println(" - not a directory");
return;
}
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels) {
listDir(fs, file.path(), levels - 1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print("\tSIZE: ");
Serial.println(file.size());
printf("address = %p\n", file);
}
file = root.openNextFile();
}
}
void memCopyRead() {
size_t sz = 0;
char buff [4096];
char * fpn;
char * bptr;
bptr = buffer;
char thisline [32];
float flt = 0.0;
printf("FreeHeap variables loaded: %lu\n", ESP.getFreeHeap());
uint32_t start = micros();
FILE * fptr = fopen("/littlefs/01032025.csv", "r");
if (fptr == NULL) {
Serial.println("Not here");
return;
}
else {
Serial.println("Got somethin'");
Serial.printf("FILE Stream address: %p (from LittleFS)\n", fptr);
}
fseek(fptr, 0, SEEK_END);
sz = ftell(fptr);
//reset(fptr);
fseek(fptr, 0, SEEK_SET);
printf("Size: %lu bytes\n", sz);
//char* buffer = (char*) malloc(sz + 1024);
memcpy(&bptr, fptr, sz);
bptr[sz + 1] = '\0';
printf("Ptr* to 'buffer' address: %p (Copy to...)\n", bptr);
Serial.println("memcpy() result...");
Serial.print(bptr);//Will crash the Heap at this print unless you do something else
//before processing start @line 113
//i.e. If you comment out lines 92 & 93 the Heap will surely CRASH! Question: WHY?
start = micros();
fread(buff, 1, sz, fptr);//This code only here by accident. Was sparring off
buff[sz] = '\0';//C functions memcpy() against fread()
fclose(fptr);
printf("fread() in %lu µs\n", micros() - start);
Serial.println("fread() result...");
Serial.print(buff);
////////////////////////////////////////////////////////////
/*
Size: 2891 bytes
Ptr to 'buffer' address: 0x3ffb2330 (Copy to...)////Line 86 OK then BOOM!
CORRUPT HEAP: Bad head at 0x3ffb2328. Expected 0xabba1234 got 0x00000001
assert failed: 0x4008cd6f <cached disabled>:279 (<cached disabled>)
Backtrace: 0x400823c9:0x3ffb1fe0 0x400884c9:0x3ffb2000 0x4008e066:0x3ffb2020
0x4008cd6f:0x3ffb2150 0x4008351b:0x3ffb2170 0x4008e0b1:0x3ffb2190
0x400852cb:0x3ffb21b0 0x4008532f:0x3ffb21d0 0x400d1b6b:0x3ffb21f0
0x400d1ff5:0x3ffb2250 0x400d4e10:0x00000000 |<-CORRUPTED
*/
start = micros();
fpn = strtok (bptr, "\n");//discard header row
fpn = strtok (NULL, ",");//get first timestamp
while (fpn != NULL)
{
if (begin) {
stamp = atoll(fpn) / 1000; //parse first timestamp
fpn = strtok (NULL, ",");//get first float
flt = atof(fpn);
avg += flt;
sprintf(output, "0 time,temp\n1 %lu000,%.2f\n", stamp, flt);
line ++;
begin = false;
}
fpn = strtok (NULL, ",");// move on to float, could be first or any row
flt = atof(fpn);
avg += flt;
if (++line % 6 == 0) {
stamp += 3600;
sprintf(thisline, "%d %lu000,%.2f\n", newline++, stamp, avg / 6.0);
strcat(output, thisline);
thisline[0] = 0;
avg = 0.0;
}
}
strcat(output, "\n");
printf("\nProcessed in %lu µs\n", micros() - start);
printf("FreeHeap at function exit: %lu\n", ESP.getFreeHeap());
//count ++;
//if (count == 7) {
Serial.print(output);
// count = 0;
//}
//fclose(fptr);
}
void writeFile(fs::FS & fs, const char * path, const char * message) {
Serial.printf("\nWriting file: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file) {
Serial.println("- failed to open file for writing");
return;
}
if (file.print(message)) {
Serial.println("- file written");
Serial.printf("address = %p\n", file);
} else {
Serial.println("- write failed");
}
file.close();
}
const char CSV_FILE[] = R"rawliteral(
time,temp
1740787200000,20.42
1740787800000,19.07
1740788400000,19.49
1740789000000,20.73
1740789600000,20.58
1740790200000,20.30
1740790800000,21.72
1740791400000,20.44
1740792000000,21.78
1740792600000,19.23
1740793200000,20.09
1740793800000,21.40
1740794400000,19.65
1740795000000,20.92
1740795600000,21.42
1740796200000,19.87
1740796800000,21.03
1740797400000,20.27
1740798000000,21.29
1740798600000,19.40
1740799200000,20.12
1740799800000,19.03
1740800400000,20.69
1740801000000,19.09
1740801600000,21.57
1740802200000,20.60
1740802800000,19.33
1740803400000,19.99
1740804000000,19.78
1740804600000,20.16
1740805200000,21.35
1740805800000,19.97
1740806400000,19.26
1740807000000,21.12
1740807600000,19.67
1740808200000,20.10
1740808800000,19.33
1740809400000,19.79
1740810000000,19.49
1740810600000,21.79
1740811200000,19.21
1740811800000,19.67
1740812400000,21.72
1740813000000,20.93
1740813600000,19.36
1740814200000,20.85
1740814800000,21.45
1740815400000,20.28
1740816000000,19.91
1740816600000,21.94
1740817200000,20.57
1740817800000,20.01
1740818400000,19.53
1740819000000,21.08
1740819600000,21.44
1740820200000,21.68
1740820800000,21.90
1740821400000,19.24
1740822000000,21.96
1740822600000,19.30
1740823200000,20.03
1740823800000,19.22
1740824400000,20.66
1740825000000,21.49
1740825600000,21.24
1740826200000,20.01
1740826800000,21.53
1740827400000,20.77
1740828000000,20.08
1740828600000,21.28
1740829200000,20.33
1740829800000,21.98
1740830400000,20.81
1740831000000,21.35
1740831600000,19.13
1740832200000,20.65
1740832800000,21.14
1740833400000,21.63
1740834000000,19.36
1740834600000,20.25
1740835200000,21.69
1740835800000,19.15
1740836400000,19.94
1740837000000,20.29
1740837600000,19.01
1740838200000,19.17
1740838800000,19.95
1740839400000,20.05
1740840000000,20.04
1740840600000,19.51
1740841200000,20.98
1740841800000,21.88
1740842400000,19.23
1740843000000,19.05
1740843600000,19.82
1740844200000,21.52
1740844800000,21.66
1740845400000,19.16
1740846000000,21.37
1740846600000,19.38
1740847200000,20.44
1740847800000,21.01
1740848400000,21.97
1740849000000,19.71
1740849600000,20.28
1740850200000,20.37
1740850800000,20.58
1740851400000,21.77
1740852000000,21.97
1740852600000,21.94
1740853200000,21.04
1740853800000,21.09
1740854400000,20.31
1740855000000,21.45
1740855600000,19.75
1740856200000,20.35
1740856800000,19.98
1740857400000,20.42
1740858000000,20.99
1740858600000,19.68
1740859200000,21.12
1740859800000,19.60
1740860400000,20.57
1740861000000,21.94
1740861600000,21.08
1740862200000,21.95
1740862800000,20.68
1740863400000,20.13
1740864000000,20.30
1740864600000,20.06
1740865200000,20.62
1740865800000,20.42
1740866400000,21.65
1740867000000,19.82
1740867600000,19.52
1740868200000,19.67
1740868800000,19.21
1740869400000,20.95
1740870000000,20.12
1740870600000,20.71
1740871200000,20.01
1740871800000,21.90
1740872400000,21.31
1740873000000,19.38
)rawliteral";
void setup() {
Serial.begin(115200);
if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) {
Serial.println("LittleFS Mount Failed");
return;
}
//writeFile(LittleFS, "/01032025.csv", CSV_FILE);
//listDir(LittleFS, "/", 0);
//printf("\nFreeHeap: %lu\n", ESP.getFreeHeap());
//memCopyRead();
//delay(2000);
//printf("\nFreeHeap: %lu\n", ESP.getFreeHeap());
}
void loop() {
while(Serial.available()){
char inchar = Serial.read();
if (inchar == 'w') writeFile(LittleFS, "/01032025.csv", CSV_FILE);
if (inchar == 'l') listDir(LittleFS, "/", 0);
if (inchar == 'm') {
//printf("FreeHeap before function: %lu\n", ESP.getFreeHeap());
//for (uint16_t i = 0; i < 7; i ++) {
memCopyRead();
}
}
}
//delay(1);
//}