SOLVED: Datalogger example messes up SD card

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
K3A
 
Posts: 3
Joined: Wed Mar 12, 2014 6:54 am

SOLVED: Datalogger example messes up SD card

Post by K3A »

Hi!

Summary:
While running the datalogger example, the SD card is erased and multiple files appear. The filenames basically consist of the sensor data. All of those files are corrupt.

My Setup:
  • Arduino Leonardo
  • Samsung 4GB microSD card, formatted to FAT16 with gparted (Ubuntu Partition Editor)
  • Arduino 1.0.4, Ubuntu
The CardInfo example works like a charm, the card is recognized, file system is recognized, size is correct. (see the code under my post, only CS is changed to 5)

Code: Select all

Initializing SD card...
Card type: SDHC

Volume type is FAT16

Volume size (bytes): 3940220928
Volume size (Kbytes): 3847872
Volume size (Mbytes): 3757

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

Now I wanted to log sensor data and started off with the Datalogger Example (see code below). Again I only modified the chip select line. I put the file "datalog.txt" on the card. Running CardInfo again:

Code: Select all

Initializing SD card...
Card type: SDHC

Volume type is FAT16

Volume size (bytes): 3940220928
Volume size (Kbytes): 3847872
Volume size (Mbytes): 3757

Files found on the card (name, date and size in bytes): 
DATALOG.TXT   2014-03-12 12:16:06 0
Looks good. Now I power the Arduino down and remove the card. I flash the Datalogger example (see code below), power down the Arduino, attach the card, start up:

Code: Select all

Initializing SD card...card initialized.
196,136,110
100,97,87
89,85,76
89,84,77
123,118,109
130,126,116
116,111,102
114,110,101
122,117,108
133,129,118
...and so on
I power the Arduino down and remove the card. After inserting it into my computer, it appears to be empty.

In a terminal, 'ls' gives me:

Code: Select all

computer /media/116A-DD02 % ls
0,179??1.97,  ,151??16.8,1  202,189?.?20  ,226,214.??2	4,223,21.5??
0,200,18.8??  156??173.,16  ,203??21.6,2  ??226,21.5,2	5,121??1.22,
0,209,19.5??  ?166,158.,15  ?207,197.,18  ??229,21.9,2	5??126,1.28,
1,164??1.54,  169,159?.?17  213??238.,22  232,223?.?24	5,221??2.31,
,123,120.??1  ??170,16.2,1  ,214,201.??2  ,233,223.??2	5,259??2.53,
,123??12.9,1  ,171,162.??1  ,214??22.1,2  ?238,230.,22	8,168??1.87,
124??121.,12  ,171,162.??1  ,216??23.8,2  ??269,25.8,2	9??171,1.64,
?124,125.,12  ??176,16.8,1  2,165,15.7??  3,124,12.0??	9??195,1.85,
,127,123.??1  ,178??18.5,1  217,206?.?22  3,154??1.61,	9??268,2.58,
??128,13.0,1  189??200.,19  2??183,1.75,  3,212??2.40,
129,124?.?12  ?191,182.,17  2??183,1.75,  3??228,2.17,
?142,143.,13  ,197,184.??2  2??226,2.15,  3,232,21.9??
So datalog.txt is missing, instead, the sensor values appear as some sort of file names. I have reproduced this behavior multiple times, after re-formating the card. What's wrong here? Is it the card? Or the formatting? Or the code?

Thanks for taking the time to read my post and for helping me with that issue!

==================================
CardInfo.ino:

Code: Select all

/*
  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.
 	
 The circuit:
 * SD card attached to SPI bus as follows:
 ** UNO:  MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 4 (CS pin can be changed)
  and pin #10 (SS) must be an output
 ** Mega:  MOSI - pin 51, MISO - pin 50, CLK - pin 52, CS - pin 4 (CS pin can be changed)
  and pin #52 (SS) must be an output
 ** Leonardo: Connect to hardware SPI via the ICSP header
 		Pin 4 used here for consistency with other Arduino examples

 
 created  28 Mar 2011  by Limor Fried 
 modified 9 Apr 2012   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;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 5;    

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(SS, OUTPUT);


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  while (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
  } 
  
  // print the type of card
  Serial.print("\nCard 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");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  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(void) {
  
}
Datalogger.ino:

Code: Select all

/*
  SD card datalogger
 
 This example shows how to log data from three analog sensors 
 to an SD card using the SD library.
 	
 The circuit:
 * SD card attached to SPI bus as follows:
 ** UNO:  MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 4 (CS pin can be changed)
  and pin #10 (SS) must be an output
 ** Mega:  MOSI - pin 51, MISO - pin 50, CLK - pin 52, CS - pin 4 (CS pin can be changed)
  and pin #52 (SS) must be an output
 ** Leonardo: Connect to hardware SPI via the ICSP header
 		Pin 4 used here for consistency with other Arduino examples
 
 created  24 Nov 2010
 modified 9 Apr 2012 by Tom Igoe
 
 This example code is in the public domain.
 	 
 */

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

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 5;

File dataFile;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(SS, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1) ;
  }
  Serial.println("card initialized.");
  
  // Open up the file we're going to log to!
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (! dataFile) {
    Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
    while (1) ;
  }
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }

  dataFile.println(dataString);

  // print to the serial port too:
  Serial.println(dataString);
  
  // The following line will 'save' the file to the SD card after every
  // line of data - this will use more power and slow down how much data
  // you can read but it's safer! 
  // If you want to speed up the system, remove the call to flush() and it
  // will save the file only every 512 bytes - every time a sector on the 
  // SD card is filled with data.
  dataFile.flush();
  
  // Take 1 measurement every 500 milliseconds
  delay(500);
}
Last edited by K3A on Thu Mar 13, 2014 4:42 am, edited 1 time in total.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Datalogger example messes up SD card

Post by adafruit_support_bill »

Not sure what is going on there. It looks like maybe logging data has been written to a directory block somehow.

We do recommend using the SD association formatter. According to the author of the SD library, all of the major OS formatters diverge from the standard somewhat. On a resource limited platform like the Arduino, it is not practical to build all the workarounds into the library.

What are you using to power the system? Writing takes significantly more power than reading. So if power is an issue, errors are more likely to occur during a write.

K3A
 
Posts: 3
Joined: Wed Mar 12, 2014 6:54 am

Re: Datalogger example messes up SD card

Post by K3A »

OK, so here's the solution:

I dusted off an old windows box and installed the official SDFormatter™. The tool (on windows 7) only formats FAT32. I thought I could just give it a try. And YAY, success. The Datalogger example even creates the textfile for me and writes all data neatly into that file.
BUT: Still it's not FAT16 as recommended in your tutorial. So I thought THAT might actually have been the problem. So I formatted the SD card in gparted as FAT32 and surprise: The Datalogger works like a charm. I don't know if that also applies to cards up to 2 GB, as in the tutorial, but for my 4GB card, FAT32 works fine, FAT16 does NOT work properly.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Datalogger example messes up SD card

Post by adafruit_support_bill »

Still it's not FAT16 as recommended in your tutorial.
The tutorial does recommend 16 or 32 here. Is there a place where it specifies FAT16 only?
FAT16 does NOT work properly.
The library has supported (properly formatted) FAT16 since first published (The author of the library still posts on these forums as "fat16lib")
And we have tested this to work with both.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Datalogger example messes up SD card

Post by adafruit_support_bill »


K3A
 
Posts: 3
Joined: Wed Mar 12, 2014 6:54 am

Re: Datalogger example messes up SD card

Post by K3A »

Well maybe it's just an issue with my very SDcard. The important thing is: it works at all, because I basically just wanted to test my design. Thanks!

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”