Go Down

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

zoomx

Lo sketch allegato, troppo lungo per essere incluso nel forum, è uno schema di datalogger e ha un problema di scrittura su SD.
Il test di scrittura crea il file ma dentro non c'è nulla. E' vuoto, zero byte.
Ho provato a cambiare SD ma il risultato non cambia.
Se uso il programma di esempio ReadWrite funziona, trovo il file con il testo di esempio.
Uso la libreria SDfat ma anche con la libreria SD standard accade esattamente la stessa cosa. Ma la SDfat dovrebbe essere un aggiornamento della SD, secondo il suo autore.
Se elimino la parte dell'RTC DS1307, funziona.
Uso la libreria DS1307new, se la cambio con RTClib di Adafruit accade esattamente la stessa cosa. Inoltre la libreria Adafruit mi da una serie di 165 invece di data e ora, Ma questo l'ho scritto in un altro post http://forum.arduino.cc/index.php?topic=166715
Come ho scritto in un altro post (http://forum.arduino.cc/index.php?topic=165088.0), se è presente una piccola parte che ha a che fare con il Timer1, il programma va in reset anche se quella parte non viene attivata ancora prima di arrivare ad aprire il file oppure subito dopo averlo aperto.
Sembra un problema di RAM ma i controlli sulla RAM usata danno sempre oltre 700 byte liberi.

Lo sketch gira su Arduino UNO R3 con uno shield per il DS1307 e uno per la SD. Uso le librerie SDfat e DS1307new.
La libreria DS1307new è questa https://code.google.com/p/ds1307new/
La libreria SDfat è questa http://code.google.com/p/sdfatlib/downloads/list
Uso Arduino 1.0.4 dove l'unico cambiamento sta nella libreria java che fa la scansione delle seriali.

Il programma mostra un menù autoesplicativo (più o meno) sulla console seriale. Se premete 9 parte il test di scrittura su SD. Questo stampa su seriale la quantità di RAM subito dopo l'apertura del file e subito dopo la chiusura. Il quantitativo è sempre 897. I test K e k li ho eliminati anche se nel menù appaiono ancora. Qualsiasi comando non riconosciuto, ma anche il semplice invio, fa apparire il menù.

Questo è il codice estratto dallo sketch

Code: [Select]

void SDwriteTest(){
  Serial.println(F("SD write test1"));
  if (!card.init(SPI_HALF_SPEED, CHIPSELECT)) {
    Serial.println(F("SD init failed."));
    return;
  }
  Serial.println(F("opening"));
  if (!MioFile.open("test.txt", O_WRITE | O_CREAT | O_APPEND)) {
    sd.errorHalt("Failed");
  }
  Serial.println(freeRam());
  ciccio=MioFile.println(F("ProvaF"));
  Serial.println(ciccio, DEC);
  MioFile.close();
  Serial.println(freeRam());
  Serial.println(F("done!"));
}



Io credo lo stesso che sia un problema di RAM, se avessi un Mega farei subito la prova.
Credo anche che sto facendo qualche grossolano errore nel codice perché in giro vedo programmi ben più grossi di questo (ad esempio http://forum.arduino.cc/index.php?topic=132746.0) che non hanno affatto problemi di questo genere. Ecco il motivo per cui ho incluso tutto lo sketch.

pablos71

#1
May 17, 2013, 10:58 am Last Edit: May 17, 2013, 11:09 am by pablos Reason: 1
Code: [Select]
//pinMode(4, OUTPUT);
hai fatto male a escluderla nel setup, ci va eccome e ci andrebbero anche
Code: [Select]
digitalWrite(4, 1);
pinMode(10, OUTPUT);
digitalWrite(10, 1);


L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

zoomx

#2
May 17, 2013, 11:04 am Last Edit: May 17, 2013, 11:07 am by zoomx Reason: 1
Ma io non uso lo shield Ethernet!
Comunque, fra le varie prove, mi ricordo di avere fatto anche questa.

Ricordo che la creazione del file avviene, solo che è vuoto.

Aggiungo le tue linee e  provo.

Edit: niente da fare, sempre zero byte!!!

Grazie lo stesso!

pablos71

un altra cosa....nell'inizializzazione della SD
Code: [Select]
Serial.print(F("\nInit SD card..."));
 if (!card.init(SPI_HALF_SPEED, CHIPSELECT)) {
   Serial.println(F("Init failed."));
   return;
 }
 else {
   Serial.println(F("SD card present"));
 }


CHIPSELECT lo hai dichiarato 10
Code: [Select]
#define CHIPSELECT 10  //4 on ethernet card

è il contrario 10 per la ethernet e 4 per la SD, la riga giusta è
Code: [Select]
if (!card.init(SPI_HALF_SPEED, 4)) {
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

zoomx

Ripeto, uso uno shield dove il chipselect è sul 10. Non uso la Ethernet. Il commento in effetti non è chiarissimo per cui ti ha indotto in errore. Lo cambierò.

Aggiungo che gli shield non sono collegati direttamente alla UNO ma al Sensor Shield V5.


pablos71

Può darsi che mi abbia tratto in inganno, quindi hai un arduino uno, uno shield sensor che credo abbia i pin in parallelo all' UNO, e come SD è uno shield solo sd o una scheda ethernet + sd?
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

zoomx

#6
May 17, 2013, 11:27 am Last Edit: May 17, 2013, 11:53 am by zoomx Reason: 1
Lo shield Sendor ha un header per la SD con i pin descritti nello sketch.

La SD sta su uno shield con un convertitore di tensione e alcuni condensatori e resistenze SMD. Lo shield con il programma ReadWrite e i collegamenti attuali funziona. Non penso ci siano problemi elettrici, anche se la storia del DS1307, che da me sta su un altro shield con una eeprom, la batteria e pochi altri componenti SMD, mi da da pensare.

Se dallo sketch elimini tutta la parte del DS1307, funziona.

Il mio sospetto principale sta in un errore grossolano nel codice che consuma memoria. O che ci sia una interferenza tra i due shield. Ho anche provato l'alimentazione a parte, non da USB ma il risultato è sempre stato lo stesso.

Edit:
Usando la libreria tinyFAT
http://henningkarlsen.com/electronics/library.php?id=37
funziona. Freeram mi da sempre 860 in tutte le fasi da apertura a chiusura file, quindi meno della SDfat, eppure funziona, almeno il test.
Edit 2: ho scritto all'autore perché non c'è un modo chiaro per definire il pin per CS o SS. A me funziona perché la combinazione sarà giusta ma questo significa che se uso la Ethernet card non mi funzionerà.

PaoloP


zoomx

Sebbene cambiando libreria sembri che funzioni a me rimane il dubbio che nel codice ci siano errori grossolani che mi porranno altri problemi di memoria in futuro. La mia esperienza di C su microcontrollori è di pochi mesi, ho usato l'assembler su micro ST (l'ST6 e l'ST9 ma anni fa), basic e assembler su 68HC11 (TFX11, grande scheda!) e poi basic su PC insieme ad un po' di C e Delphi.



cyberhs

Probabilmente lo sai già...

Non è che ti sei dimenticato di formattare la SD con FAT16?

zoomx

Non dovrebbe essere un problema di formattazione visto che, come ho già scritto, l'esempio ReadWrite funziona, il file viene creato ma è vuoto, se tolgo la libreria DS1307 funziona. Però hai fatto bene a ricordarmi della formattazione perché mi hai ricordato che manca una informazione che può essere utile.


Ho dimenticato di scrivere che la SD è da 256Mb. Ho però provato con SD da 2Gb ottenendo lo stesso risultato. E' però vero che non ho provato tutte le combinazioni possibili tra le prove che ho fatto.

Però il mio sospetto è di tipo software.

nid69ita


Edit 2: ho scritto all'autore perché non c'è un modo chiaro per definire il pin per CS o SS. A me funziona perché la combinazione sarà giusta ma questo significa che se uso la Ethernet card non mi funzionerà.

Dal manualetto pdf accluso alla libreria:
file.setSSpin();          da chiamare prima di   file.initFAT()
my name is IGOR, not AIGOR

zoomx

E' vero, è l'ultima istruzione nel manualetto. Grazie nid69ita!!!

Devo riscrivergli e chiedere perdono!

zoomx

Grazie ai chiarimenti di Lesto su Serial.flush() ne ho aggiunti un po' al test di scrittura

Code: [Select]
void SDwriteTest(){
  Serial.println(F("SD write test1"));
  Serial.flush();
  if (!card.init(SPI_HALF_SPEED, CHIPSELECT)) {
    Serial.println(F("SD init failed."));
    return;
  }
  Serial.println(F("opening"));
  Serial.flush();
  if (!MioFile.open("test.txt", O_WRITE | O_CREAT | O_APPEND)) {
    sd.errorHalt("Failed");
  }
  Serial.println(freeRam());
  Serial.flush();
  ciccio=MioFile.println(F("ProvaF"));
  Serial.println(ciccio, DEC);
  Serial.flush();
  MioFile.close();
  Serial.println(freeRam());
  Serial.println(F("done!"));
}


che mi stampa il seguente

Code: [Select]
SD write test1
opening
897
8
897
done!


dove 897 dovrebbe essere la RAM libera e 8 il numero dei byte scritti (http://arduino.cc/en/Reference/FilePrintln). Solo che il file viene creato ma continua ad essere desolatamente vuoto.

lestofante

#14
May 20, 2013, 12:28 pm Last Edit: May 20, 2013, 12:33 pm by lesto Reason: 1
uhmmm... prova a modificare:
Code: [Select]
ciccio=MioFile.println(F("ProvaF"));
in
Code: [Select]
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
Code: [Select]
MioFile.flush(); prima della close()  :smiley-mr-green:
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Go Up