Integrating a Micro SD card

I’ve been trying to get my Micro SD card to record data from an accelerometer I have on my arduino, with the Mayhew labs Mux Shield and a libelium.com SD card.

I’m attempting to pick up a project that was left behind for me to finish this semester, and am rather lost. Any help would be much appreciated.

There is also some strain gauges that are going to be hooked up before too long, but I’m going to tackle that at a later date.

Here is the code that they left for me

// BST DATA AQUISITION SYSTEM 
//this code was written Spring 2010



/* THINGS TO KNOW
Serial.print prints to the computer
File.print   prints to the Micro SD Card
*/

// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL  100 // mills between entries
#define SENSOR_COUNT     6 // number of analog pins to log
#define ECHO_TO_SERIAL   0 // echo data to serial port 1=on 0=off (turn this on if you want values to print to the computer screen)
#define WAIT_TO_START    0 // Wait for serial input in setup() 1=on 0=off 
#define SYNC_INTERVAL 1000 // mills between calls to sync()
uint32_t syncTime = 0;     // time of last sync()

// this library is for the accelerometer
#include <Wire.h>
// these librarys make the card reader work
#include <SdFat.h>
#include <SdFatUtil.h>

//Give convenient names to the control pins for multiplexer
#define CONTROL0 5    
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

// accelerometer definitions
#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)      //num of bytes we are going to read each time (two bytes for each axis)



//Create arrays for data from the the MUXs
//See the Arduino Array Reference: http://www.arduino.cc/en/Reference/Array
int data0[16];
int data1[16];
int data2[16];


// card prep
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

//accelerometer prep
byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];          //string buffer to transform data before sending it to the serial port


// store error strings in flash to save RAM these errors are from the card reader if something is wrong
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup(void)
{
  
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  digitalWrite (8, HIGH);
  Wire.begin();        // join i2c bus 

  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);      
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);

  

  
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  if (!card.init(true)) error("card.init");
  
  // initialize a FAT volume
  if (!volume.init(card)) error("volume.init");
  
  // open root directory
  if (!root.openRoot(volume)) error("openRoot");
  
  // create a new file
  char name[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;
  }
  if (!file.isOpen()) error ("file.create");
  
  Serial.print("Logging to: ");
  Serial.println(name);

  // write header in file this is automaticaly commented out so matlab will be happy
  file.writeError = 0;
  file.print("%millis");
  file.print(" ,x");
  file.print(" ,y");
  file.print(" ,z");
#if ECHO_TO_SERIAL 
  Serial.print("%millis");
  Serial.print(" ,x");
  Serial.print(" ,y");
  Serial.print(" ,z");
#endif //ECHO_TO_SERIAL

#if SENSOR_COUNT > 15
#error SENSOR_COUNT too large
#endif //SENSOR_COUNT

  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    file.print(" ,sens");file.print(i, DEC);    
#if ECHO_TO_SERIAL
    Serial.print(" ,sens");Serial.print(i, DEC);
#endif //ECHO_TO_SERIAL
  }
  file.println();  
#if ECHO_TO_SERIAL
  Serial.println();
#endif  //ECHO_TO_SERIAL

  if (file.writeError || !file.sync()) {
    error("write header");
  }
}

void loop(void)
{
  // clear print error
  file.writeError = 0;
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
  // log time
  uint32_t m = millis();
  file.print(m);  
#if ECHO_TO_SERIAL
  Serial.print(m);
#endif //ECHO_TO_SERIAL

//Read Data From Accelerometer      
  int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345
  int x, y, z;
  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
   //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!

   //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];   
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];

 
  //we send the x y z values as a string to the card
    file.print(',');    
    file.print(x);
    file.print(',');
    file.print(y);
    file.print(',');
    file.print(z);
  //we send the x y z values as a string to the serial port
  #if ECHO_TO_SERIAL
    Serial.print(',');   
    Serial.print(x);
    Serial.print(',');   
    Serial.print(y);
    Serial.print(',');   
    Serial.print(z);
  #endif //ECHO_TO_SERIAL


    //This for loop is used to scroll through and store the 16 inputs on the FIRST multiplexer ** to add the other multiplexers copy and past the loop and change data0 to the correct number (1 or 2)
  for (uint8_t i=0; i< SENSOR_COUNT; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    //See the Arduino Bitwise AND Reference: http://www.arduino.cc/en/Reference/BitwiseAnd
    //See the Aruino Bitshift Reference: http://www.arduino.cc/en/Reference/Bitshift
    digitalWrite(CONTROL0, (i&15)>>3); 
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
    
    //Read and store the input value at a location in the array
    data0[i] = analogRead(0);
  
    file.print(',');    
    file.print(data0[i]);
#if ECHO_TO_SERIAL
    Serial.print(',');   
    Serial.print(data0[i]);
#endif //ECHO_TO_SERIAL
  }
    file.println();  
  #if ECHO_TO_SERIAL
    Serial.println();
  #endif //ECHO_TO_SERIAL

  if (file.writeError) error("write data");
  
  //don't sync too often - requires 2048 bytes of I/O to SD card
  if ((millis() - syncTime) <  SYNC_INTERVAL) return;
  syncTime = millis();
  if (!file.sync()) error("sync");
}

//---------------- Functions to read the data from the ADXL345

//Writes values to address register on the Accelerometer
void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device 
   Wire.send(address);        // send register address
   Wire.send(val);        // send value to write
   Wire.endTransmission(); //end transmission
}


//reads num bytes starting from address register on device in to buff array

void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device 
  Wire.send(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device
  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
  { 
    buff[i] = Wire.receive(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

And here are the errors when I try to compile

DAQ_02.cpp:28:19: error: SdFat.h: No such file or directory
DAQ_02.cpp:29:23: error: SdFatUtil.h: No such file or directory
DAQ_02:44: error: 'Sd2Card' does not name a type
DAQ_02:45: error: 'SdVolume' does not name a type
DAQ_02:46: error: 'SdFile' does not name a type
DAQ_02:47: error: 'SdFile' does not name a type
DAQ_02.cpp: In function 'void error_P(const char*)':
DAQ_02:58: error: 'PgmPrint' was not declared in this scope
DAQ_02:59: error: 'SerialPrintln_P' was not declared in this scope
DAQ_02:60: error: 'card' was not declared in this scope
DAQ_02.cpp: In function 'void setup()':
DAQ_02:91: error: 'card' was not declared in this scope
DAQ_02:91: error: 'PSTR' was not declared in this scope
DAQ_02:94: error: 'volume' was not declared in this scope
DAQ_02:94: error: 'card' was not declared in this scope
DAQ_02:94: error: 'PSTR' was not declared in this scope
DAQ_02:97: error: 'root' was not declared in this scope
DAQ_02:97: error: 'volume' was not declared in this scope
DAQ_02:97: error: 'PSTR' was not declared in this scope
DAQ_02:104: error: 'file' was not declared in this scope
DAQ_02:104: error: 'root' was not declared in this scope
DAQ_02:104: error: 'O_CREAT' was not declared in this scope
DAQ_02:104: error: 'O_EXCL' was not declared in this scope
DAQ_02:104: error: 'O_WRITE' was not declared in this scope
DAQ_02:106: error: 'file' was not declared in this scope
DAQ_02:106: error: 'PSTR' was not declared in this scope
DAQ_02:112: error: 'file' was not declared in this scope
DAQ_02:140: error: 'PSTR' was not declared in this scope
DAQ_02.cpp: In function 'void loop()':
DAQ_02:147: error: 'file' was not declared in this scope
DAQ_02:213: error: 'PSTR' was not declared in this scope
DAQ_02:218: error: 'PSTR' was not declared in this scope
DAQ_02.cpp:28:19: error: SdFat.h: No such file or directory
DAQ_02.cpp:29:23: error: SdFatUtil.h: No such file or directory

Have you placed the SD Card library in the right place?

Well that is a very valid question, and me being very new to this, wouldn't have a clue where to put it. Or even where it should be downloaded from?

Thanks for the help

Well that is a very valid question, and me being very new to this, wouldn't have a clue where to put it. Or even where it should be downloaded from?

On this page: http://www.cooking-hacks.com/index.php/shop/arduino/microsd-2gb-module-for-arduino.html there is a link to http://blushingboy.net/p/SDuFAT/

If you don't mind changing shields... the one I am going to suggest is not very expensive (about $20, w/ p&p)... then you can have an SD card on your Arduino easily....

Details at:

http://sheepdogguides.com/arduino/ar3ne1sd.htm

(You MIGHT even find Good Bits in that for the shield you have... but with the recommended shield, things will Just Work. And it will have a real time clock for your use, too.)

(The shield the tutorial applies to is the nuElectronics Datalogging Shield)

I have inserted the library into the Arduino's library list, and when I hit include, it included three lines that were already in the previous code. When I hit compile, I got the same errors.

So I have put the library in the right spot, and am still getting the same errors even after the re-downloading them and and then extracting the files into the library location.

The sheepdogguides page gives links to an alternate library, if you come to the end of your patience with the "official" library.

I had the same problem. I found the needed header files and made a copy of them in the parent directory and it worked.

I was inserting SD*u*Fat, but in the code they called SDfat.

Simple but stupid :(