Browse Source
Added auto save channel feature. On the next power cycle it will auto reload back the same channel
master
Added auto save channel feature. On the next power cycle it will auto reload back the same channel
master
Englebert
3 years ago
4 changed files with 289 additions and 3 deletions
-
4platformio.ini
-
220src/Storage.cpp
-
42src/Storage.h
-
26src/main.cpp
@ -0,0 +1,220 @@ |
|||
#include "Storage.h"
|
|||
|
|||
// REF:
|
|||
// https://github.com/pbecchi/ESP32-Sprinkler/blob/master/Eeprom_ESP.cpp
|
|||
|
|||
Storage::Storage(void) { |
|||
// Just some initialization
|
|||
} |
|||
|
|||
|
|||
bool Storage::format(void) { |
|||
if(LITTLEFS.format()) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
bool Storage::exists(String path) { |
|||
if(LITTLEFS.exists(path)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
bool Storage::begin(void) { |
|||
if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)) { |
|||
Serial.println("LITTLEFS mount failed"); |
|||
return false; |
|||
} |
|||
|
|||
// Demo and checking only
|
|||
Storage::listDir(LITTLEFS, "/", 0); |
|||
|
|||
if(Storage::exists("/DIVERSITY")) { |
|||
Serial.println(F("DIVERSITY FOUND")); |
|||
} else { |
|||
Serial.println(F("DIVERSITY NOT FOUND - Formatting now")); |
|||
Storage::format(); |
|||
Storage::writeFile(LITTLEFS, "/DIVERSITY", ""); |
|||
load_defaults = true; |
|||
} |
|||
|
|||
// Check Total storage
|
|||
Serial.print(F("Storage size: ")); |
|||
Serial.print(LITTLEFS.totalBytes()); |
|||
Serial.println(F(" Bytes")); |
|||
|
|||
Serial.print(F("Storage used: " )); |
|||
Serial.print(LITTLEFS.usedBytes()); |
|||
Serial.println(F(" Bytes")); |
|||
return true; |
|||
} |
|||
|
|||
|
|||
void Storage::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(F("- failed to open directory")); |
|||
return; |
|||
} |
|||
if(!root.isDirectory()){ |
|||
Serial.println(F(" - not a directory")); |
|||
return; |
|||
} |
|||
|
|||
File file = root.openNextFile(); |
|||
while(file){ |
|||
if(file.isDirectory()){ |
|||
Serial.print(F(" DIR : ")); |
|||
|
|||
#ifdef CONFIG_LITTLEFS_FOR_IDF_3_2
|
|||
Serial.println(file.name()); |
|||
#else
|
|||
Serial.print(file.name()); |
|||
time_t t= file.getLastWrite(); |
|||
struct tm * tmstruct = localtime(&t); |
|||
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec); |
|||
#endif
|
|||
|
|||
if(levels){ |
|||
listDir(fs, file.name(), levels -1); |
|||
} |
|||
} else { |
|||
Serial.print(F(" FILE: ")); |
|||
Serial.print(file.name()); |
|||
Serial.print(F(" SIZE: ")); |
|||
|
|||
#ifdef CONFIG_LITTLEFS_FOR_IDF_3_2
|
|||
Serial.println(file.size()); |
|||
#else
|
|||
Serial.print(file.size()); |
|||
time_t t= file.getLastWrite(); |
|||
struct tm * tmstruct = localtime(&t); |
|||
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec); |
|||
#endif
|
|||
} |
|||
file = root.openNextFile(); |
|||
} |
|||
} |
|||
|
|||
|
|||
String Storage::readFile(fs::FS &fs, String path){ |
|||
// Serial.printf("Reading file: %s\r\n", path);
|
|||
String return_str = ""; |
|||
|
|||
File file = fs.open(path, "r"); |
|||
if(!file || file.isDirectory()){ |
|||
//// Serial.println(F("- failed to open file for reading"));
|
|||
return ""; |
|||
} |
|||
|
|||
while(file.available()){ |
|||
return_str = return_str + String((char)file.read()); |
|||
} |
|||
file.close(); |
|||
|
|||
return return_str; |
|||
} |
|||
|
|||
|
|||
void Storage::appendFile(fs::FS &fs, const char * path, const char * message){ |
|||
Serial.printf("Appending to file: %s\r\n", path); |
|||
|
|||
File file = fs.open(path, FILE_APPEND); |
|||
if(!file){ |
|||
Serial.println("- failed to open file for appending"); |
|||
return; |
|||
} |
|||
if(file.print(message)){ |
|||
Serial.println("- message appended"); |
|||
} else { |
|||
Serial.println("- append failed"); |
|||
} |
|||
file.close(); |
|||
} |
|||
|
|||
|
|||
void Storage::deleteFile(fs::FS &fs, const char * path){ |
|||
Serial.printf("Deleting file: %s\r\n", path); |
|||
if(fs.remove(path)){ |
|||
Serial.println("- file deleted"); |
|||
} else { |
|||
Serial.println("- delete failed"); |
|||
} |
|||
} |
|||
|
|||
|
|||
void Storage::writeFile(fs::FS &fs, String path, String message){ |
|||
File file = fs.open(path, "w+"); |
|||
if(!file){ |
|||
return; |
|||
} |
|||
|
|||
file.println(message); |
|||
file.close(); |
|||
} |
|||
|
|||
|
|||
//void Storage::write_block(uint8_t * data, const char * path, uint32_t len){
|
|||
void Storage::write_block(const void * data, const char * path, uint32_t len){ |
|||
uint32_t i; |
|||
fs::FS &fs = LITTLEFS; |
|||
// Serial.println("write block 1");
|
|||
// Serial.print("FILE: ");
|
|||
// Serial.println(path);
|
|||
// Serial.println(ESP.getFreeHeap());
|
|||
|
|||
File file = fs.open(path, FILE_WRITE); |
|||
// Serial.println("write block 2");
|
|||
if(!file) { |
|||
Serial.println("write_block append failed"); |
|||
return; |
|||
} |
|||
// Serial.println("write block 3");
|
|||
/**
|
|||
for(i = 0; i < len; i++){ |
|||
// EEPROM.write(address+i, data[i]);
|
|||
byte b = *((unsigned char*) data + i); |
|||
Serial.print("Wrote: "); Serial.println(b); |
|||
} |
|||
**/ |
|||
file.write((byte *)&data, sizeof(len)); |
|||
// Serial.println("write block 4");
|
|||
file.close(); |
|||
} |
|||
|
|||
|
|||
void Storage::read_block(void * data, const char * path, uint32_t len){ |
|||
uint32_t i; |
|||
fs::FS &fs = LITTLEFS; |
|||
|
|||
File file = fs.open(path); |
|||
if(!file) { |
|||
Serial.println("- File not exists."); |
|||
return; |
|||
} |
|||
|
|||
// for(i = 0; i < len; i++){
|
|||
/**
|
|||
i = 0; |
|||
while(file.available()) { |
|||
// data[i] = EEPROM.read(address+i);
|
|||
// data[i++] = file.read();
|
|||
// uint8_t b = file.read()
|
|||
*((char *)data + i) = file.read(); |
|||
Serial.print("read_block: "); Serial.println(*((char *)data + i)); |
|||
i++; |
|||
} |
|||
**/ |
|||
file.read((byte *)&data, sizeof(len)); |
|||
file.close(); |
|||
} |
|||
|
|||
Storage storage; |
@ -0,0 +1,42 @@ |
|||
#ifndef _Storage_H |
|||
#define _Storage_H |
|||
|
|||
#include <Arduino.h> |
|||
#include <LITTLEFS.h> |
|||
|
|||
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2 |
|||
#include <time.h> |
|||
#endif |
|||
|
|||
/* 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 */ |
|||
|
|||
#define FORMAT_LITTLEFS_IF_FAILED true |
|||
|
|||
|
|||
class Storage { |
|||
|
|||
public: |
|||
Storage(void); |
|||
bool begin(void); |
|||
void listDir(fs::FS &fs, const char * dirname, uint8_t levels); |
|||
String readFile(fs::FS &fs, String path); |
|||
void appendFile(fs::FS &fs, const char * path, const char * message); |
|||
void deleteFile(fs::FS &fs, const char * path); |
|||
void writeFile(fs::FS &fs, String path, String message); |
|||
|
|||
// Emulate EEPROM write to LITTLEFS |
|||
// void write_block(uint8_t * data, const char * path, uint32_t len); |
|||
void write_block(const void * data, const char * path, uint32_t len); |
|||
void read_block(void * data, const char * path, uint32_t len); |
|||
|
|||
bool format(void); |
|||
bool exists(String path); |
|||
bool load_defaults = false; // Default false. Only during reset this will auto set to true |
|||
|
|||
private: |
|||
}; |
|||
|
|||
extern Storage storage; |
|||
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue