ADXL 345 - 335 DAQ (speed problem)

Hi everyone, im working on a project in wich i have to make an DAQ to measure acceleration, storing the data (3 axis) in a file with an SD module.
Ive been working with arduino Sketching (I have no idea programming in low level C), and im having problems with the Sample rate (time between measurements). i will expose the cases:

  1. ADXL335:
    code:
#include <SPI.h>
#include <SD.h>
int x,y,z=0;
String dataString = ""; 
String timestamp = "";
File dataFile;
const int chipSelect=4;
const int boton=8;
int lastButtonState = LOW;
int lastDebounceTime;
int const debounceDelay=30;
int reading=0;
int i=1;
 
 
void setup() {
  // put your setup code here, to run once:
pinMode(boton,INPUT);
analogReference(EXTERNAL);
Serial.begin(9600);
 
if (!SD.begin(chipSelect)) {                               //Check si se reconoce tarjeta SD
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");                     //Check si se reconoce tarjeta SD                      
                 
if (SD.exists("datalog.txt")) {
    Serial.println("datalog.txt existe.");
  } else {
    Serial.println("datalog.txt no existe.");
    delay(1000);
    //dataFile = SD.open("datalog.txt", FILE_READ);
    //Serial.println("Archivo datalog.txt creado");
    dataFile.close();
    delay(2000);
    }
 
 
}
void loop() {
  reading = digitalRead(boton);
  if (reading==1){
    Serial.println("iniciando Lectura/Escritura de datos");
    i=1;
    delay(2000);
    if (SD.exists("datalog.txt")){
      Serial.println("Removing example.txt...");
      SD.remove("datalog.txt");
      delay(800);
    }
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    Serial.println("datalog.txt se a abierto tipo FILE_WRITE");
    read_xyz();
    dataFile.close();
  }


}
 
void read_xyz(){
  while (i==1){
    timestamp=String(micros());
    x = analogRead(0);
    y = analogRead(1);
    z = analogRead(2);
    dataString= timestamp + "," + String(x) + "," + String(y)+ "," + String(z);
    if (dataFile) { 
      dataFile.println(dataString);
      //Serial.println(dataString);
      reading = digitalRead(boton);
      if (reading==1){
          dataFile.close();
          Serial.println("cerrando archivo.");
          delay(300);
          Serial.println("cerrando archivo..");
          delay(300);
          Serial.println("cerrando archivo...");
          delay(300);
          Serial.println("cerrando archivo....");
          delay(300);
          Serial.println("cerrando archivo.....");
          delay(300);
          Serial.println("Archivo Cerrado");          
          i=0;
          delay(1000);
          
      }
    }
  
  

      else {
        Serial.println("error opening datalog.txt");
      }
  }
 
}

this one is with ADXL335 (analog device), no prescaller set or anything weird, just with IDE of Arduino, the result was:

the most frequent sample time is aprox. 2 ms.

  1. ADXL 345 (I2C protocoll)
    code:
# include <Wire.h>;

//Comunicacion I2C con ADXL345:
//Direcciones:
# define DEVICE 0x53
# define DATAX0 0x32
# define DATAX1 0x33
# define DATAY0 0x34  
# define DATAY1 0x35
# define DATAZ0 0x36
# define DATAZ1 0x37
# define DATA_FORMAT 0x31
# define BW_RATE 0x2c
# define POWER_CTL 0x2d
//Esctrituras
# define range_2g 0x0
# define range_4g 0x1
# define range_8g 0x2
# define range_16g 0x3

# define freq_100 0xA
# define freq_200 0xB 
# define freq_400 0xC 
# define freq_800 0xD 
# define freq_1600 0xE 
# define freq_3200 0xF

# define measure_on  0x8
# define measure_off  0x0

//Declaracion de variables:
byte rango_seleccionado;
byte _buff[6];
int ser_read=0;
int i=1;



void setup() {
  
  Wire.begin();
  Serial.begin (9600);  
  writeTo(POWER_CTL,measure_on);
  Serial.println("seleccionar rango de medicion (2, 4, 8, 16 g): "); 
  while(i==1){
    ser_read=Serial.parseInt();
    if (Serial.available()>0){
      Serial.print("Se ha seleccionado un rango de: ");
      Serial.print(ser_read); Serial.println(" g");          
      delay(100);      
      i=2;
    }
  }
 
  if (ser_read==2){
    writeTo(DATA_FORMAT, range_2g);correspondiente
    Serial.print("hola 2");
    delay(500);
  }
  else if (ser_read==4){
    writeTo(DATA_FORMAT, range_4g);    
  }
  else if (ser_read==8){
    writeTo(DATA_FORMAT, range_8g);    
  }
  else if (ser_read==16){
    writeTo(DATA_FORMAT, range_16g);
  }  

    Serial.println("seleccionar frequencia maxima (100, 200, 400, 800, 1600, 3200) [Hz]: ");
    
  while(i==2){
    ser_read= Serial.parseInt();
    if (Serial.available()>0){   
      Serial.print("Se ha seleccionado una frecuancua de: ");
      Serial.print(ser_read); Serial.println(" g");
      delay(100);
      i=3;    
    }
  }
  if (ser_read==100){ correspondiente
    writeTo(BW_RATE, freq_100);  
  }
  else if (ser_read==200){
    writeTo(BW_RATE, freq_200);
  }
  else if (ser_read==400){
    writeTo(BW_RATE, freq_400);
    Serial.print("hola 100");
    delay(500);
  }
  else if (ser_read==800){
    writeTo(BW_RATE, freq_800);     
  } 
  else if (ser_read==1600){     
    writeTo(BW_RATE, freq_1600);
  }
} 

 

void loop() {
  
  uint8_t howManyBytesToRead=6;
  ReadFrom( DATAX0, howManyBytesToRead, _buff);
  int x = (((int)_buff[1]) << 8) | _buff[0];
  int y = (((int)_buff[3]) << 8) | _buff[2];          //
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z);
}  


void writeTo(byte address, byte val) {
  
  Wire.beginTransmission(DEVICE);
  Wire.write(address);
  Wire.write(val);
  Wire.endTransmission();
}


void ReadFrom(byte address, int num, byte _buff[]) {
  
  Wire.beginTransmission(DEVICE); 
  Wire.write(address);
  Wire.endTransmission();
  Wire.beginTransmission(DEVICE)
  Wire.requestFrom(DEVICE, num);
  int j = 0;
  while(Wire.available())                            
  { 
    _buff[j] = Wire.read();                          
    j++;
  }
  Wire.endTransmission();

result:

the most frequent sample time is aprox. 2 ms. (same as 335)

i was reading a bit of SD modules and i found a library with a C programmed datalog (fatlib16) (i understand 1/3 of the code xD! ), i tried it out and i figured out that the sample rate was not improving at all. this library works with interrupt and i was able to get a 30 ms between sample with no problems, if i changed it to a faster sample rate the program collapsed (if i ran it with a 1ms per measure, the program only saved 1 measurement in the .csv file)
i bought an new microSD card Kingstone Serie 4.
the program code:

the result with ADXL335 and the code show before was almost the same:

almost same 2ms between samples.

I cant figure out how to improve this time, i need a sample rate of 2000 Hz → 0.5 ms.

please someone guide me!
regards everyone!

Find out what's the bottleneck:

  • data acquisition from sensor
  • data processing
  • data output

Also the many delay() may slow down everything.