Go Down

Topic: ADXL345 I2C communication (Read 58 times) previous topic - next topic

Vink

Hello everyone,

I'm currently working with a 9DOF Razor IMU (https://www.sparkfun.com/products/10736).

On this board an ADXL345 is connected to an Atmega328. The two units communicate through I2C protocol.

The problem is, when I read the content of a register, say (0x00 = device ID), I get 4 bytes returned instead of one.

The ID of the ADXL345 is defined in the datasheet:
Code: [Select]
ID_ADXL:1110 0101

When I read the register I get;
Code: [Select]
ID_ADXL: 1111 1111 1111 1111 1111 1111 1110 0101

This is how I read the register;
Code: [Select]
char id_adxl=0;
  id_adxl = i2cRead(adxlAddress, 0x00);
  Serial.print("ID_ADXL: ");
  Serial.println(id_adxl, BIN);


And this is how i2cRead() is defined;
Code: [Select]
unsigned char i2cRead(char address, char registerAddress)
{
  //This variable will hold the contents read from the i2c device.
  unsigned char data=0;
 
  //Send the register address to be read.
  Wire.beginTransmission(address);
  //Send the Register Address
  Wire.write(registerAddress);
  //End the communication sequence.
  Wire.endTransmission();
 
  //Ask the I2C device for data
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 1);
 
  //Wait for a response from the I2C device
  if(Wire.available()){
    //Save the data sent from the I2C device
    data = Wire.read();
  }
 
  //End the communication sequence.
  Wire.endTransmission();
 
  //Return the data read during the operation
  return data;
}


I don't understand how these 3 additional bytes are being read in the register?

The ADXL345 supports fast data transfer mode (400kHz) but my arduino Wire.h library is programmed for normal data transfer (100kHz). I thought this could be the reason.

I tried adding:
Code: [Select]
Wire.begin();
TWBR = 12;

to enable fast transfer mode, but the error remains.

Any idea what I could be doing wrong?

Thank you for reading this.

chucktodd

Hello everyone,

I'm currently working with a 9DOF Razor IMU (https://www.sparkfun.com/products/10736).

On this board an ADXL345 is connected to an Atmega328. The two units communicate through I2C protocol.

Thank you for reading this.
You have mis-understood the I2C Wire library.

to send data to an I2C device use :
Code: [Select]

Wire.beginTransmission(i2cAddr);
Wire.write(byteValue);
Wire.endTransmission(sendStop); //Actually send the buffered data to the Slave. 32 byte limit

   // some devices need a repeated-start between
  // setting the register pointer and the read operation.

To receive data from an I2C device use:
Code: [Select]

Wire.requestFrom(i2cAddr,numberOfBytes); //actually transfer data from Slave 32byte limit

uint8_t myBuffer[numberOfBytes];
for(uint8_t i=0;i<numberOfBytes;i++){
  myBuffer[i] = Wire.read(); // transfer from internal Wire buffer to my buffer.
  }


when you coded

Quote
Code: [Select]

/Ask the I2C device for data
  Wire.beginTransmission(address);         // start Transmit operation
  Wire.requestFrom(address, 1);
 
  //Wait for a response from the I2C device
  if(Wire.available()){                                   // the requestFrom will always return
                                                                // the requested amount or Zero if the Slave
                                                                // does not respond.
    //Save the data sent from the I2C device
    data = Wire.read();
  }
 
  //End the communication sequence.
  Wire.endTransmission();                           // actually send a the Transmit buffer (empty)
                                                               // this just a 'attention' call
 

Try this code as your read code:
Code: [Select]

/* read byte from device, return error as negative value
*/
int16_t i2cReadByte(uint8_t i2cAddr, uint8_t regAddr){
uint8_t result = 0;
Wire.beginTransmission(i2cAddr);
Wire.write(regAddr);
uint8_t ec=Wire.endTransmission(false); // don't send the stop use restart

if(ec==0){
  ec = Wire.requestFrom(i2cAddr,1);
  if (ec==0) result = -10; // error no data received
  else result =  Wire.read();
  } 
else result = -ec;
return result;
}



chuck.

DrDiettrich

Eventually the byte is extended to a signed long, when printed?

chucktodd

Eventually the byte is extended to a signed long, when printed?
you are correct, I did not see that.

He must be calling his readByte() like this:
Code: [Select]

long value = readByte();
// and the complier did a sign extension from a 8bit to 32bit negative value!

// so maybe he could change the definition of readByte() to uint8_t readByte() instead of char readByte().




I am chagrined ;)

Chuck.

DrDiettrich

I think that the library only contains one function for outputting a long value. It may help to use "byte" instead of "char" variables.

Go Up