Data logging ADXL335 accelerometer values to SD card?

I wrote the code to read & serial print accelerometer values in Gs, I need to log the same data on a SD card so I can put the whole setup on a RC car to measure cornering forces.
I have all the necessary hardware required, just need to add the datalogging part to the code. Never worked with SD cards before, I checked a few examples to understand how it works, but couldn't grasp it even duly. :fearful:
Someone help me out?

const int xpin = A0;                 
const int ypin = A1;                  
const int zpin = A2;  
void setup()
{
  Serial.begin (9800);
}
void loop()
{
  int x = analogRead(xpin);
    delay(1); 
   
  int y = analogRead(ypin);
    delay(1); 

  int z = analogRead(zpin);

  float zeroG = 512.0;
  float scale = -105; 

  
 float xAxis= (((float)x - zeroG)/scale);
  Serial.print (xAxis);
  Serial.print("\t");

 float yAxis= (((float)y - zeroG)/scale);
  Serial.print (yAxis);
  Serial.print("\t");
  
float zAxis= (((float)z - zeroG)/scale);
  Serial.print(zAxis);
  Serial.print("\n");  
  delay(200);
}

Someone help me out?

What have you tried? Do any of the examples point you in the right direction?

I have all the necessary hardware required

Oh? You don't think that it is necessary to tell us what that hardware consists of, or how it is connected?

May I suggest that you look into 24LCV1024 SPI Ram chips for your data storage as an alternative to SD card since , in your application, you are not necessarily writhing files? They are easy to interface, fast, and can be made non-volatile with a 1.5V battery. Each chip holds 128K bytes (64K samples). The code to use them will be much smaller than SDFat or other libraries.

PaulS, I tried the datalogging examples from the Arduino IDE, it worked fine. I tried to understand how it works and use a similar code structure for my application, I couldn't .

As for the hardware, I made a SD card breakout board with the necessary level shifting circuit, I have tested it and it works, I have an Arduino Uno W/ATmega 328P and ADXL335 accelerometer. I cannot think what other hardware is necessary to make this work besides what I already have.

As for how the connections are made, the SD card wiring pattern is same as what's suggested in the Arduino SD examples. The ADXL335's X, Y & Z axes are connected to analog pins A0, A1 and A2, respectively.

groundfungus, Thanks for the suggestion. I think I'll stick to SD cards, I intend to plot a graph on Processing using the datalog, it's less complicated to read data on my laptop if it's an SD card.

The main reason that I suggest SPI RAM is the speed and code size. I built a datalogger myself with SD and found that it was not fast enough for what I wanted and SDFat sucked up too much sram.

I tried the datalogging examples from the Arduino IDE

Which one(s)?

I tried to understand how it works and use a similar code structure for my application, I couldn't .

I guess I don't see what is difficult to understand about File::print(). The method actually comes from the Print class which is the basis for many other classes, like HardwareSerial.

Post what you have tried, and describe what is wrong about the code/results/file contents.

groundfungus, Thanks for the info! I'll give it a try with the SD card before I try your suggestion.

PaulS, I tried the "datalogger" example from the SD library.

Here's the code I wrote for the accelerometer data logging.
I think the error in the code is because I'm trying to write a float value to the file and the String() doesn't accept floating point values.
I looked up the forum for a solution and I found dtostrf() applicable for my code, going to try it soon.
I'm open to other solutions/alternatives too.

#include <SD.h>
const int chipSelect = 10;
File gFile;
 
void setup()
{
  Serial.begin (9800);
  pinMode(SS, OUTPUT);
  gFile = SD.open("gLog.txt", FILE_WRITE);
}
void loop()
{
  String gString = "";   
 

  float zeroG = 512.0;
  float scale = -105; 

  for (int gPin = 0; gPin < 3; gPin++ )
  {
 int gSensor = analogRead (gPin);
  float gValue= (((float)gSensor - zeroG)/scale);
  gString + = String (gValue);
  if (gPin < 2)
  {
    gString+ = ",";
  }
  }
  gFile.println (gString);
  
  Serial.println (gString);
  Serial.print ("\t");
  gFile.flush();
  delay (200);
}

I think the error in the code is because I'm trying to write a float value to the file and the String() doesn't accept floating point values.

It doesn't. So don't use Strings. Write the value to the file. Write the comma and space to the file. No Strings needed that piss away resources.

I tried the dtostrf () function and it's working. I'm able to log the values to SD card.

#include <SD.h> 
const int chipSelect = 10;
File dataFile;
char buffer [5];
float gValue;
int gPin;
 
void setup()
{
  Serial.begin (9800);
  Serial.print("Initializing SD card...");
  pinMode(SS, OUTPUT);
  if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  }
  Serial.println("card initialized.");
  dataFile = SD.open("gLog.txt", FILE_WRITE);
  if (! dataFile) {
  Serial.println("error opening datalog.txt");
  while (1) ;
  }
}
void loop()
{   
  float zeroG = 512.0;
  float scale = -105; 

  for (gPin = 0; gPin < 3; gPin++ )
  {
 int gSensor = analogRead (gPin);
  gValue= (((float)gSensor - zeroG)/scale);
  }
  
  dtostrf(gValue, 2, 1, buffer);
  
  dataFile.println (buffer);
  
  Serial.println (buffer);
  Serial.print ("\t");
  dataFile.flush();
  delay (200);
}

I get a column of values, not able to differentiate between the axes. If I could add a comma in between the output of each axis, it's going to be easy to read, like for example: 1.2 , 1.4 , 1.7. I tried to add this line in the code, I get errors. How do I write the comma/ space to file? HELP.

if (gPin < 2)
{
gValue += ",";
}

I tried the dtostrf () function and it's working.

But, it was unnecessary, since the File class, which derives from the Print class, knows how to deal with floats.

If I could add a comma in between the output of each axis, it's going to be easy to read

Then, why don't you?

  for (gPin = 0; gPin < 3; gPin++ )
  {
 int gSensor = analogRead (gPin);
  gValue= (((float)gSensor - zeroG)/scale);
  }

Read each pin, overwriting the value in gSensor and gValue each time. Not terribly useful, if the idea was to print EACH value to the file. Print a comma and space when gPin < 2.

PaulS, thanks a ton! The file.print() function did the trick. 8)
Looking at it now, the code is way simpler than I initially expected it to be.

I'll leave the final code here for anybody who's looking for the same.

#include <SD.h>
const int chipSelect = 10;
File gFile;
const int xPin = A0;                 
const int yPin = A1;                  
const int zPin = A2;  
void setup()
{
  Serial.begin (9800);
  
  Serial.print("Initializing SD card... ");
  
  pinMode(SS, OUTPUT);
  
  if (!SD.begin(chipSelect)) 
  {
    Serial.println("SD card not found... Try again");
    
    while (1) ;
  }
    gFile = SD.open("glog.txt", FILE_WRITE);
  
  if (! gFile) 
  {
    Serial.println("Error opening glog.txt");
     
     while (1) ;
  }
  Serial.println("Data logging initiated");
}
void loop()
{
  int x = analogRead(xPin);
    delay(1); 
   
  int y = analogRead(yPin);
    delay(1); 

  int z = analogRead(zPin);

  float zeroG = 512.00;
  float scale = -105.00; 

  
 float xAxis= (((float)x - zeroG)/scale);
  Serial.print (xAxis);
  Serial.print("\t");
  gFile.print(xAxis);
  gFile.print("\t");

 float yAxis= (((float)y - zeroG)/scale);
  Serial.print (yAxis);
  Serial.print("\t");
  gFile.print(yAxis);
  gFile.print("\t");
  
float zAxis= (((float)z - zeroG)/scale);
  Serial.print(zAxis);
  Serial.print("\n"); 
  gFile.print(zAxis);
  gFile.print("\n"); 
  
  gFile.flush();
  
  delay(300);
  
}