ESP32 SPIFFS, Copercini, Add and Find integers in Flash

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby rodmcm » Fri Sep 15, 2017 6:05 am

I include below a variation of copercini's library, eliminating the print statements within the subroutines and using a boolean return to indicate completeness.

I have also added in two crude subroutines to add and find integers in a comma deliminated file. A position integer is linked to the value saved and a 'C' is added to the start of the position string so that it is easy to locate. While crude the add and return subroutines act like a random access storage. unfortunately the file has to be scanned through until the position is found ( or not). As I said, crude, but it works!

#include <SPIFFS.h>

// This variation is based on the work of copercini

//List Directories
// Example:Spiffs_List_Dir(SPIFFS, "/", 0);
// Lists down to number of levels required
//==================================================================
void Spiffs_List_Dir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\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) {
Spiffs_List_Dir(fs, file.name(), levels - 1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}

// Create Directory
// Example: bool y= Spiffs_Create_Dir(SPIFFS, "/mydir");
//================================================
bool Spiffs_Create_Dir(fs::FS &fs, const char * path)
{
bool x;
if (fs.mkdir(path))
{
x=true;
} else {
x=false;
}
return x;
}
// Remove Directory
// Example: bool y= Spiffs_Remove_Dir(SPIFFS, "/mydir")
//================================================
bool Spiffs_Remove_Dir(fs::FS &fs, const char * path) {
bool x;
if (fs.rmdir(path)) {
x=true;
} else {
x=false;
}
return x;
}

// Print a File from a directory
//Example: bool y=Spriffs_Print_File(SPIFFS, "/hello.txt");
//=================================================
bool Spiffs_Print_File(fs::FS &fs, const char * path) {
bool x;
File file = fs.open(path);
if (!file) {
x=false;
return x;
}
while (file.available()) {
Serial.write(file.read());
}
}

// create a File
// Example:bool y= Spiffs_Create_File(SPIFFS, "/hello.txt");
//===============================================================
bool Spiffs_Create_File(fs::FS &fs, const char * path)
{
bool x;
File file = fs.open(path, FILE_WRITE);
if (!file) {
x= false;
return x;
}
}



// Write text to a file in a directory
// Example:bool y= Spiffs_Write_File(SPIFFS, "/hello.txt", "Hello ");
//===============================================================
bool Spiffs_Write_File(fs::FS &fs, const char * path, const char * message)
{
bool x;
File file = fs.open(path, FILE_WRITE);
if (!file) {
x= false;
return x;
}
if (file.print(message)) {
x= true;
} else {
x=false;
}
return x;
}


// Append information to existing file in a directory
// Example: bool y=Spiffs_Append_File(SPIFFS, "/hello.txt", "World!\n");
//===============================================================
bool Spiffs_Append_File(fs::FS &fs, const char * path, const char * message) {
bool x;
File file = fs.open(path, FILE_APPEND);
if (!file) {
x= false;
return x;
}
if (file.print(message)) {
x=true;
} else {
x=false;
}
return x;
}


// Rename a directory
// Example: bool y=Spiffs_Rename_File(SPIFFS, "/hello.txt", "/foo.txt");
//=================================================================
bool Spiffs_Rename_File(fs::FS &fs, const char * path1, const char * path2) {
bool x;
if (fs.rename(path1, path2)) {
x = true;
} else {
x=false;
}
return x;
}

// Delete a directory
// Example: bool y= Spiffs_Delete_File(SPIFFS, "/foo.txt");
//=================================================================
bool Spiffs_Delete_File(fs::FS &fs, const char * path) {
bool x;
if (fs.remove(path)) {
x=true;
} else {
x=false;
}
return x;
}

// Write an Integer to a comma deliminated file with a position indicator.
// Add 'C' to the start of the position indicator so that it can be easily found
// Almost simulates random access!
// Example : Spiffs_Add_Int_Posn(SPIFFS,"/Data.csv",10,1234);
//==========================================================================
void Spiffs_Add_Int_Posn (fs::FS &fs, const char * path,int posn, unsigned int x)
{
String comma = ",";
File file = fs.open(path, FILE_APPEND); // opens file ready for append
String No = 'C'+String(posn)+','+String(x)+',';
file.print(No);
}

//Find the integer associated with a known position identifier in the comma deliminated file
//Example :int z=Spiffs_Return_Int_Posn(SPIFFS, "/Data.csv",3);
//==========================================================================
int Spiffs_Return_Int_Posn(fs::FS &fs, const char * path,int posn)
{
File file = fs.open(path);
while (file.available())
{
if (file.read()=='C') // finds count header
{
if (file.parseInt()==posn) // checks position against that required
{
return file.parseInt(); // returns the value.
}
}
}
return 0;
}

//=================================================================
// Main Program to Test Features
//================================================================
void setup() {
bool y;
Serial.begin(115200);
SPIFFS.begin();

// general add and substract directories and files
Serial.println("List Directories");
Spiffs_List_Dir(SPIFFS, "/", 0);
Serial.println("Create a directory '/mydir'");
y= Spiffs_Create_Dir(SPIFFS, "/mydir");
Serial.println("Create a file '/Hello.txt' with the String 'Hello' ");
y=Spiffs_Write_File(SPIFFS, "/hello.txt", "Hello ");
Serial.println("List Directories");
Spiffs_List_Dir(SPIFFS, "/", 0);
Serial.println("Remove directory '/mydir'");
y=Spiffs_Remove_Dir(SPIFFS, "/mydir");
Serial.println("List Directories");
Spiffs_List_Dir(SPIFFS, "/", 0);
Serial.println("Add 'World' to /hello.txt");
y= Spiffs_Append_File(SPIFFS, "/hello.txt", "World!\n");
Serial.println("Print '/hello.txt'");
y= Spiffs_Print_File(SPIFFS, "/hello.txt");
Serial.print("Delete a fictious file f23.txt: Y=1 or N=0 ");
y=Spiffs_Delete_File(SPIFFS, "/f23.txt"); // Will not remove if file doesn't exist
Serial.println(y);
Serial.println("Rename '/hello.txt' to '/f00.txt'");
y=Spiffs_Rename_File(SPIFFS, "/hello.txt", "/f00.txt");
Serial.println("Print '/f00.txt'");
y= Spiffs_Print_File(SPIFFS, "/f00.txt");
Serial.println("List the directories");
Spiffs_List_Dir(SPIFFS, "/", 0);


// test for integer in and out
y= Spiffs_Create_File(SPIFFS, "/Data1.csv");

for (int i=1;i<100;i++)
{
Spiffs_Add_Int_Posn (SPIFFS,"/Data1.csv",i,i*10);
}
Serial.println("Printing Data1.csv :");
y=Spiffs_Print_File(SPIFFS, "/Data1.csv");
Serial.println("");
Serial.println("Find value associated with posn 27 in Data1.csv :");
int z=Spiffs_Return_Int_Posn(SPIFFS, "/Data1.csv",27); // find integer with 27 as the locator
Serial.println();
Serial.print("Found Value :");
Serial.println(z);
Serial.println("List the directories");
Spiffs_List_Dir(SPIFFS, "/", 0);

SPIFFS.end();
}

void loop() {

}

tele_player
Posts: 90
Joined: Sun Jul 02, 2017 3:38 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby tele_player » Fri Sep 15, 2017 7:37 am

There is a button here to easily insert code tags, so your code is readable.

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby rodmcm » Fri Sep 15, 2017 10:55 am

Okay... Are there instructions to use please

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby rodmcm » Fri Sep 15, 2017 11:14 am

Found it

here is a second version using the same crude way to add and retrieve floats

Code: Select all

#include <SPIFFS.h>

// This variation is based on the work of copercini

//List Directories
// Example:Spiffs_List_Dir(SPIFFS, "/", 0);
// Lists down to number of levels required
//==================================================================
void Spiffs_List_Dir(fs::FS &fs, const char * dirname, uint8_t levels) {
  Serial.printf("Listing directory: %s\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) {
        Spiffs_List_Dir(fs, file.name(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

// Create Directory
// Example: bool y= Spiffs_Create_Dir(SPIFFS, "/mydir");
//================================================
bool Spiffs_Create_Dir(fs::FS &fs, const char * path) 
 {
  bool x;
  if (fs.mkdir(path)) 
  {
  x=true;
  } else {
  x=false;
  }
  return x;
}
// Remove Directory
// Example: bool y= Spiffs_Remove_Dir(SPIFFS, "/mydir")
//================================================
bool Spiffs_Remove_Dir(fs::FS &fs, const char * path) {
  bool x;
  if (fs.rmdir(path)) {
     x=true;
  } else {
     x=false;
  }
 return x; 
}

// Print a File from a directory
//Example: bool y=Spriffs_Print_File(SPIFFS, "/hello.txt");
//=================================================
bool Spiffs_Print_File(fs::FS &fs, const char * path) {
  bool x;
  File file = fs.open(path);
  if (!file) {
    x=false;
    return x;
  }
  while (file.available()) {
    Serial.write(file.read());
  }
}

// create a File
// Example:bool y= Spiffs_Create_File(SPIFFS, "/hello.txt");
//===============================================================
bool Spiffs_Create_File(fs::FS &fs, const char * path) 
{
  bool x;
  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    x= false;
    return x;
  }
}



// Write text to a file in a directory
// Example:bool y= Spiffs_Write_File(SPIFFS, "/hello.txt", "Hello ");
//===============================================================
bool Spiffs_Write_File(fs::FS &fs, const char * path, const char * message) 
{
  bool x;
  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    x= false;
    return x;
  }
  if (file.print(message)) {
   x= true;
  } else {
   x=false;
  }
  return x;
}


// Append information to existing file  in a directory
// Example: bool y=Spiffs_Append_File(SPIFFS, "/hello.txt", "World!\n");
//===============================================================
bool Spiffs_Append_File(fs::FS &fs, const char * path, const char * message) {
  bool x;
   File file = fs.open(path, FILE_APPEND);
  if (!file) {
    x= false;
    return x;
  }
  if (file.print(message)) {
    x=true;
  } else {
   x=false;
  }
  return x;
}


// Rename a directory
// Example: bool y=Spiffs_Rename_File(SPIFFS, "/hello.txt", "/foo.txt");
//=================================================================
bool Spiffs_Rename_File(fs::FS &fs, const char * path1, const char * path2) {
  bool x;
  if (fs.rename(path1, path2)) {
    x = true;
  } else {
    x=false;
  }
  return x;
}

// Delete a directory
// Example: bool y= Spiffs_Delete_File(SPIFFS, "/foo.txt"); 
//=================================================================
bool Spiffs_Delete_File(fs::FS &fs, const char * path) {
  bool x;
  if (fs.remove(path)) {
   x=true;
  } else {
  x=false;
  }
  return x;
}

// Write an Integer to a comma deliminated file with a position indicator.
// Add 'C' to the start of the position indicator so that it can be easily found
// Amost simulates random access
// Example : Spiffs_Add_Int_Posn(SPIFFS,"/Data.csv",10,1234); 
//==========================================================================
void Spiffs_Add_Int_Posn (fs::FS &fs, const char * path,int posn, unsigned int x)
{
   String comma = ",";
   File file = fs.open(path, FILE_APPEND);   // opens file ready for append
   String No = 'C'+String(posn)+','+String(x)+',';
   file.print(No);
}

//Find the integer associated with a known position identifier in the comma deliminated file
//Example :int z=Spiffs_Return_Int_Posn(SPIFFS, "/Data.csv",3);
//==========================================================================
int Spiffs_Return_Int_Posn(fs::FS &fs, const char * path,int posn)
{
  File file = fs.open(path); 
   while (file.available()) 
  {
    if (file.read()=='C')          // finds count header
      {
      if (file.parseInt()==posn)   // checks position against that required
        {
        return file.parseInt();    
        } 
      }
  }
    return 0;   
}

// Write an real to a comma deliminated file with a position indicator.
// Add 'C' to the start of the position indicator so that it can be easily found
// Amost simulates random access
// Example : Spiffs_Add_Real_Posn(SPIFFS,"/Data.csv",10,1234.56); 
//==========================================================================
void Spiffs_Add_Float_Posn (fs::FS &fs, const char * path,int posn, float x)
{
   String comma = ",";
   File file = fs.open(path, FILE_APPEND);   // opens file ready for append
   String No = 'C'+String(posn)+','+String(x,6)+',';   /// 6 decimal places
   file.print(No);
}

//Find the float associated with a known position identifier in the comma deliminated file
//Example :float z=Spiffs_Return_Int_Posn(SPIFFS, "/Data.csv",3);
//==========================================================================
float Spiffs_Return_Float_Posn(fs::FS &fs, const char * path,int posn)
{
  File file = fs.open(path); 
   while (file.available()) 
  {
    if (file.read()=='C')          // finds count header
      {
      if (file.parseInt()==posn)   // checks position against that required
        {
        int InByte;
        String message;
        InByte=file.read();  // moves to next location, which is a ',' 
        do
        {
         InByte=file.read();
         if (InByte !=',') message=message+char(InByte);
        }
        while ((InByte!=',')&&file.available());
        return message.toFloat();    
        } 
      }
  }
    return 0;   
}


//=================================================================
// Main Program to Test Features
//================================================================
void setup() {
  bool y;
  Serial.begin(115200);
  SPIFFS.begin(); 

// general add and substract directories and files
  Serial.println("List Directories");
  Spiffs_List_Dir(SPIFFS, "/", 0);
  Serial.println("Create a directory '/mydir'");
  y= Spiffs_Create_Dir(SPIFFS, "/mydir");
  Serial.println("Create a file '/Hello.txt' with the String 'Hello' ");
  y=Spiffs_Write_File(SPIFFS, "/hello.txt", "Hello ");
  Serial.println("List Directories");
  Spiffs_List_Dir(SPIFFS, "/", 0);
  Serial.println("Remove directory '/mydir'"); 
  y=Spiffs_Remove_Dir(SPIFFS, "/mydir");
  Serial.println("List Directories");
  Spiffs_List_Dir(SPIFFS, "/", 0);
  Serial.println("Add 'World' to /hello.txt");
  y= Spiffs_Append_File(SPIFFS, "/hello.txt", "World!\n");
  Serial.println("Print '/hello.txt'");
  y= Spiffs_Print_File(SPIFFS, "/hello.txt");
  Serial.print("Delete a fictious file f23.txt: Y=1 or N=0 ");
  y=Spiffs_Delete_File(SPIFFS, "/f23.txt");    // Will not remove if file doesn't exist
  Serial.println(y);
  Serial.println("Rename '/hello.txt' to '/f00.txt'");
  y=Spiffs_Rename_File(SPIFFS, "/hello.txt", "/f00.txt");
  Serial.println("Print '/f00.txt'");
  y= Spiffs_Print_File(SPIFFS, "/f00.txt");
  Serial.println("List the directories");
  Spiffs_List_Dir(SPIFFS, "/", 0);

  
// test for integer in and out 
  y= Spiffs_Create_File(SPIFFS, "/Data1.csv"); 

  for (int i=1;i<100;i++)
    {
    Spiffs_Add_Int_Posn (SPIFFS,"/Data1.csv",i,i*10); 
    }
  Serial.println("Printing Data1.csv :");
   y=Spiffs_Print_File(SPIFFS, "/Data1.csv");
   Serial.println("");
   Serial.println("Find value associated with posn 27 in Data1.csv :");
  int j=Spiffs_Return_Int_Posn(SPIFFS, "/Data1.csv",27);   // find integer with 27 as the locator
  Serial.println();
  Serial.print("Found Value  :");Serial.println(j);
  
// test for float in and out 
  y= Spiffs_Create_File(SPIFFS, "/Data2.csv"); 
  for (int i=1;i<10;i++)
    {
    Spiffs_Add_Float_Posn (SPIFFS,"/Data2.csv",i,i*10.23); 
    }
  Serial.println("Printing Data2.csv :");
  y=Spiffs_Print_File(SPIFFS, "/Data2.csv");
  Serial.println("");
  Serial.println("Find value associated with posn 4 in Data2.csv :");
  float z=Spiffs_Return_Float_Posn(SPIFFS, "/Data2.csv",4);   // find float with 4 as the locator
  Serial.println();
  Serial.print("Found Value  :"); Serial.println(z,6);

SPIFFS.end();
}

void loop() {

}

tele_player
Posts: 90
Joined: Sun Jul 02, 2017 3:38 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby tele_player » Fri Sep 15, 2017 11:05 pm

Now I'm curious - when would this CSV integer stuff be useful?

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby rodmcm » Sat Sep 16, 2017 12:51 am

Downloading to Excel mainly
The CSV also allows easy use of parseInt() and definition of the length of the data
If you do a search on SD cards one of the most usual application is data logging, so integers and floats from sensors
You can of course write the data sequentially without the posn, but if the information misses a beat then you don't know
This method also allows easy read back to an array

tele_player
Posts: 90
Joined: Sun Jul 02, 2017 3:38 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby tele_player » Sat Sep 16, 2017 3:40 am

I understand CSV, but the common way CSV is used is line-oriented, with a defined structure. Fields are positional, so no tagging of data type is necessary.

rodmcm
Posts: 65
Joined: Sat Sep 02, 2017 3:31 am

Re: ESP32 SPIFFS, Copercini, Add and Find integers in Flash

Postby rodmcm » Mon Sep 18, 2017 6:59 am

Yes I suppose this is a bit literal, ie variables separated by a comma. :D

Who is online

Users browsing this forum: No registered users and 120 guests