SDHC Datalogging

Hi,

I use SDHC 4 GB SD card using reading digital data from potentiometer. The problem is here that i just get three or four samples of data and writing to SD card stops but when I write a simple text it keeps writing at a high speed. What could be the problem?
I am using the following code.
/*
SD card datalogger

This example shows how to log data from three analog sensors
to an SD card using the SD library.

The circuit:

  • analog sensors on analog ins 0, 1, and 2
  • SD card attached to SPI bus as follows:
    ** MOSI - pin 11
    ** MISO - pin 12
    ** CLK - pin 13
    ** CS - pin 4

created 24 Nov 2010
updated 2 Dec 2010
by Tom Igoe

This example code is in the public domain.

*/

#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 = 4;

void setup()
{
Serial.begin(9600);
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(10, 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:
return;
}
Serial.println("card initialized.");
}

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 += ",";
}
}

// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);

// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}

What could be the problem?

String dataString = "";

There is little memory available on the Arduino. The String class badly fragments that little bit of memory. The free() function that the destructor uses trashes what little isn't badly fragmented.

Therefore, you should NOT be using the String class.

With what you are doing, there is no reason to. Open the file, then read each pin, write the value to the file, write the comma and space, if not at the last pin, then close the file. No need to store all the data into a String.

Nick Gammon also provided a good work around to fix the heap allocation problems that affect all dynamic memory use on Arduino, not just strings.

search malloc and his name and the thread should come up.

IIRC, Paul Stoffregen not only researched this bug thoroughly but also submitted a fix to the Arduino core that for whatever reason was not adopted. See here.

I too have been bitten by the String bugs. I don't know enough about the topic to comment intelligently re: the motivation of the Arduino team not to take over the proposed changes wholesale, but I do plan to do two things: apply the teensy fixes to malloc, etc. followed by sending Paul a direct contribution.

I hear that serious programmers rely on char arrays and so on instead of Strings, but boy are Strings convenient, easy to use, etc for novices like myself.

but boy are Strings convenient, easy to use, etc for novices like myself.

If you look at the String source and header files, you'll find that there is nothing magic about the class. A couple of days experimenting with all the functions defined in the string.h file will enable you to understand how to do all the stuff that the String class does, without the overhead of dynamic memory allocation. After all, there are really very few cases where a fixed length string doesn't make more sense.

Hi Paul,

One big plus re: Strings for me, its the ease with which one can mix and match things going into strings, easily append, etc. For example, on my GPRS module, I created a function that executes an AT command and then waits x number of millis for the modem / GSM network to respond while printing out the replies. With Strings, sending such commands is incredibly easy. With a char array, I'd have to work out ahead of time what the max length is that could be sent, right? Similarly, my 'duinos datalog to SD card with the main module. With a string being written, I do not have to worry re: dates, values, etc. causing a potential overflow, it just works.

So while I understand your point, I somewhat shake my head re: the IDE including a class that is known to be faulty and for which someone has submitted a fix which has been proven to work as a drop-in replacement for 2 years, which consumes fewer resources than the original class, etc.