ADXL345 I2C

hola gente, les quiero pedir ayuda ya que tengo el siguiente problema:
estoy tratando de tomar los datos de medicion de 3 ejes del sensor adxl345, me base en una libreria que esta colgada en internet y la modifique un poco,

# include <Wire.h>;

//Comunicacion I2C con ADXL345:
//Direcciones:
# define DEVICE 0x53       // Direccion de ADXL345
# define DATAX0 0x32       // LSB de la medicion en el eje ""
# define DATAX1 0x33       // MSB de la medicion en el eje ""
# define DATAX0 0x34  
# define DATAX1 0x35
# define DATAX0 0x36
# define DATAX1 0x37
# define DATA_FORMAT 0x31  //Configuracion del rango de medicion.
# define BW_RATE 0x2c      // Direccion donde se configura frequency sample, para I2C se tiene como limite MAXIMO 800 (Hz), debido a la velocidad de sampleo de 400kHz
# define POWER_CTL 0x2d    // Direccion donde se coloca al sensor en Measure Mode
//Esctrituras
# define range_2g 0x8      //Byte a mandar a DATA_FORMAT
# define range_4g 0x9
# define range_8g 0xA
# define range_16g 0xB    //

# define freq_100 0xA      //Byte a mandar a BW_RATE
# define freq_200 0xB 
# define freq_400 0xC 
# define freq_800 0xD 
# define freq_1600 0xE 
# define freq_3200 0xF     //

# define measure_on  0x8   //pasa de stanby a measure mode
# define measure_off  0x0  //pasa a standby mode

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



void setup() {
  Wire.begin();        // Inicia libreria para comunicacion I2C
  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);   
      Serial.print(ser_read);
      i=2;
    }
  }
 
  if (ser_read==2){
    WriteTo(DATA_FORMAT, range_2g);         //Escribe seleccion de usuario a la Adress 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){                                 //Escribe seleccion de usuario a la Adress 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;                       //Lectura de 6 bytes, 2 por eje
  ReadFrom( DATAX0,howManyBytesToRead, _buff);        //Lectura de los datos, se almazenara en arreglo de 6 bits
  int x = (((int)_buff[1]) << 8) | _buff[0];          // crea variable x a partir de la union entre 2 bytes de informacion del eje, el MSF lo corre 8 unidades
  int y = (((int)_buff[3]) << 8) | _buff[2];
  int z = (((int)_buff[5]) << 8) | _buff[4];          //
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z);
}  


void WriteTo(byte address, byte val) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(address);             // send register address
  Wire.write(val);                 // send value to write
  Wire.endTransmission();         // end transmission
}

void ReadFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(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 j = 0;
  while(Wire.available())         // device may send less than requested (abnormal)
  { 
    _buff[j] = Wire.read();    // receive a byte
    j++;
  }
  Wire.endTransmission();         // end transmission
}

el problema es que me toma solo el primer dato (eje x), el Y y el Z me los deja en 0.
Lo otro que no logro entender es porque no es necesario hacer un Read en la direccion Y y Z del sensor, en el programa del sensor (original) se hace y finciona,lo andjunto

// Cabling for i2c using Sparkfun breakout with a Spar Core
// Spark Core <-> Breakout board
// Gnd         -  GND
// 3.3v        -  VCC
// 3.3v        -  CS
// Digital 0   -  SDA
// Digital 1   -  SCL


#define DEVICE (0x53) // Device address as specified in data sheet 

byte _buff[6];

char POWER_CTL = 0x2D;	//Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32;	//X-Axis Data 0
char DATAX1 = 0x33;	//X-Axis Data 1
char DATAY0 = 0x34;	//Y-Axis Data 0
char DATAY1 = 0x35;	//Y-Axis Data 1
char DATAZ0 = 0x36;	//Z-Axis Data 0
char DATAZ1 = 0x37;	//Z-Axis Data 1

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(57000);  // start serial for output. Make sure you set your Serial Monitor to the same!
  Serial.print("init");
  
  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeTo(DATA_FORMAT, 0x01);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeTo(POWER_CTL, 0x08);
}

void loop()
{
  readAccel(); // read the x/y/z tilt
  delay(500); // only read every 0,5 seconds
}

void readAccel() {
  uint8_t howManyBytesToRead = 6;
  readFrom( DATAX0, howManyBytesToRead, _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
  int x = (((int)_buff[1]) << 8) | _buff[0];   
  int y = (((int)_buff[3]) << 8) | _buff[2];
  int z = (((int)_buff[5]) << 8) | _buff[4];
  Serial.print("x: ");
  Serial.print( x );
  Serial.print(" y: ");
  Serial.print( y );
  Serial.print(" z: ");
  Serial.println( z );
}

void writeTo(byte address, byte val) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(address);             // send register address
  Wire.write(val);                 // send value to write
  Wire.endTransmission();         // end transmission
}

// Reads num bytes starting from address register on device in to _buff array
void readFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(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.read();    // receive a byte
    i++;
  }
  Wire.endTransmission();         // end transmission
}

Saludos!

Para que solo responda 6 bytes y sean suficientes quiere decir que envía enteros o 16 bits por dato. Es asi? Ahora que es esto

//Comunicacion I2C con ADXL345:
//Direcciones:
# define DEVICE 0x53       // Direccion de ADXL345
# define DATAX0 0x32       // LSB de la medicion en el eje ""
# define DATAX1 0x33       // MSB de la medicion en el eje ""
# define DATAX0 0x34  
# define DATAX1 0x35
# define DATAX0 0x36
# define DATAX1 0x37

Defines DATAX0 3 veces y si me quedo con la última por eso lees 2 datos y lo demás en 0. elige una y comenta las demás.

muchas gracias por tu respuesta, si me di cuenta de eso y lo corregi aunque el error siguio finalmente se corrigio por arte de magia, adjunto el codigo final:

# include <Wire.h>;

//Comunicacion I2C con ADXL345:
//Direcciones:
# define DEVICE 0x53       // Direccion de ADXL345
# define DATAX0 0x32       // LSB de la medicion en el eje ""
# define DATAX1 0x33       // MSB de la medicion en el eje ""
# define DATAY0 0x34  
# define DATAY1 0x35
# define DATAZ0 0x36
# define DATAZ1 0x37
# define DATA_FORMAT 0x31  //Configuracion del rango de medicion.
# define BW_RATE 0x2c      // Direccion donde se configura frequency sample, para I2C se tiene como limite MAXIMO 800 (Hz), debido a la velocidad de sampleo de 400kHz
# define POWER_CTL 0x2d    // Direccion donde se coloca al sensor en Measure Mode
//Esctrituras
# define range_2g 0x0      //Byte a mandar a DATA_FORMAT --> Este valor se puede modificar para dejar en FULL_RES las mediciones
# define range_4g 0x1
# define range_8g 0x2
# define range_16g 0x3     //

# define freq_100 0xA      //Byte a mandar a BW_RATE 
# define freq_200 0xB 
# define freq_400 0xC 
# define freq_800 0xD 
# define freq_1600 0xE 
# define freq_3200 0xF     //

# define measure_on  0x8   //pasa de stanby a measure mode
# define measure_off  0x0  //pasa a standby mode

//Declaracion de variables:
byte rango_seleccionado;
byte _buff[6];             //Arreglo donde se almacenaran los datos exraidos del Sensor, 2 Bytes por cada eje
int ser_read=0;
int i=1;



void setup() {
  
  Wire.begin();        // Inicia libreria para comunicacion I2C
  Serial.begin (9600);  
  writeTo(POWER_CTL,measure_on);                                        //Manda al sensor a Measure_on
  Serial.println("seleccionar rango de medicion (2, 4, 8, 16 g): "); 
  while(i==1){
    ser_read=Serial.parseInt();
    if (Serial.available()>0){                                          //Espera Ingreso de datas en puerto Serial    
      Serial.print("Se ha seleccionado un rango de: ");
      Serial.print(ser_read); Serial.println(" g");          
      delay(100);   
      Serial.print(ser_read);
      i=2;
    }
  }
 
  if (ser_read==2){
    writeTo(DATA_FORMAT, range_2g);                   //Escribe seleccion de usuario a la Adress 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){                                 //Escribe seleccion de usuario a la Adress 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;                       //Lectura de 6 bytes, 2 por eje
  ReadFrom( DATAX0, howManyBytesToRead, _buff);       //Lectura de los datos, se almazenara en arreglo de 6 bits
  int x = (((int)_buff[1]) << 8) | _buff[0];          // crea variable x a partir de la union entre 2 bytes de informacion del eje, el MSF lo corre 8 unidades
  int y = (((int)_buff[3]) << 8) | _buff[2];
  int z = (((int)_buff[5]) << 8) | _buff[4];          //
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z);
}  


void writeTo(byte address, byte val) {                //Funcion para la escritura al sensor 
  
  Wire.beginTransmission(DEVICE);                     // Comienza la transmision 
  Wire.write(address);                                // Manda direccion especifica dentro del sensor
  Wire.write(val);                                    // Valor a Escribir
  Wire.endTransmission();                             // fin de la transmicion
}


void ReadFrom(byte address, int num, byte _buff[]) {
  
  Wire.beginTransmission(DEVICE);                     // Comienza la transmision 
  Wire.write(address);                                // Manda direccion especifica dentro del sensor
  Wire.endTransmission();                             // fin de la transmision
  Wire.beginTransmission(DEVICE);                     // Empieza transmicion al sensor
  Wire.requestFrom(DEVICE, num);                      // Hace un request del sensor, num son los numeros de bytes a recibir
  int j = 0;
  while(Wire.available())                             // Verifica disponibilidad de datos
  { 
    _buff[j] = Wire.read();                           // recibe un bit y lo almacena en una parte j del arreglo
    j++;
  }
  Wire.endTransmission();                             // fin de la transmision
}

sin embargo aun me queda la duda de como el programa es capaz de tomar los datos de Y y Z, entiendo que el arreglo y la solicitud de bytes solicitados por el maestro son 6, sin embargo nunca se llaman a las direcciones de Y y Z correspondientes. No se si me explico. Saludos!

muchas gracias por tu respuesta, si me di cuenta de eso y lo corregi aunque el error siguio finalmente se corrigio por arte de magia, adjunto el codigo final:

No hay arte de magia. O se hace bien o no funciona.

A ver… llamas a la primera DATAX0 que esta en 0x32 del IC y pides 6 bytes
Lees x esta formado por un byte MSB (mas significativo) y un LSB (menos signitifcativo) y los demás igual.
Entonces values[0] recibe el byte de DATAX0 y asi sucesivamente.

  readRegister(DATAX0, 6, values);
  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];

al apuntar debidamente a la primera dirección los 6 bytes se llenarán con lo que corresponda y por eso ahora lees los datos. SIN MAGIA, solo por la corrección de apuntar donde corresponde.

Es que ahi radica mi duda, en el manual existen seis direcciones diferentes para cada meidion, cada direccion te entrega un byte, 2 direcciones por eje. Lo que no entiendo es como es posible pedir los 6 bytes de una entrando solo a la direccion DATAX0. Mi logica dice que para obtener todas las mediciones seria necesario entrar a cada direccion para obtener la informacion (solicidar los bytes independientes por cada mediicion). Saludos!

Mal tu lógica. Mira esto

void ReadFrom(byte address, int num, byte _buff[]) {
  
  Wire.beginTransmission(DEVICE);                     // Comienza la transmision 
  Wire.write(address);                                // Manda direccion especifica dentro del sensor
  Wire.endTransmission();                             // fin de la transmision
  Wire.beginTransmission(DEVICE);                     // Empieza transmicion al sensor
  Wire.requestFrom(DEVICE, num);                      // Hace un request del sensor, num son los numeros de bytes a recibir
  int j = 0;
  while(Wire.available())                             // Verifica disponibilidad de datos
  { 
    _buff[j] = Wire.read();                           // recibe un bit y lo almacena en una parte j del arreglo
    j++;
  }
  Wire.endTransmission();                             // fin de la transmision
}

Esta es la rutina a la que le dices, Ehhh lee del ADX los 6 bytes comenzando en DATAX0 y me los devuelves en _buff[] o como lo hayas usado, en tu caso

readRegister(DATAX0, 6, values);

Entonces por I2C se genera una consulta al Dispositivo en la dirección Wire.write(address); y se solicitan los 6 bytes comenzando en 0x32 y terminando en 0x37 perfecto!!