ADXL345 data rate & method to read it

Hi all, I am currently using ADXL345 in my project but i'm little confused about method to read it. I am using library from Arduino-libraries/ADXL345 at master · jenschr/Arduino-libraries · GitHub and want to read it at 100 Hz.
Does the read function on that library guarantee that I will get data every 0.01 s (if I put the read function on main loop) or should I use timer based interrupt every 0.01 s and put the read function on the ISR?

Thanks :slight_smile:

Have you timed the read function?

If fast enough you can do it in the ISR.

For 100x per second I would consider the "blink without delay" technique, but it depends heavily on what other things the uProc has to do..

Can you tell more about the project?

Hi rob, thanks for the reply. I want to make a wireless pedometer using this digital Accelerometer and Arduino UNO.
Yes, I have already measured the time needed to read the data and compared the time when it was using the library and when it wasnt. It required around 4000 us to read the data using the library. Codes to get that value:

#include <Wire.h>
#include <ADXL345.h>

ADXL345 adxl;

const int rangeSetting = 2; // +- 2 G
const double rateSetting = 100.00; // 100 Hz

int x,y,z;
unsigned long int time;

void setup() {
  Serial.begin(9600);
  adxl.powerOn();
  
  adxl.setRangeSetting(rangeSetting);
  adxl.setRate(rateSetting);
    
}

void loop() {
  adxl.readAccel(&x, &y, &z);
  time = micros();
  
  Serial.println(time);
  
  delay(20);
}

Also, I measured the time but didnt use the library and got around 2500 us. It used this codes:

#include <Wire.h>

// Definisi2 ADXL345
#define ACC (0x53)  //Alamat register ADXL345
#define REG_POWER_CTL 0x2D //register Power Control
#define ACC_TO_READ (6)// Axis Accelermoter yg akan dibaca

//unsigned int icr1;
int x,y,z;
int data_acc[3];
int regAddress = 0x32;
byte buff[ACC_TO_READ];
unsigned long time;

void setup() {
  Serial.begin(9600);
  delay(1);
  
  Wire.begin();
  
  
  //mengatur accelerometer agar dalam mode measurement dan menonaktifkan semua
  //fitur powersaving melalui register 0x2D
  Wire.beginTransmission(ACC); //start transmission to ACC 
  Wire.write(REG_POWER_CTL);        // register address: 0x2D
  Wire.write(0x08);        // 0x08
  Wire.endTransmission(); //end transmission
  
  
*/
void loop() {
  //Serial.print("A");
     
  Wire.beginTransmission(ACC);
  Wire.write(regAddress);
  Wire.endTransmission(ACC);
  
  Wire.beginTransmission(ACC);
  Wire.requestFrom(ACC, ACC_TO_READ);
  
  int i = 0;
  while(Wire.available()) {
    buff[i] = Wire.read();
    i++;
  }
  Wire.endTransmission();
  
  //masking!!
  // each axis reading comes in 10 bit resolution, ie 2 bytes
  // thus we are converting both bytes in to int
  data_acc[0] = (((int)buff[1]) << 8) | buff[0];
  data_acc[1] = (((int)buff[3]) << 8) | buff[2];
  data_acc[2] = (((int)buff[5]) << 8) | buff[4];
  
  x = data_acc[0];
  y = data_acc[1];
  z = data_acc[2];
  
  time = micros();
  Serial.println(time);

  
  delay(20);
  
}

I don't know what is in that library, but it should be quite similar to the code which you have in the other example.

Your sample rate is limited by two things:

the rate at which the device samples it's own hardware
the rate at which the I2C operation to the arduino works.

The datasheet for the device has description of it's own sampling process.

One of the interrupt options for the device, is "data ready". It can generate an arduino interrupt
as soon as each measurement is available. That is probably the way to get the fastest overall
sample rate.

Serial.begin(9600); ==> Serial.begin(115200); takes less time :wink:

The lib might be made more generic; include additional features; do float math iso int ...(this causes extra delay)

@fino1990, give this code a try (not tested but you should get it running in no time)

#include <Wire.h>

#define ACC (0x53)                    
#define REG_POWER_CTL 0x2D  
#define ACC_TO_READ (6)    

int x, y, z;

int regAddress = 0x32;

unsigned long lastTime;

void setup()
{
  Serial.begin(115200);
  delay(1);
  setupADXL();
}

void loop()
{
  unsigned long now = millis();
  if (now - lastTime >= 10)               // 100x per second
  {
    lastTime = now();
    readADXL();
    Serial.print(now);
    Serial.print(", ");   
    Serial.print(x)
    Serial.print(", ");
    Serial.print(y)
    Serial.print(", ");
    Serial.println(z);
  }
}

void setupADXL()
{
  Wire.begin();
  Wire.beginTransmission(ACC); 
  Wire.write(REG_POWER_CTL);   
  Wire.write(0x08);
  Wire.endTransmission();
}

bool readADXL() 
{
  byte buff[ACC_TO_READ];
   
  Wire.beginTransmission(ACC);
  Wire.write(regAddress);
  Wire.endTransmission(ACC);
  
  Wire.beginTransmission(ACC);
  Wire.requestFrom(ACC, ACC_TO_READ);
  
  int i = 0;
  while(Wire.available() && i<6) 
  {
    buff[i] = Wire.read();
    i++;
  }
  Wire.endTransmission();
  
  if (i == 6)  // valid read 
  {
    x = (((int)buff[1]) << 8) | buff[0];
    y = (((int)buff[3]) << 8) | buff[2];
    z = (((int)buff[5]) << 8) | buff[4];
    return true;
  }
  return false;
}

Hi michinyon, thanks for the suggestions

michinyon:
Your sample rate is limited by two things:

the rate at which the device samples it's own hardware
the rate at which the I2C operation to the arduino works.

Ohh I see, the ADXL345 data rate is the rate at which the I2C operation to the arduino works while its bandwidth is the rate at which the device samples it's own hardware. Is that right?
So if I set the ADXL345 data rate at 100 Hz, I have to set the Arduino to sample at 200 Hz?

@ robtillaart, I have test the code and measure the execution time. I found that when I set the serial rate at 9600, actually, the longest execution time was not when it did the read function but at the serial print. I think this is my problem and speed up the serial rate solved it.

So if I set the ADXL345 data rate at 100 Hz, I have to set the Arduino to sample at 200 Hz?

No, thats not what I meant at all. The point is, your maximum possible data acqusition rate is limited
to whatever is the worst of the possible constraints.

For example, if a GPS device only updates it's position once each second, then there is not much point in
asking it for the position 100 times a second, even if the communication method in use enables that to happen.

Conversely, some device might generate millions of samples a second, but if the communication process only
enables you to enquire and get a response 20 times a second, then that is the sample rate which you
will get.

Okay, I got it. Thanks a lot for the answers :slight_smile: