Scrivo su SD ma il file è vuoto.

uhmmm... prova a modificare:

ciccio=MioFile.println(F("ProvaF"));

in

ciccio=MioFile.println("ProvaF");

comunque se togliendo qeulla libreria funziona, il problema o è la ram o è qualche cozzamento tipo timero o interrupt

edit: giusto per... prova con una MioFile.flush(); prima della close() :grin:

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.

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.

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.

se si inchioda subito a naso non hai attivato il giusto pin SS

Purtroppo no

#define CHIPSELECT 53  //MEGA!!!!

e nella funzione setup() ho

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.

puoi mettere un pò di Serial.print per capire dove si blocca la SD.h?

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

Uso questa funzione

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

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.

qualcosa non mi torna, vedo che fai

card.init(SPI_HALF_SPEED, CHIPSELECT)

invece la SD vorrebbe un semplice begin

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

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 SD - Arduino Reference

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 SD - Arduino Reference recita

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.

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

Mi sà che @lesto ci ha preso.

Se guardi cosa fa la begin:

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

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!!!!

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

  1. 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

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.

rimetti il check su

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

@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" ?

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.

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)".

a questo punto se non ci posti il codice completo dovrai contare solo sulle tue zampette :slight_smile:

Il codice è simile a quello riportato nel primo post ma lo riallego comunque.
Dovrebbe funzionare anche senza il DS1307 attaccato, io ho provato a disconnetterlo e, a parte la segnalazione che l'RTC non va il programma gira.
9, k e K sono i comandi da dare per i 3 test come descritto nel primo post.
Il codice è per MEGA ma se si cambia il chipselect dovrebbe andare anche sull'UNO (più la parte per il timer, tutti i 4 dei registri timer presenti vanno cambiati in 1) su cui però avevo dubbi per la RAM occupata nonostante sembra che ci fossero almeno 600 byte.

Datalogger23.zip (3.79 KB)

aspetta, ma senza il DS1307 collegato funziona la scrittura su SD?

No, purtroppo :frowning: stesso inchiodamento.