One SD Card example works, other does not

I am trying to setup a Nano (ATM168) so that it can write data to a 1GB SD card.

The built-in 'CardInfo' example works. The card is detected, it tells me it's type, size, etc. all fine:


/*

  SD card test

  This example shows how use the utility libraries on which the'

  SD library is based in order to get info about your SD card.

  Very useful for testing a card when you're not sure whether its working or not.

  Pin numbers reflect the default SPI pins for Uno and Nano models

  The circuit:

    SD card attached to SPI bus as follows:

 ** SDO - pin 11 on Arduino Uno/Duemilanove/Diecimila

 ** SDI - pin 12 on Arduino Uno/Duemilanove/Diecimila

 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila

 ** CS - depends on your SD card shield or module.

        Pin 10 used here for consistency with other Arduino examples

  created  28 Mar 2011

  by Limor Fried

  modified 24 July 2020

  by Tom Igoe

*/
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:

Sd2Card card;

SdVolume volume;

SdFile root;

// change this to match your SD shield or module;
// Default SPI on Uno and Nano: pin 10
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN

const int chipSelect = 10;

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("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  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);
  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);
  root.close();
}
void loop(void) {
}

When I load any other example, it never gets past the SD.begin() call. It's a boolean that is returned as false, terminating the script:

#include <SPI.h>
#include <SD.h>
File myFile;
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 (!SD.begin(10)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("This is a test file :)");
myFile.println("testing 1, 2, 3.");
for (int i = 0; i < 20; i++) {
myFile.println(i);
}
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// nothing happens after setup
}

No idea how should I debug this. I assume my wiring & parts are fine, as the first script works. I also tried swapping everything - Arduino, SD card and the SD module.

What should I look into?

The problem can be the SPI speed.

The speed is configured on first example but not on second.

The speeds are full, half and quater.

1 Like

Your second programme looks rather like the read/write example included in the IDE. If that is your intention, it is incomplete and you might as well just cut to the chase and load the given example.

If that is not your intention and you really do want to just write, you might as well use the given example anyway. Mellis, Fried and Igoe usually know what they are doing.

Why you would want to change the SPI speed is beyond me. I didn't know it was possible.

Thanks! I missed that.

Unfortunately it did not fix it, no change at all.

Guess I'll try the SdFat lib, which could give me a bit more info about whats wrong.

If I recall correctly your 168 has half the RAM of a 328 - 1k instead of 2k. You may not have enough free RAM to run the SD card library.

1 Like

This is very well possible. I've just accidentally found an old UNO with a 328... and it worked on first try.

Guess I'm ordering another bunch of Arduinos then

Thanks!

Wow! I have never heard of a 168 and simply ignored it. In the same vein, though, it is certainly easy to run out of free RAM on a Uno and, if you are into datalogging, you may well find that the 328 Unos you are looking at ordering aren't up to the job either, and you will be a lot safer using a Mega or something from the ESPxxxx family.

1 Like

Or just Nanos with 328P instead of Unos.

1 Like

Both of the programs are the built-in to IDE, just checked them and they are complete. First one works, second fails at SD.begin().

How would I use the code from the first example to write? I strugle to find the way.

The following is legitimate code, and you appear to be doing that

 lcd.println("Init SD CARD");
  if (!SD.begin(chipSelect)) 
  {
    lcd.println("Card failed");
    return;
  }
  lcd.println("CARD OK");
  delay(2000);

You do not say if you actually get the "card fail" alert. If you do, you need to check that it is properly seated.

If you simply want to record data, you myfile.print it in the currently unused loop.

Hey Nick, thanks for all your replies so far!

By this I meant that I get that "card fail". The setup works just fine on UNO's ATM326, it really seems to be problem of the limited Nano 168's RAM.

Therefore I assume my current possible solutions are:

A) Get new Nanos with 326's
B) Somehow strip the code down to pure WRITE, presumably using card.init(SPI_HALF_SPEED, chipSelect) instead of SD.begin(). However, I just cannot seem to find the way to do this...

Possibly true, and even if it isn't, using 168s can't possibly be a good idea. I think it is just asking for trouble. See my previous. I'm not sure what your intentions are but, if it is datalogging, a Mega is a better way to go. In this particular business, a Uno 326 is likely to run out of memory before it runs out of pins. If there is a pressing need for a small format, there is a Pro Mega and likely something in the ESPxx flotilla.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.