RISOLTO! - SD card, problema durante reinserimento scheda

Houston we have a problem!
Sto cercando di utilizzare questa SD card per salvarmi dei dati.
Mi sono guardato i vari tutorial e sta funzionando tutto correttamente.

Dov’è il problema?
Mi sono incaponito sul voler rendere il sistema resistente alla rimozione e al reinserimento della card.
Ok che se viene tolta brutalmente la scheda durante la scrittura rischio di compromettere il file system ecc. ecc. ecc.
Ho preso alcune precauzioni visive per permettere di scegliere il momento giusto :wink:

Il problema è che non riesco a reinizializzare il tutto per farlo ri-funzionare una volta reinserita la card.
Il problema sta nel “volume”, che non lo riesco più a far funzionare.

Descrivo il problema.
Partiamo dal codice di esempio clasico dell’IDE “CardInfo”
Da me il CS è il 10, è l’unica modifica rispetto al codice standard.

#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 10; //4;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("\nInitializing SD card...");

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {
}

Funziona tutto.
Se tolgo la card e rilancio lo sketch, con nuova pubblicazione, tanto per indicare una modalità che dovrebbe far partire tutto ben pulito.
Ottengo, giustamente, il seguente messaggio di errore sulla seriale:

Initializing SD card...initialization failed. Things to check:
* is a card inserted?
* is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

Tutto OK,
come previsto è fallita la

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {

Se ora reinserisco la card e ripubblico tutto e riparto, mi aspetto torni tutto a funzionare e invece ottengo:

Initializing SD card...Wiring is correct and a card is present.

Card type:         SD2
Could not find FAT16/FAT32 partition.
Make sure you've formatted the card

La:

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {

è andata a buon fine, quella che è fallita è la:

  if (!volume.init(card)) {

Per far rifunzionare tutto di nuovo devo staccare l’USB.
Se ripubblico il codice o faccio semplicemente il reset della scheda, continua ad uscire questo errore.
Se invece stacco la USB (non essendoci altra alimentazione si spegne tutto) e chiudo il monitor seriale.
Quando la riattacco riparte tutto correttamente.
Per ripartire puliti serve spegnere fisicametne tutto.

Ora, leggendomi mezzo internet non ho mai trovato indicazioni sul fatto che la libreria SD o anche la scheda lettore SD abbiano qualche sorta di cache che richiede uno spegnimento totale.
Questo problema pregiudica ogni mio tentativo software di riprendere dalla rimozione della scheda e quindi mi fa da show stopper.

La scheda che ho postato non può essere il problema, perchè ho provato a scollegarla completamente e a ricollegarla e il problema persiste. E’ solo disalimentando Arduino (nel caso specifico un Nano) che si risolve e si esce dalla situazione sballata.

Qualcuno ha qualche idea?

Probabilmente c’è un qualche valore che viene settato e che non riesco a resettare perchè non sono riuscito a riconoscere le funzioni per farlo.
[pre[/pre]

La sparo, perchè adesso non riesco a provare.

Ho visto che esistono i metodi close sia per SdVolume che per SdFile, prova chiuderli e poi riprova il giochino.

  ...
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
  root.ls(LS_R | LS_DATE | LS_SIZE);

  root.close(); // <====
  volume.close(); // <====

[Update]
Adesso ho visto, forse per il volume non funziona (è un metodo interno). Prova :frowning:

Federico

Non ci credo!!!
Ho fatto la prova, root.close() esiste, volume.close() no.
Comunque, a parte questo, dopo aver fatto questa prova e aver rimesso il codice come prima non ho più avuto il problema e rieseguendo il mio codice ora funziona!
Mi ha preso per il c...lo tutto il pomeriggio e ora invece va!
Mah

Bene :slight_smile:

Comunque è buona norma chiudere, visto che estrai la card.
Mi pare che esista anche un root.isOpen(), quindi puoi sempre fare una verifica prima di riaprire.

Federico

Federico66:
Bene :slight_smile:

Mica tanto :frowning:
ora ha ripreso a non funzionare.

Io la close la facevo già.
Mi ero illuso ci fosse sulla volume, ma li non c’è.

Comunque, posto il mio codice che ogni tanto funziona e ogni tanto no.

#include <SPI.h>
#include <SD.h>

File myFile;

#define SD_CS 10

Sd2Card card;
SdVolume volume;
SdFile root;

boolean sdIsOn = false;

void initSD() {
  Serial.println("initSD()");
  if (!card.init(SPI_HALF_SPEED, SD_CS)) {
    sdIsOn = false;
    Serial.println("card.init() fail");
    return;
  }
  if (!volume.init(card)) {
    sdIsOn = false;
    Serial.println("volume.init() fail");
    return;
  }
  if (!root.openRoot(volume)) {
    Serial.println("root.open() fail");
    sdIsOn = false;
  }
  sdIsOn = true;
  Serial.println("SD Attiva!");
}

void setup() {
  Serial.begin(9600);
  pinMode(SD_CS, OUTPUT);
  initSD();
}

void loop() {
  if (!sdIsOn) {
    initSD();
  } else if (!volume.init(card)) {
    sdIsOn = false;
    if (root.isOpen()) {
      root.close();
    }
    Serial.println("SD OFF");
  }
  if (!sdIsOn) {
    return;
  }
  // Qui ci andrebbe il codice che usa la SD.
  Serial.print(".");
  delay(1000);
}

E’ solo il wrapper che si occupa di verificare che sia tutto ok all’inizio del loop e nel caso la card vada OFF si occupa di rimetterla ON appena ci riesce.
C’è una variabile che ne indica lo stato da usare all’interno del loop.

Di fatto funzionerebbe pure, solo che ogni tanto non va, quindi non è del tutto affidabile e non capisco perchè!

Oops.

Se riesco più tardi provo.

Hai già visto questo post?

F

Il fatto che ora funzioni e ogni tanto non funzioni mi fa sospettare molto seriamente a problemi di cablaggio.
Perchè avrò tolto a rimesso la card 100 volte e ha rilevato sempre correttamente il tutto, poi ad un tratto ha smesso di funzionare, ho tocchignato per un bel po' e ora ha ripreso a funzionare.
Sono su breadboard e quindi al momento resta la principale indagata.

Il codice che ho postato sopra, in teoria, funziona correttamente, se riesco a verificare che il problema di instabilità dipende dal cablaggio, sono a posto.

Grazie per il supporto

Confermo.
Problema di cablaggio.
Ho rimesso la card, non la rilevava, ha fatto diversi tentativi, ho toccato la scheda e dopo poco l'ha rilevata.

Questa volta non ho minimamente toccato il software o fatto reset di alcun tipo, solo toccato i cavi.

maubarzi:
Grazie per il supporto

Solo morale, ma a volte aiuta condividere :slight_smile:

Federico

Sicuramente, e comunque non è stato solo morale, il link che mi hai postato è stato interessante e non lo avevo trovato.