SD - lettura file in cartella

Buonasera a tutti,
Sto smanettando un po' con la carta micro SD e sono giunto di fronte ad un problema. Devo necessariamente leggere un file all'interno di una cartella, questo file si trova sempre all'interno della stessa cartella, quindi lo script una volta fatto sarà sempre funzionante (suppongo). Utilizzo la libreria SD.h e ho già cercato su internet ma non ho trovato molto, magari non ho la tecnica di ricerca giusta, ma sono riuscito a trovare qualcosa che ha a che fare con le cartelle. Ciò che mi ha attirato di più sono le funzioni isDirectory();, openNextFile() e rewindDirectory. Purtroppo non sono riuscito a capire la funzione di alcuna di queste, o almeno singolarmente sì ma non riesco ad utilizzarle per il mio scopo. Come posso fare?
Grazie in anticipo :slight_smile:

Se è sempre lo stesso file nella stessa cartella basta che specifichi il percorso al momento dell'apertura:

SD.open("/nome_dir/nome_file");

Le altre funzioni servono per avere una lista dei files presenti nella directory, ammesso che ti serva.

Ciao, Ale.

Ho applicato ciò che mi hai detto, inoltre in precedenza avevo provato un metodo simile con SD.open("nome_dir/nome_file"); ma non aveva funzionato. Comunque, tornando a noi, non funziona :frowning:
Ho caricato questo codice:

#include <SD.h>
File document;
const byte chipSelect = 10;

void setup() {
  Serial.begin(9600);
  if(SD.begin(chipSelect)){
    Serial.println("connesso");
  }else{
    Serial.println("errore 1");
  }

}

void loop() {
  document = SD.open("/BACKUP/a.txt", FILE_WRITE);
  if(document){
    if(document.available()){
      Serial.write(document.read());
      document.close();
    }
  }else{
    Serial.println("errore 2");
  }
}

Mentre sulla schedina SD ho caricato un banale file A.txt all'interno della cartella BACKUP.
Sulla seriale mi restituisce errore 2, eppure mi sembra di aver fatto tutto bene...

... occhio perché la libreria SD inclusa in Arduino non supporta i nomi file lunghi, quindi massimo 8+3 caratteri e niente maiuscole/minuscole ... solo tutto in MAIUSCOLO come sotto MSDOS. :wink:

Guglielmo

Giusto, non avevo notato questa discordanza, ho aggiornato il codice ma continua a non funzionare

#include <SD.h>
File document;
const byte chipSelect = 10;


void setup() {
  Serial.begin(9600);
  if(SD.begin(chipSelect)){
    Serial.println("connesso");
  }else{
    Serial.println("errore 1");
  }

}

void loop() {
  document = SD.open("/BACKUP/A.txt");
  if(document){
    if(document.available()){
      Serial.write(document.read());
      document.close();
    }
  }else{
    Serial.println("errore 2");
  }
}

Con nome lungo intendi che 8+3 deve comprendere anche il nome della cartella?

NO, è come su MSDOS ... il nome cartella è soggetto agli stessi vincoli ... ne tuo caso si deve chiamare: /BACKUP/A.TXT ... tutto in maiuscolo (anche il file che crei sulla SD).

Guglielmo

Altra cosa ... con la libreria standard SD la Open:

Returns

A File object referring to the opened file; if the file couldn't be opened, this object will evaluate to false in a boolean context, i.e. you can test the return value with

if (f)

... quindi ... da dove arriva quel document.available() che NON trovo nella documentazione ufficiale della libreria SD?

Guglielmo

Guarda bene, è nella classe File, ed è ereditato da Stream.

Ciao, Ale.

Nell'esempio ReadWrite incluso nella libreria SD.h a cui si giunge dall'IDE è presente il available() nella parte di lettura:

myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {          //QUI
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

Da ciò che so questa funzione restituisce come argomento booleano la disponibilità di caratteri da leggere.

Non proprio, la funzione restituisce il numero dei carattteri disponibili:

Returns

The number of bytes available as an integer.

Ciao, Ale.

Allora, ho provato a sostituire /BACKUP/A.TXT nel mio codice ma succede una cosa alquanto strana...
In seriale mi restituisce "connesso" e tanti zeri, successivamente resetto con il tasto reset e mi restituisce "errore 1", resetto nuovamente e ricomincia con "connesso" e tanti zeri e così via...

ah ecco, non ne sapevo con esattezza la funzione :slight_smile:

Quanta roba c'è sulla SD? Prova a caricare lo sketch listfiles degli esempi e posta il risultato.

Ciao, Ale.

	Initializing SD card...initialization done.
SYSTEM~1/
	WPSETT~1.DAT		12
	INDEXE~1		76
BACKUP/
	Z.TXT		30
	E#.TXT		32
	F#.TXT		30
	F.TXT		30
	G#.TXT		32
	G.TXT		32
	H#.TXT		33
	H.TXT		30
	I#.TXT		29
	I.TXT		29
	J#.TXT		32
	J.TXT		32
	K#.TXT		31
	K.TXT		33
	L#.TXT		29
	L.TXT		30
	M#.TXT		31
	M.TXT		29
	N#.TXT		32
	N.TXT		28
	O#.TXT		29
	O.TXT		29
	P#.TXT		30
	P.TXT		30

	P#.TXT		30
	P.TXT		30
	Q#.TXT		33
	Q.TXT		30
	R#.TXT		30
	R.TXT		24
	S#.TXT		30
	S.TXT		29
	T#.TXT		30
	T.TXT		32
	TEST.TXT		126
	U#.TXT		31
	U.TXT		28
	V#.TXT		31
	V.TXT		28
	V.TXT		28
	W#.TXT		34
	W.TXT		29
	X#.TXT		32
	X.TXT		29
	Y#.TXT		30
	Y.TXT		30
	Z#.TXT		30
	(.TXT		29
	).TXT		29
	-.TXT		27
	0.TXT		32
	1.TXT		29
	2.TXT		31
	3.TXT		32
	5.TXT		30
	6.TXT		32
	7.TXT		30
	8.TXT		32
	9.TXT		31
	A#.TXT		33
	A.TXT		29
	B#.TXT		32
	B.TXT		31
	C#.TXT		30
	C.TXT		28
	D#.TXT		32
	D.TXT		31
	E.TXT		29
done!

:sweat_smile:

Sono veramente tanti, spero non sia un problema, il fatto è che sto costruendo una "stampante" con Arduino e qui immagazzino tutti i caratteri, in ogni file ci sono 14 numeri separati da ; è quindi necessario che rimangano, anzi in futuro potrei incrementarne il numero. Avevo provato a metterli tutti in un file ma in questo modo mi sembrava più ottimizzato

Ho svuotato la SD e ho lasciato dentro solo il file A.TXT dentro alla cartella BACKUP, però continua a dare i risultati strani di prima... ho modificato il contenuto del file e ho notato che i numeri che scrive sono il primo numero all'interno del .TXT
Non ho la più pallida idea di ciò che stia accadendo.

AGGIORNAMENTO:
Ho spostato tutto nel setup:

#include <SD.h>
File document;
const byte chipSelect = 10;


void setup() {
  Serial.begin(9600);
  if(SD.begin(chipSelect)){
    Serial.println("connesso");
  }else{
    Serial.println("errore 1");
    while(1);
  }
  document = SD.open("/BACKUP/A.TXT");
  if(document){
    while(document.available()){
      Serial.write(document.read());
    }
    document.close();
  }else{
    Serial.println("errore 2");
  }
}

void loop() {
}

Finalmente ora anche se resetto Arduino non mi restituisce più i valori strani di prima e mi legge l'intero file per bene, quindi funziona. Adesso devo vedere cosa succede se lo posiziono nel loop

Che è quello che gli chiedi di fare:

if(document){
    if(document.available()){
      Serial.write(document.read());
      document.close();
    }
  }else{
    Serial.println("errore 2");
  }

Chiedi se ci sono caratteri disponibili, la risposta è maggiore di zero, stampi un carattere che leggi (il primo), chiudi il file. Cosa altro ti aspettavi??
Se guardi l'esempio che hai postato vedrai che è diverso (while al posto di if).

Cioa, Ale.

Esatto, me ne sono accorto dopo :frowning:

... potevano pure documentarlo nel reference della libreria :roll_eyes:

Guglielmo

Se inserisco questa la parte di codice nel loop va una volta si e una no, come mai? O meglio, cosa cambia?

Inserendo un delay(100) alla fine del loop funziona quasi sempre anche resettando, mi viene da dire che lavorava troppo velocemente...

Ma stai facendo una stampante 'stampante' ?

Che scrive testo a partire da codifica ascii?

Non si fa così
Perché ti mancherebbe la codifica di una carriola di caratteri, tra riservati, non stampabili e vietati nel file-name