Go Down

Topic: Scrivo su SD ma il file è vuoto. (Read 9339 times) previous topic - next topic

zoomx

Si, ho fatto quella prova ed il risultato era il medesimo.

L'ho rifatta perché non si sa mai ed il risultato è che va in reset dopo la prima stampa di RAM libera, 891 per la cronaca.

Code: [Select]
SD write test1
opening
891
Setup


Setup viene stampato nella funzione omonima proprio per individuare eventuali reset.

Se uso la libreria tinyFAT invece sembra che il problema scompaia ma non riesco a capire perché la libreria standard mi dia questo problema. Si trattasse di una oscura libreria usata da solo 10 persone in tutto il mondo lo capirei ma questa è molto usata....
Anche il fatto che funzioni a metà è strano, il file viene creato per cui non si dovrebbe trattare di un problema di comunicazione.
La memoria è fortemente sospettata ma quale errore può consumare 891 byte?

L'unica prova che non posso fare è di caricare lo sketch in un altro Arduino, magari questo ha problemi con la RAM, perché ne ho solo uno.

Per adesso andrò avanti cambiando libreria, poi cercherò di provare su un altro Arduino o magari sul Mega che sto aspettando.

zoomx

E' arrivata la mega e ho fatto le prove:
Libreria SD originale -> si inchioda subito dopo l'apertura del file, che quindi trovo vuoto ma non ho errore perché l'apertura mi restituisce 1, e mi va in reset. Non è un problema di memoria, stavolta i byte liberi sono oltre 6000.
Libreria TinyFAT -> funziona ma manca delle utili funzioni della libreria originale come il trattamento delle stringhe.

lestofante

se si inchioda subito a naso non hai attivato il giusto pin SS
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

zoomx

Purtroppo no

Code: [Select]
#define CHIPSELECT 53  //MEGA!!!!

e nella funzione setup() ho
Code: [Select]
pinMode(CHIPSELECT, OUTPUT);
SD.begin(CHIPSELECT);

Ho ricontrollato perché non si sa mai.
Per me rimane un mistero che però ho voglia di risolvere perché la libreria SD.h usa gli stream come la Serial.print per cui è più comoda.
La TinyFAT curiosamente stampa solo con il Return e LineFeed obbligato per cui ho modificato la libreria per stampare senza il CR+LF.

Se ho novità le riporto qui.

lestofante

puoi mettere un pò di Serial.print per capire dove si blocca la SD.h?
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

zoomx

Premetto che l'esempio ReadWrite della libreria SD.h funziona, cambiando il Chipselect a 53, visto che uso una mega.

Uso questa funzione
Code: [Select]
void SDwriteTest(){
  Serial.println(F("SD write test"));
  Serial.flush();
  Serial.println(freeRam());
  Serial.flush();
  if (!card.init(SPI_HALF_SPEED, CHIPSELECT)) {
    Serial.println(F("SD init failed."));
    Serial.flush();
    return;
  }
  Serial.println(F("opening"));
  Serial.flush();
  FileOut=SD.open("PROVA.TXT",FILE_WRITE);
  Serial.println(freeRam());
  Serial.flush();
  if (FileOut) {
    Serial.println(FileOut);                                                          //Questo viene stampato
    Serial.flush();
    ciccio=FileOut.println("Prova non F");
    Serial.println(ciccio, DEC);                                                    //Questo non viene stampato!!!!!
    Serial.flush();
    Serial.println(freeRam());
    Serial.flush();
    ciccio=FileOut.println(F("ProvaF"));
    Serial.println(ciccio, DEC);
    Serial.flush();
    Serial.println(freeRam());
    Serial.flush();
    //SDPrintTime();
    FileOut.close();
    Serial.println(F("Done!"));
  }
  else {
    // if the file didn't open, print an error:
    Serial.println(F("error opening prova.txt"));
  }
}


e quest'altra
Code: [Select]

void SDwriteTest2(){
  Serial.println(F("SD write test2"));
  Serial.flush();
  if (!card.init(SPI_HALF_SPEED, CHIPSELECT)) {
    Serial.println(F("SD init failed."));
    Serial.flush();
    return;
  }
  Serial.println(F("opening"));
  Serial.flush();
  FileOut=SD.open("PROVA.TXT",FILE_WRITE);

  //if (FileOut) {
  Serial.println(FileOut);                                              //Questo viene stampato
  Serial.flush();
  FileOut.println("Prova non F");
  delay(100);
  ciccio=FileOut.println("Prova non F");
  Serial.println(ciccio, DEC);                                         //Questo non viene stampato!!!
  RTC.getTime();
  SDPrintTime();
  FileOut.close();
  Serial.println(F("Done!"));
  //}else {
  // if the file didn't open, print an error:
  //  Serial.println(F("error opening prova.txt"));
  //}
}

In questo in effetti avrei potuto mettere un altro print in maniera opportuna fra i due println ma non credo cambierebbe molto rispetto al primo esempio. Succede qualcosa dopo la creazione del file che poi trovo sulla SD ovviamente vuoto.
Windows non segnala alcun problema sulla SD dovuto al fatto che il MEGA si pianta dopo la creazione del file.
Se credi posso allegare tutto il codice ma ci vuole un MEGA e un DS1307, come ho scritto nel primo post.

lestofante

qualcosa non mi torna, vedo che fai

Code: [Select]

card.init(SPI_HALF_SPEED, CHIPSELECT)


invece la SD vorrebbe un semplice begin

Code: [Select]

if (!SD.begin(CHIPSELECT)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");


ATTENTO!!! il CHIPSELECT e il pin SS sono due pin differenti!!! il 53 va messo come output e basta, il CS è il pin a cui hai collegato il CS della SD
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

zoomx

Code: [Select]
card.init(SPI_HALF_SPEED, CHIPSELECT)
Era negli esempi e in ogni caso nello sketch il micro va oltre inchiodandosi dopo. Però ho preso nota del suggerimento.

Chiariamo invece il secondo punto.
La documentazione riporta http://arduino.cc/en/Reference/SD
Quote
Additionally, another pin must be used to select the SD card. This can be the hardware SS pin - pin 10 (on most Arduino boards) or pin 53 (on the Mega) - or another pin specified in the call to SD.begin(). Note that even if you don't use the hardware SS pin, it must be left as an output or the SD library won't work.

Quindi nella parte delle note http://arduino.cc/en/Reference/SDCardNotes recita
Quote
The Ethernet Shield comes with an SD card slot onboard. The shield fits on top of your Arduino. Because the Ethernet module uses pin 10, the CS pin for the SD card has been moved to pin 4. Make sure you use SD.begin(4) to use the SD card functionality.

Da cui ho dedotto che SS e CS sono la stessa cosa. Io ho il pin 53 collegato alla linea CS della schedina con l'SD.

lestofante

hai ragione per il pin 53, però qeul pezzo di codice non mi torna dagli esempi sul reference.

Usa la begin al posto di quello
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

nid69ita

Mi sà che @lesto ci ha preso.

Se guardi cosa fa la begin:
Code: [Select]

boolean SDClass::begin(uint8_t csPin) {   // Performs the initialisation required by the sdfatlib library.  Return true if initialization succeeds, false otherwise.
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);


Esegue anche altre 2 funzioni, mentre tu chiami solo la card.init
my name is IGOR, not AIGOR

zoomx

Mi sa che avete trovato il problema.
Difatti, non so perché, SD.begin mi funziona in setup ma non nei due esempi di scrittura dove mi da failed. Quindi immagino che si inchiodi perché la SD non è perfettamente pronta, tra il setup e la successiva prova di scrittura succede qualcosa. Faccio ulteriori indagini!!!!

zoomx

Siccome mi è venuto un sospetto ho fatto una ricerca e ho scoperto che sembra che SD.begin può essere richiamato una sola volta all'interno di uno sketch, tutte le altre volte ritorna False.
C'è un issue in proposito del 2011
https://code.google.com/p/arduino/issues/detail?id=465
Dove c'è scritto fra l'altro
Quote
2) you can not re-initialize the SD-object again. This would be
necessary (for some SPI magic I guess) if you remove the SDCard from the socket and put it back later. There is no SD.close() or something and calling SD.begin() a second time will always return FALSE and not initialize the SD again.

Non ho trovato nulla in proposito nella documentazione di riferimento.
A questo punto ho scritto un terzo test eliminando il controllo con SD.begin visto che in ogni caso restituisce falso nei due test precedenti
Code: [Select]
void SDwriteTest3(){
  Serial.println(F("SD write test3"));
  Serial.flush();
  Serial.println(F("opening"));
  Serial.flush();
  FileOut=SD.open("PROVA.TXT",FILE_WRITE);

  //if (FileOut) {
  Serial.println(FileOut);                                      //Questo viene stampato
  Serial.flush();
  FileOut.println("Prova non F");
  Serial.println(FileOut);                                      //Questo non viene stampato e va in reset
  Serial.flush();
  ciccio=FileOut.println("Prova non F");
  Serial.println(ciccio, DEC);
  RTC.getTime();
  SDPrintTime();
  FileOut.close();
  Serial.println(F("Done!"));
  //}else {
  // if the file didn't open, print an error:
  //  Serial.println(F("error opening prova.txt"));
  //}
}

Resetto il MEGA, aspetto che l'SD.begin dia risultato positivo nella setup(), quindi eseguo il test e si pianta come prima.

lestofante

rimetti il check su
Code: [Select]
if (FileOut) {

che non centra niente col begin. in oltre NON puoi usare altre periferiche SPI (da quanto ho capito), perchè prima dovresti fare SD.close(), usare l'altra scheda, e poi SD.begin() di nuovo.

In oltre se dici che con gli esempi funziona, il problema è nel tuo codice, quindi cerca di eliminare parti (in partiolare altri sensori) fino ad ottenere una situazione funzionante
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

nid69ita

@zoomx scusa, domanda probabilmente stupida, ma l'istruzione   Serial.println(FileOut);   hai provato lo sketch senza ?
Mi viene il dubbio, FileOut non è un oggetto? Oppure è un puntatore? Ha significato "stamparlo" ?
my name is IGOR, not AIGOR

zoomx

Ehmmm... SD.close(); non esiste. Nell'issue scrivono appunto di implementarlo.

Non ho altre periferiche SPI, l'RTC è in I2C.

Ho provato anche SDfat e mi si inchioda nello stesso punto (è derivata proprio da SD.h), trovo sempre che il file è stato creato e poi nulla perché, appunto si inchioda. La TinyFAT è l'unica che non si inchioda a parità di codice, più o meno.

Che il problema sia nel mio codice non ci piove, non ho mai sostenuto il contrario altrimenti avrei aperto un issue. Domani faccio daccapo una prova usando lo Shield Ethernet e una microSD. E farò altrre prove cercando di escludere un conflitto con la libreria per l'RTC, conflitto sempre dovuto al mio codice perché ci sono un sacco di esempi di sketch dove le due librerie convivono tranquillamente.

@nid69ita
Si, restituisce un oggetto ma secondo quanto scritto nella documentazione non dovrebbero esserci problemi a stamparlo, infatti mi stampa un 1. In effetti la seconda stampa nel terzo test non ha senso. PErò manca nei due test precedenti e l'inchiodamento c'è lo stesso. Riporto quanto dice la documentazione.
Quote
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)".

Go Up