I am the author of SdFat, the base library for SD. Several people have asked me why SD is so slow in Arduino 22 when you use print() for numbers.
Here is the reason SD is so slow and a way to speed it up by a factor of 100.
Print does character at a time writes when it formats numbers. SD has been setup to do a flush after every write.
This means that println(n) will call flush six times for a four digit number, four times for the digits and two times for the new line.
SD cards can only be read or written in 512 byte blocks and SdFat has a single 512 byte buffer.
A flush causes the data block to be written, the directory block to be read, updated and written. The next write requires the data block to be read so it can be updated. This is 2048 bytes of I/O.
Therefore writing the four byte number and a new line requires 12,288 bytes of I/O to the SD card.
This sketch writes 600 bytes to a SD card and takes 7.8 seconds for a rate of 77 bytes/sec. The total I/O to the SD card is 1,228,800 bytes.
#include <SD.h>
File file;
void setup() {
Serial.begin(9600);
SD.begin(10);
file = SD.open("WR_TEST1.TXT", FILE_WRITE);
while(millis() < 1000); // delay so mills() is four digits
for (uint8_t i = 0; i < 100; i++) {
file.println(millis());
}
file.close();
}
void loop() {}
If you replace FILE_WRITE with O_WRITE | O_CREAT and control when flush is called you can increase the speed by a large factor.
This sketch writes 600 bytes to the SD card in 0.070 seconds for a rate of 8,571 bytes/sec.
#include <SD.h>
File file;
void setup() {
Serial.begin(9600);
SD.begin(10);
file = SD.open("WR_TEST2.TXT", O_CREAT | O_WRITE);
while(millis() < 1000); // delay so mills() is four digits
for (uint8_t i = 0; i < 100; i++) {
file.println(millis());
}
// not needed in this example since close() will call flush.
file.flush();
file.close();
}
void loop() {}