ADXL345 Sampling rate

Hello,
I am trying to measure vibrations with MEMS accelerometer. I used an analog one (GY-61 module) but decided to try a digital accelerometer in order to simplify circuitry. ADXL345 (ADXL345 Hookup Guide - learn.sparkfun.com) seemed to be a good candidate. Wow, the datasheet says something about 3200Hz sampling rate!
...But it turned out to be much worse. By trying an example sketch from SparkFun I found out that the actual sampling rate is about 100Hz - it even sends the same result multiple times via I2C!

Am I doing something wrong? The IC is not in low power mode, but instead configured to work at 6400Hz.

Can you post your code?

I imagine the Arduino is slow to poll the ADXL (unless you are using a hardware interrupt). You might also want to check the register map and see if there are any registers you need to set to increase sample speed.

Q109:
it even sends the same result multiple times via I2C!

Maybe because the ADXL hasn't moved that much since the last reading?

I simply copied the code from SF page (see above), but can repost it here:

 /******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

Serial.begin(9600);                 // Start the serial terminal
Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
Serial.println();

adxl.powerOn();                     // Power on the ADXL345

adxl.setRangeSetting(2);           // Give the range settings
                                    // Accepted values are 2g, 4g, 8g or 16g
                                    // Higher Values = Wider Measurement Range
                                    // Lower Values = Greater Sensitivity

adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                    // Default: Set to 1
                                    // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 

adxl.setActivityXYZ(1, 0, 0);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)

adxl.setInactivityXYZ(1, 0, 0);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
adxl.setTimeInactivity(10);         // How many seconds of no activity is inactive?

adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)

// Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
adxl.setTapThreshold(50);           // 62.5 mg per increment
adxl.setTapDuration(15);            // 625 μs per increment
adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
adxl.setDoubleTapWindow(200);       // 1.25 ms per increment

// Set values for what is considered FREE FALL (0-255)
adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment

// Setting all interupts to take place on INT1 pin
//adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" 
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.

// Turn on Interrupts for each mode (1 == ON, 0 == OFF)
adxl.InactivityINT(1);
adxl.ActivityINT(1);
adxl.FreeFallINT(1);
adxl.doubleTapINT(1);
adxl.singleTapINT(1);

//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt

}

/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

// Accelerometer Readings
int x,y,z;  
adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

// Output Results to Serial
/* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.println(z); 

ADXL_ISR();
// You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR(); 
//  and place it within the loop instead.  
// This may come in handy when it doesn't matter when the action occurs. 

}

No, Arduino turns out to be more than enough fast. Serial monitor gives 4 or 5 identical strings of data, and then again 4 or 5 of a totally different values. Unfortunately I have no screenshots now.
As far as I'm able to tell looking at the register map, the sensor is set to a maximum speed (0x2C is set to 0001111) Or is it? I found that it's never set in the code. Gotta check the register values, brb :slight_smile:

Yea, Ox2C was factory set to 1010b (50Hz). I changed it by

adxl.set_bw(ADXL345_BW_1600);

and things are much better now.