problema creazione file SD da funzione sterna

Ciao a tutti,

Sto scrivendo un programma ma non riesco a risolvere un problema: Devo creare un file in una funzione esterna. Il file ha un nome che decido nel programma, all'interno del loop. Il file, però, non viene creato.
Ecco la funzione esterna:

void FUNZIONE(char  nome, const RtcDateTime& dt) 

// il primo parametro viene passato dal loop ed è "Parola"
// il secondo parametro serve per passare alla funzione le coordinate temporali che sono
// parte di ciò che deve essere rielaborato e scritto nel file.
{
  
  char datestring[20];
  char nome_mese_anno[20];

  sprintf(nome_mese_anno,"%s_%02u-%02u.csv",nome,dt.Month(),dt.Year());


// il file viene creato se sostituiscola riga qui sopra con sprintf(nome_mese_anno,"%02u-%02u.csv",dt.Month(),dt.Year());

  Serial.println(nome_mese_anno);

  File dataFile = SD.open(nome_mese_anno, FILE_WRITE ); 


// se al posto di nome_mese_anno, scrivessi direttamente "nomefile.txt",  il file verrebbe creato.

  dataFile.close();


// qui ci sarebbero le varie righe di codice che scrivono il file


// di seguito eseguo un controllo che restituisce su monitor seriale "IL FILE NON PUO' ESSERE APERTO" 
senza dovere necessariamente estrarre la SD.
  if(!(dataFile=SD.open(nome_mese_anno,FILE_READ))) Serial.println("IL FILE NON PUO' ESSERE APERTO");
dataFile.close();

}

Avete idee?

propifol:

void FUNZIONE(char  nome, const RtcDateTime& dt) 

// il primo parametro viene passato dal loop ed è "Parola"

Veramente tu hai dichiarto che passi UN singolo e SOLO carattere nel parametro "nome" (char nome) e quindi l'unica cosa di "Parola" che ricevi è la lettera 'P' ... magari questo ti crea dei problemi ... ::slight_smile:

Guglielmo

magari non riceve nemmeno quello, dato che viene passato un puntatore a carattere, non un carattere, che forse (non ho voglia adesso di controllare) viene castato automaticamente a char, essendo sia i puntatori che i char degli interi (sì, lo so, diversamente lunghi)
alla fine quello che vuole fare non è difficile, basta ricordarsi che la sd.open() con argomento write "crea" un file precedentemente inesistente, sempre leggere il reference prima di cominciare a scrivere badilate di codice..........

gpb01:
Veramente tu hai dichiarto che passi UN singolo e SOLO carattere nel parametro "nome" (char nome) e quindi l'unica cosa di "Parola" che ricevi è la lettera 'P' ... magari questo ti crea dei problemi ... ::slight_smile:

Guglielmo

Grazie mille per la risposta: Ho corretto l'errore sostituendo

nome[]

a

nome

e ora "Parola" viene passata correttamente alla funzione esterna. Il file, però non viene creato. Allego video.

Dwm 2018-12-09 21-56-54-01.zip (170 KB)

Standardoil:
basta ricordarsi che la sd.open() con argomento write "crea" un file precedentemente inesistente

Grazie mille per la risposta! Ho rimediato al problema del passaggio della variabile ma non riesco comunque a creare un file (vedi messaggio precedente).

Ad ogni modo, per completezza e chiarezza, pubblico il codice modificato (anche se in minima parte):

void SDprintDateTime(char  nome[], const RtcDateTime& dt)
{ 
  char datestring[20];
  char nome_mese_anno[20];
  sprintf(nome_mese_anno,"%s%02u%02u.csv",nome,dt.Month(),dt.Year()-2000);
  Serial.println(nome_mese_anno);
  File dataFile = SD.open(nome_mese_anno, FILE_WRITE ); 
  snprintf_P(datestring,
             countof(datestring),
             PSTR("%02u;%02u;%04u;%02u;%02u;%02u"),
             dt.Day(),
             dt.Month(),
             dt.Year(),
             dt.Hour(),
             dt.Minute(),
             dt.Second() );
  dataFile.println(datestring);
  dataFile.close();

  if(!(dataFile=SD.open(nome_mese_anno,FILE_READ))) Serial.println("IL FILE NON PUO' ESSERE APERTO");
dataFile.close();
}
[code\]

se non ho contato male il filename diventa una cosa del genere:
"parola_02-1981.csv"
ovvero la stringa parola, un underscore, il mese con almeno 2 cifre, un trattino, l'anno con almeno 2 cifre, puntociessevi
sei andato a leggere il reference della libreria SD?
edit, avevo letto male, l'anno con almeno 2 cifre fa solo 2 cifre
ma il concetto non cambia di molto

Standardoil:
se non ho contato male il filename diventa una cosa del genere:
"parola_02-1981.csv"
ovvero la stringa parola, un underscore, il mese con almeno 2 cifre, un trattino, l'anno con almeno 2 cifre, puntociessevi
sei andato a leggere il reference della libreria SD?
edit, avevo letto male, l'anno con almeno 2 cifre fa solo 2 cifre
ma il concetto non cambia di molto

Non so se ho capito bene, ho letto da qui (SD - Arduino Reference): quindi non posso nominare i miei file usando più di 8+3 (estensione) caratteri?
purtroppo io ho bisogno di nomi più lunghi di quelli permessi. Ho letto che c'è una libreria alternativa (SdFat with Long File Names - smaller than SD.h with 8.3 names - Storage - Arduino Forum): La consigliate? C'è un modo alternativo?

mai usata, purtroppo
ma mi dicono che non va male

Ok, ho provato a sostituire

Pa

a

Parola

e funziona tutto perfettamente. Forse l'avevo già fatto oggi ma non avevo messo [] dopo nome.

Insomma, grazie mille... siete stati velocissimi e efficacissimi. Spero di arrivare presto ai vostri livelli.

Comunque, per ovviare al problema del nome del file di un massimo di 8 caratteri + 3 per l'estensione, ho utilizzato il seguente codice nella funzione esterna:

 char cartelle[8];
    sprintf(cartelle,"%04u/%02u",dt.Year(),dt.Month());
    SD.mkdir(cartelle) ;

In pratica, le informazioni di cui avevo bisogno nel nome del file le ho "scorporate" nelle cartelle in cui questo viene salvato. Per fare questo, visto che SD.open non può creare cartelle, ho utilizzato SD.mkdir.

Il codice della funzione esterna terminato è il seguente:

void SDprintDateTime(char  nome[], const RtcDateTime& dt)
{ 
  char datestring[20];
  char nome_mese_anno[20];
  char cartelle[8];
    sprintf(cartelle,"%04u/%02u",dt.Year(),dt.Month());
    SD.mkdir(cartelle) ;
  sprintf(nome_mese_anno,"%04u/%02u/%s.csv",dt.Year(),dt.Month(),nome);
  Serial.println(nome_mese_anno);
  File dataFile = SD.open(nome_mese_anno, FILE_WRITE ); 
  snprintf_P(datestring,
             countof(datestring),
             PSTR("%02u;%02u;%04u;%02u;%02u;%02u"),
             dt.Day(),
             dt.Month(),
             dt.Year(),
             dt.Hour(),
             dt.Minute(),
             dt.Second() );
  dataFile.println(datestring);
  dataFile.close();

  if(!(dataFile=SD.open(nome_mese_anno,FILE_READ))) Serial.println("IL FILE NON PUO' ESSERE APERTO");
dataFile.close();
}

Attenzione al fatto che in SD.open va inserito l'intero indirizzo del file, comprese le cartelle eventualmente create con SD.mkdir: notare che l'indirizzo (escluso il nome del file) non conta negli 8 +3 caratteri massimi ammissibili per nominare il file.

Grazie ancora.

Bravo, te lo meriti