[RISOLTO] Scrittura su SD salta bytes

La scheda itead ha il selettore 3/5V. Già fatto tutte le prove. Sempre il medesimo problema.
credevo che il problema derivasse dalla lettura della seriale che con l'interrupt o qualche timer andasse in conflitto con il bus SPI. Allora ho fatto scrivere su SD una stringa con un contenuto variabile che indicasse il numero di righe scritte ed il timing. Risultato? sembra che inevitabilmente ci sia sto problema. A questo punto, sì provo con un'altro shield o thinker...

#include <SD.h>
#include <PString.h>

// Default SD chip select for Uno and Mega type devices
const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega

// chipSelect_SD can be changed if you do not use default CS pin
const int chipSelect_SD = chipSelect_SD_default;

long counter;

char buffer [300];
PString dataString (buffer,sizeof(buffer));

File dataFile;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  Serial1.begin(9600);

  // Make sure the default chip select pin is set to so that
  // shields that have a device that use the default CS pin
  // that are connected to the SPI bus do not hold drive bus
  
  pinMode(chipSelect_SD_default, OUTPUT);
  digitalWrite(chipSelect_SD_default, HIGH);

  pinMode(chipSelect_SD, OUTPUT);
  digitalWrite(chipSelect_SD, HIGH);


  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect_SD)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (!dataFile) {
    Serial.println("error opening datalog.txt");
    return;
  }
  dataFile.close();
    
  counter = 0;
  
  
}

void loop()
{
    dataString.print("prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. ");
    dataString.print(counter);
    dataString.print(" creata dopo ");
    dataString.println(millis());
    counter+=1;
  
         dataFile = SD.open("datalog.txt", FILE_WRITE);
        if (!dataFile) {
          Serial.println("... File error");
          return;
        } 
        else
        {
          //dataString.println();        // aggiungo alla stringa <CR> e <LF>
          Serial.print(dataString);      // creo l'echo a monitor
          dataFile.print(dataString);    // scrivo la stringa su SD
          Serial.print(" SD writing:... ");
          dataFile.flush();
          dataFile.close();              // assicurati che tutti i bytes siano stati scritti
          delay(300);
          dataString.begin();            // resetta la stringa     
          Serial.println("  ... done!"); 
        }
}

la riga che mi dice quantio bytes ha scritto non me la compila.

Di seguito un paio di esempi dell'errore: in rosso le stringhe scritte in modo errato, in blu i caratteri "saltati"

prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7468 creata dopo 3691897
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7469 creata dopo 3692375
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7470 creata dopo 3692853
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7471 creata dopo 3693331
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7472 creata dopo 3693835
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7474 creata dopo 3694853
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7475 creata dopo 3695335
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7476 creata dopo 3695816

prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7505 creata dopo 3709923
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7506 creata dopo 3710401
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7507 creata dopo 3710879
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7508 creata dopo 3711364
prova a salvare questa stringa su SD e vedere quanti caratteri perde se ne perde qualcuno. Questa riga n. 7509 creata dopo 3711908

Mvedovetto:
la riga che mi dice quantio bytes ha scritto non me la compila.

           Serial.print(dataString);      // creo l'echo a monitor
          int num=dataFile.print(dataString);    // scrivo la stringa su SD
          Serial.print(" SD writing "); 
          Serial.print(num);
          Serial.print("/"); 
          Serial.print(dataString.length()); 
          dataFile.flush();
          dataFile.close();              // assicurati che tutti i bytes siano stati scritti

Ho provato con una SD classe 10 e non sembra più avere problemi. Non conosco il protocollo SDI, ma essendo asincrono, la libreria non consente di gestire la velocità del bus?
Faccio qualche altro test e dopo credo che possa considerarsi risolto

Quindi era una questione di velocità della tua SD?

Hai provato ad utilizzare l'IDE Nightly Builds, hanno rivisto completamente le librerie SPI e SD.
--> http://arduino.cc/en/Main/Software#toc4
Potresti avere qualche problema con PROGMEM.

Sembra proprio di sì: questione di velocità SD. Provato con SD classe 4: 0 errori. Provato con un'altra SD "generica": soliti errori...

In merito alle nightly builds... sto utilizzando MPIDE visto che alla fine attribuivo alla velocità di Arduino UNO l'errore...

Direi che possiamo marcare il thread come "RISOLTO".

Grazie a tutti per i riscontri.

Marco

Il cambio di titolo è un'operazione eseguibile anche dai normali utenti, basta editare il primo post del thread e cambiare il titolo da lì

piu' che velocita' della SD io direi che e' la SD "generiche" difettose.
Stai parlando di scrivere un misero dato ogni secondo, quanti byte e' lungo il dato che scrivi ? Come fa ad essere un rpoblema di velocita' ? Se fosse stato un rpoblema di velocita' scrivendo ogni 2 secondi invece che ogni secondo avresti risolto, immagino invece che i problemi restano.

leo72:
Il cambio di titolo è un'operazione eseguibile anche dai normali utenti, basta editare il primo post del thread e cambiare il titolo da lì

Grazie. Credevo fosse un attributo di un topic.

Testato:
piu' che velocita' della SD io direi che e' la SD "generiche" difettose.
Stai parlando di scrivere un misero dato ogni secondo, quanti byte e' lungo il dato che scrivi ? Come fa ad essere un rpoblema di velocita' ? Se fosse stato un rpoblema di velocita' scrivendo ogni 2 secondi invece che ogni secondo avresti risolto, immagino invece che i problemi restano.

Allora io e altri due utilizzatori abbiamo impigato 5 memorie SD " generiche". Tutte difettose? Se fosse, Murphy avrebbe colpito appieno aiutato da Fantozzi. Ho anche provato anche a bufferizzare il dato scrivendo 5 sequenze alla volta, senza ovviamente risolvere il problema.
Ho smesso di raccontare bugie da parecchio tempo e se scrivo che utilizzando memorie con classe dichiarata il problema non c'è significa che non è stato riscontrato. Se hai qualche ulteriore suggerimento ti ringrazio.

Se ti vuoi divertire a testare le velocità delle varie SD ti consiglio --> CrystalDiskMark プロジェクト日本語トップページ - OSDN

Murphy+Fantozzi deve essere imbattibile :slight_smile:

Sia chiaro mica non ti credo nel senso che stai dicendo bugie, se dici che con quelle piu' veloci funziona ci credo, dico solo che visto che parli di velocita' anche sulle lenti deve esserci soluzione, sto' cioe' approfondendo la soluzione , non smentendola.

Allora partendo dall'ottimo programma consigliato da PaoloP, lo conosco e' molto ben fatto, vediamo le reali velocita' delle schede che hai in mano, e poi si accettano scommesse.
io scommetto che anche le piu' lente che hai, cioe' quelle che non funzionano, Superano le necessarie capacita' per scrivere una singola coordinata GPS al secondo, cioe' ripeto quanto e' grande la stringa ? 1K ? non credo, ma se anche fosse vuoi vedere che le SD in questione scrivono a meno di 1K al secondo ?

Approfondendo in tal senso si potra' trovare una soluzione anche per esse secondo me

In questo esempio

con card.init si può variare la velocità della trasmissione SPI

card.init(SPI_HALF_SPEED, chipSelect)

solo che nella documentazione ufficiale qui

non se ne fa cenno.
Puoi anche provare la libreria

che dovrebbe aver corretto alcuni bug tuttora esistenti in quella originale, almeno a quanto dice l'autore.

Testato:
...
io scommetto che anche le piu' lente che hai, cioe' quelle che non funzionano, Superano le necessarie capacita' per scrivere una singola coordinata GPS al secondo, cioe' ripeto quanto e' grande la stringa ? 1K ? non credo, ma se anche fosse vuoi vedere che le SD in questione scrivono a meno di 1K al secondo ?

Approfondendo in tal senso si potra' trovare una soluzione anche per esse secondo me

Anch'io ne sono convinto, Testato, ma tant'è... ed è proprio per la stringa che è nemmeno 100bytes ed i tempi di latenza che sono inferiori a 300ms che mi aspettavo che scrivendo dati almeno ogni 5 secondi (bufferizzando) il problema si risolvesse.
Ora vedo con il software proposto da PaoloP.
Per le librerie, utilizzando MPIDE mi pare che la SDFat non sia compatibile con la UNO32 chipkit. Devo predisporre il test utilizzando la UNO.

se voi nel file SD.cpp e SD.h e sostituisci

  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

con

  return card.init(SPI_QUARTER_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

puoi usare anche le sd vecchie

Altrimenti anche

  return card.init(SPI_TURTLE_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

oppure

  return card.init(SPI_WARP_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

per quelle ultramoderne.
:grin: :grin: :grin: