Problemi in creazione file con LittleFS su ESP8266

Buongiorno a tutti,
mi trovo con un problema curioso su uno sketch che mi fa, tra le altre cose, anche da data logger.
Ho un ESP8266 con collegato un lettore di microSD. Lo sketch riceve via rete dei dati che deve salvare in un file sulla SD e che si deve chiamare con la data corrente con l'underscore come separatore, ovvero "gg_mm_aaaa.log", file che viene creato automaticamente al primo utilizzo. Lo sketch funziona quasi sempre perfettamente, solo occasionalmente, e per tutto il giorno, non crea il file ma una struttura di directory, ovvero "/gg/mm/" e dentro ci scrive il file "aaaa.log". Ovviamente, quando poi vado a tentare di leggere il contenuto del file, lo stesso risulta inesistente.
Inizialmente avevo pensato ad un errore nella costruzione del nome, magari dovuta al fatto che alcuni giorni sono ad una cifra ed altri a due, ma non c'è una discriminante: il file 1_7_2023,log lo ha generato, al pari del 2_7_2023, poi i files dei giorni 3 e 4 luglio li ha sbagliati per riprendere regolarmente dal 5 luglio....

Di seguito le parti relative all'inizializzazione della SD e la funzione incriminata

#include <SD.h>
#define CS_PIN  D8

#include <LittleFS.h>
...

void setup(void) {
....
    // verifica se la scheda SD è presente
  if (!SD.begin(CS_PIN)) {
    Serial.println("Scheda SD non rilevata.");
  }else{
    Serial.println("Scheda SD rilevata correttamente."); 
    SD_presente = true; 
  }
  scriviSD("Sistema avviato","master.log");
.....

bool scriviSD(String Cosa, String Dove){ // Cosa è il contenuto da scrivere, Dove è il file ove scrivere
  if (SD_presente) {
  File dataFile = SD.open(Dove, FILE_WRITE);
  // Se il file si apre, prosegue
    if (dataFile) {
        dataFile.println(String(ntp_giorno) + "/" + String(ntp_mese) + "/" + String(ntp_anno) + " " + timeClient.getFormattedTime() + ":: " + Cosa);
        dataFile.close();
    }else{
      Serial.println("Apertura in scrittura del file '" + Dove + "' fallita");
      return false;
    }
  }else{
    return false;
  }
  return true;
}

Siete a conoscenza di bug di questa libreria sull'ESP8266?
Grazie

Carlo

Stai facendo confusione...

LittleFS è un tipo di filesystem per la memoria flash integrata dell'ESP8266, ma tu qui stai usando una SD quindi questa libreria è completamente inutile (ed infatti la includi, ma poi non la usi da nessuna parte).

Lo spezzone di codice che hai messo è incompleto, manca tutta la parte dove vai a generare il nome del file dove con tutta probabilità ha origine il problema che hai.
La libreria LittleFS non ha alcun bug di questo tipo.

Mmm ... hai letto il reference della libreria SD? Perché è chiaramente specificato:

The library supports FAT16 and FAT32 file systems on standard SD cards and SDHC cards. It uses short 8.3 names for files. The file names passed to the SD library functions can include paths separated by forward-slashes, /, e.g. “directory/filename.txt”. Because the working directory is always the root of the SD card, a name refers to the same file whether or not it includes a leading slash (e.g. “/file.txt” is equivalent to “file.txt”). As of version 1.0, the library supports opening multiple files.

Io passerei alla ben più completa e potente SdFat :wink:

Guglielmo

Hai ragione, la LittleFS la uso per altro.....
comunque il nome del file viene generato così

  ntp_data(timeClient.getEpochTime());
  data_testo = String(ntp_giorno) + "/" + String(ntp_mese) + "/" + String (ntp_anno) ;
...
    data_testo.replace("/","_");
    scriviSD( logtext ,data_testo+".log");

Credo che se ci fosse un problema nella creazione del nome, questo dovrebbe manifestarsi sempre, anche perché questo sketch riceve centinaia di dati da loggare e sbaglia solo occasionalmente. Sono perplesso.. comunque farò un controllo più approfondito per vedere se ci può essere qualcosa che modifica impropriamente "data_testo ", inoltre modifico la ScriviSD() in questo modo, vediamo come va

bool scriviSD(String Cosa, String Dove){ // Cosa è il contenuto da scrivere, Dove è il file ove scrivere
  if (SD_presente) {
  Dove.replace("/","_");
  File dataFile = SD.open(Dove, FILE_WRITE);
  // Se il file si apre, prosegue
    if (dataFile) {
        dataFile.println(String(ntp_giorno) + "/" + String(ntp_mese) + "/" + String(ntp_anno) + " " + timeClient.getFormattedTime() + ":: " + Cosa);
        dataFile.close();
    }else{
      Serial.println("Apertura in scrittura del file '" + Dove + "' fallita");
      scriviSD("Apertura in scrittura del file '" + Dove + "' fallita","master.log");
      return false;
    }
  }else{
    return false;
  }
  return true;
}

Grazie

@carloroma63: hai letto il mio post #3?

Guglielmo

L'ho letto adesso, però i nomi che non riesce a creare sono compatibili con il formato 8.3, come ad esempio 7_5_2023.log e, comunque, sull'ESP8266 questo limite sembra essere superato.

dir e:
 Il volume nell'unità E non ha etichetta.
 Numero di serie del volume: 8765-4321

 Directory di E:\

13/07/2022  15:13    <DIR>          VIDEO
13/07/2022  15:13    <DIR>          PHOTO
01/01/2098  10:15            41.884 1_7_2023.log
01/01/2098  00:19               749 master.log
01/01/2098  02:43            49.992 20_6_2023.log
01/01/2098  02:43            80.751 21_6_2023.log
01/01/2098  09:15           202.318 22_6_2023.log
01/01/2098  10:22           196.445 23_6_2023.log
01/01/2098  10:30            79.892 24_6_2023.log
01/01/2098  09:24            61.783 25_6_2023.log
01/01/2098  10:30           215.485 26_6_2023.log
01/01/2098  10:25           205.030 2_7_2023.log
17/03/2023  15:17    <DIR>          data
01/01/2098  10:25           557.285 27_6_2023.log
01/01/2098  10:10           112.569 28_6_2023.log
01/01/2098  10:13            84.030 29_6_2023.log
01/01/2098  09:37            74.692 30_6_2023.log
01/01/2098  11:47            39.754 3_7_2023.log
01/01/2098  00:09             5.373 1_1_1970.log
01/01/2098  09:51            57.272 4_7_2023.log
01/01/2098  00:05            39.439 5_7_2023.log
01/01/2098  00:04            36.757 6_7_2023.log
01/01/2098  00:24            69.432 7_7_2023.log
01/01/2098  10:39            54.403 8_7_2023.log
01/01/2098  00:17             3.234 12_7_2023.log
              22 File      2.268.569 byte
               3 Directory   7.471.202.304 byte disponibili

Ad ogni modo faccio tesoro della tua segnalazione e correggo il codice, non mi costa nulla.
Infine, la SdFat non l'ho provata, forse sono stato troppo pigro?

Grazie

Carlo

Si, credo che effettivamente su ESP8266 sia superato perché leggo ...

Arduino "class SD" shim wrapper

This is a simple wrapper class to replace the ancient Arduino SD.h
access method for SD cards. It calls the underlying SDFS and the latest
SdFat lib to do all the work, and is now compatible with the rest of the
ESP8266 filesystem things.

-Earle F. Philhower, III
earlephilhower@yahoo.com

... quindi usa la SdFat :grin:

Guglielmo

Comunque con tutte queste concatenazioni di stringhe fatte in questo modo, niente di più facile che se qualcosa non va a buon fine ottieni una stringa "sporca".
Questo a mio avviso è il modo "peggiore" di usare la classe String, tanta allocazione dinamica e variabili temporanee create e distrutte dietro il sipario.

Visto che hai un tempo in formato "epoch" ed una stringa più o meno di dimensione costante, io avrei usato una C string (array di char) e l'istruzione strftime() (cosa che ti consente di gestire anche lo 0 dei numeri inferiori a 10 in modo automatico).

time_t now = time(nullptr);  // time_t now = timeClient.getEpochTime(); 
struct tm timeInfo= *localtime(&now);
char data_testo[32];
strftime(data_testo, 32, "%d_%m_%Y.log", &timeInfo);

Serial.println(data_testo);

Ammetto di essere uno dei "pigri" che usa la String come eredità dalla conoscenza di altri linguaggi di programmazione.....
Farò tesoro anche di questo consiglio.

Grazie

Carlo

Come tante volte ribadito in questo forum, io non mi faccio nessun problema di sorta nell'uso di String anche con microcontrollori poco "dotati" di SRAM come Arduino Uno ad esempio, però c'è modo e modo di fare questa cosa.

Bisogna sempre tenere a mente che si parla comunque di un sistema embedded che non è dotato di un meccanismo di garbage collection.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.