Errore su Scheda SD: scrittura file

Buogiorno a tutti.
Sto tentando di realizzare un datalogger per monitorare dei dati di pressione per fare un grafico, ma il primo problema che ho incontrato è sulla scheda SD, in particolare riesco ad inizializzarla ma non riesco a scrivere.
Sto usando Arduino Uno rev 3 e una Ethernet shield con lettore di scheda SD, ma non so identificare il modello.
Riporto di seguito il codice usato, ho preso due programmi che ho trovato sia qui (su arduino.cc) sia in rete:

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

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

const int chipSelect = 13;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
  Serial.print("Initializing 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.");
  }

  // print the type of card
  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");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  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();

  // print the type and size of the first FAT-type volume
  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);

// Create/Open file 
  myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
  if (myFile) {
    Serial.println("Writing to file...");
    // Write to file
    myFile.println("Testing text 1, 2 ,3...");
    myFile.close(); // close the file
    Serial.println("Done.");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }
  // Reading the file
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("Read:");
    // Reading the whole file
    while (myFile.available()) {
      Serial.write(myFile.read());
   }
    myFile.close();
  }
  else {
    Serial.println("error opening test.txt");
  }
  /*Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
*/
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop() {
  // Create/Open file 
  myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
  if (myFile) {
    Serial.println("Scrivo il file...");
    // Write to file
    myFile.println("Testo di prova 1, 2 ,3...");
    myFile.close(); // close the file
    Serial.println("Finito.");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("errore nell'apertura del file test.txt");
  }
  // Reading the file
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("Leggo:");
    // Reading the whole file
    while (myFile.available()) {
      Serial.write(myFile.read());
   }
    myFile.close();
  }
  else {
    Serial.println("errore nell'apertura di test.txt");
  }
  delay(10000);
}

Caricando il programma, dal monitor seriale vedo:
Initializing SD card...Wiring is correct and a card is present.

Card type: SDHC
Clusters: 976512
Blocks x Cluster: 64
Total Blocks: 62496768

Volume type is: FAT32
Volume size (Kb): 31248384
Volume size (Mb): 30516
Volume size (Gb): 29.80
error opening test.txt
error opening test.txt
errore nell'apertura del file test.txt
errore nell'apertura di test.txt

Quindi la card viene vista correttamente, ma non riesco a scrivere e aprire il file. Non so come intercettare il tipo di errore per capire come risolverlo.
Ho provato a cambiare il parametro definito con

chipSelect

usando i valori, 4, 8,10,11,12,13 e 53 (so che quest ultimo è solo per arduino mega, ma provare costava poco) e solo usando 10 mi dice che la card non è presente.
Ho provato a togliere la scheda, mettere un file di testo e rimetterla su arduino e riesco a leggere la presenza del file, quindi il problema credo sia solo in scrittura.

Grazie in anticipo

L'unica cosa che vedo "strana" è l'uso di FAT32
Di solito consigliano FAT16, non ho mai provato 32
Ma non credo sia la causa
Prova a formattare ex novo la scheda
Magari con un tool apposito, non con il tool di serie di Windows
Dicono che alle volte sia quella la causa, anche se a me sembra strano

Non puoi usare "const int chipSelect = 13;" ... il pin 13 fa parte del bus SPI (esattamente è il SCK, mentre il 12 è il MISO e il 11 MOSI), devi usare il pin 4 dato che quello di base che si aspetta la libreria per le SD sulla scheda Ethernet.

Inltre dichiara in OUTPUT il pin 10 e mettilo HIGH (è il CS della Ethernet).

Guglielmo

Ciao a tutti.
Come scrivevo nel messaggio iniziale per chipSelect ho provato ad impostare i valori: 4,10,11,12,13 e in tutti i casi non riesco a scrivere sulla SD.
Ad ogni modo ho provato, come suggerito da Guglielmo, precisamente:

const int chipSelect = 4;

const unsigned int PIN = 10; aggiunto prima del setup

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

aggiunti al setup.

Il risultato purtroppo non cambia.

#include <SPI.h>
#include <SD.h>
const unsigned int PIN = 10;

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

const int chipSelect = 4;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  pinMode(PIN,OUTPUT);
  digitalWrite(PIN,HIGH);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 
  Serial.print("Initializing 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.");
  }

  // print the type of card
  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");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  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();

  // print the type and size of the first FAT-type volume
  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);

// Create/Open file
  myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
  if (myFile) {
    Serial.println("Writing to file...");
    // Write to file
    myFile.println("Testing text 1, 2 ,3...");
    myFile.close(); // close the file
    Serial.println("Done.");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }
  // Reading the file
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("Read:");
    // Reading the whole file
    while (myFile.available()) {
      Serial.write(myFile.read());
   }
    myFile.close();
  }
  else {
    Serial.println("error opening test.txt");
  }
  /*Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
*/
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop() {
  // Create/Open file
  myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
  if (myFile) {
    Serial.println("Scrivo il file...");
    // Write to file
    myFile.println("Testo di prova 1, 2 ,3...");
    myFile.close(); // close the file
    Serial.println("Finito.");
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("errore nell'apertura del file test.txt");
  }
  // Reading the file
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("Leggo:");
    // Reading the whole file
    while (myFile.available()) {
      Serial.write(myFile.read());
   }
    myFile.close();
  }
  else {
    Serial.println("errore nell'apertura di test.txt");
  }
  delay(10000);
}

Continuo a non riuscire a scrivere sulla SD.
Ho anche provato 3 SD diverse di cui una nuova.

Riciao a tutti.
Ho anche provato a formattare con FAT 16, ma stesso risultato, non riesce a scrivere.

Allora, tanto stai usando quelli, qundi usiamo gli esempi che sono a corredo della SD, ricordando sempre di aggiungere, ad inizio del setup, le due righe obbligatorie (se non si usa la parte Ethernet):

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

Comincia con l'esempio "CardInfo" e riporta esattamente quello che viene stampato a monitor seriale (fai copia/incolla) ...

Guglielmo

P.S.: Ovviamnete hai SOLO la scheda Ethernet collegata vero ?

Ciao!
Intanto grazie 1000 per la disponibilità.
Si ho solo la scheda Ehternet collegata al momento, volevo andare per gradi. L'obbiettivo era cercare di salvare dei dati a caso sulla scheda per testare poi aggiungere i valori presi dal sensore.
Ho preso l'esempio "cardinfo" come mi hai detto e aggiunto nel setup le righe, riporto la prima parte del setup:

void setup() {
  pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

L'output al momento è:

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

Card type: SDHC
Clusters: 60604
Blocks x Cluster: 128
Total Blocks: 7757312

Volume type is: FAT16
Volume size (Kb): 3878656
Volume size (Mb): 3787
Volume size (Gb): 3.70

Files found on the card (name, date and size in bytes):

Mi pare che abbia senso perché ora c'è solo una scheda montata senza files e l'esempio non genera files.

... bene, passiamo allora al prossimo esempio ... "ReadWrite" ... come al solito aggiungi solo le due righe, lancialo e riporta cosa ti scrive sul monitor seriale. :wink:

Guglielmo

Ha funzionato!
Sia con la scheda formattata FAT 16 che FAT 32.
Ho fatto un po' di prove e ... funziona.
Sto cercando di capire il perché ora.

Guarda bene il codice e cerca di vedere cosa fa l'esempio rispetto a ciò che fai tu :wink:

Guglielmo

Ok
Ho notato che:
Sd2Card card;
SdVolume volume;
SdFile root;
non sono presenti su readWrite perché vengono usati solo per carpire alcune informazioni che non servono strettamente ai vini della scrittura.

chipSelect: non ho capito a cosa serve, penso sia importante in quanto l'hai menzionato fin dall'inizio.

... magari lo studio di come funziona un bus SPI ti può chiarire l'uso dei pin :wink: Leggi QUI e anche QUI :slight_smile:

Guglielmo