AdSense

Sunday, 8 September 2013

Read and write SD cards with Arduino

If you want to use your Arduino as a datalogger, you might face the problem where to store the logged data. The best way to deal with it is storing it on a SD card. The data is safe even if the Arduino is powered off, you can connect the card directly to your computer and read the data for example with Matlab oder Excel.

Hardware

On Ebay you can find very cheap SD card modules for Arduino. I bought the module by LC Technology:
Pin mapping is clearly visible. There are pin for voltage supply (+5V, +3.3V and GND) and for SPI-bus which is used to read and write the SD card. The pins in the upper row are connected to the pins in the lower row. SD cards work with a voltage level of 3.3V. The module can be supplied with either 3.3V or 5V (a voltage regulator is included). There is NO level converter for the SPI pins so you MUST NOT connect these pins directly to your Arduino. You would destroy your card.



The module is supplied with 5V by the Arduino. The SPI pins are connected using a level converter:
MOSI to Pin 11
MISO to Pin 12
SCK to Pin 13
CS to Pin 4

I used a bi-directional level converter and converted all of the pins. Both things are technically not necessary. You could use a converter that only converts for 5V to 3.3V (e.g. 74HC4050) and you only have to convert MOSI, SCK and CS. MISO can be connected directly to the Arduino.

When everything is wired correctly, you can put a SD card into the module. The card has to be formated as FAT16 or FAT32. According to the Arduino reference FAT16 is preferred. 

Software

The SD-library for Arduino brings several examples to test your hardware. I chose the example "datalogger" which writes the values of three analog inputs to a txt-file on the SD card.

#include <SD.h>

const int chipSelect = 4;

void setup()
{
 // Open serial communications and wait for port to open:
  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");
  } 
}

In setup()-function a serial connection is established, the command SD.begin(chipSelect) initializes the SD card. The parameter is the pin CS is connected to. If initialization was succesfull we continuer to loop(). Here the values of the analog inputs are read and saved to a string variable. With the command SD.open() the file "datalog.txt" is opened in write mode. If the file was opened succesfull, the value of the string variable is wirtten to the file and the file is closed.

Reading files on the card is pretty easy, too:

  dataFile = SD.open("test.txt");
  if (dataFile) {
    Serial.println("test.txt:");
    
    // read from the file until there's nothing else in it:
    while (dataFile.available()) {
     Serial.write(dataFile.read());
    }
    // close the file:
    data.close();
  } else {
   // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

At first the file is opened with the open()-command. Then it can be read line by line with read() until the end of the file is reached (this is checked with the available()-command). In the end, the file is closed with close().

No comments:

Post a Comment