Since I didn’t save my first (overly long) reply, I’ll keep this one short. The major issue(s) with your sketch not achieving the data rates are as follows:
-
The loop() call to read the sensor is not synchronised with the sensor. You may be having to wait for the sensor to be ready to send data.
-
As I am not familiar with the Sparkfun ADXL library, I do not know what assumptions the calls make/do not make. I do not see your I2C bus speed listed.
You need data collection at 1.6kHz or 625 microseconds/cycle. I already had a sketch that reads data from a GY-85 IMU (ADXL345, gyro, and compass) where it queried the chips at separate rates. I clipped out the unneeded portions and tweaked to get it running stably at the 1.6kHz sampling rate (verified on scope, see the attachment) The top trace is the ADXL345 DATA_READY interrupt, the bottom trace is the ISR cycle time (by setting and clearing flag bits).
// GY-85 board - ITG-3205/HMC5388L/ADXL345B
// Adapted fron GetGY85RawData
// This program collects unfiltered raw data from just accelerometer
// Interrupt to take store data in arrays
// Modify integer math to use 16-bit signed as needed
// Added control through multiple interrupts (modified WInterrupts.c to release PIOA,PIOC,PIOD IRQ handlers)
// Added device presence checks
// Accelerometer interupt - PIOC
//
// Xuthus 24 Apr 17
//
// Arduino Pin Assignments
// D36 - (PIO C.4) Accelerometer interrupt input (GY_85 A_INT1)
// D20 - I2C Data (GY-85 SDA)
// D21 - I2C Clock (Gy-85 SCL)
// D13 - (PIO B.27)(internal connection) Accelerometer interrupt flag
// GND - Breadboard 3.3 GND Rail
//
#include <Wire.h>
#define ACC 0x53 // ADXL345 ACC address
#define AccRegAddr 0x32 // First data register address on the ADXL345
// Add calibration factors measured 22 Apr 17
#define AA11 3.941662
#define AA12 0.033395
#define AA13 0.085917
#define AA21 0.033395
#define AA22 4.007295
#define AA23 0.037694
#define AA31 0.085917
#define AA32 0.037694
#define AA33 4.018319
#define AB1 5.702705
#define AB2 -7.150334
#define AB3 -10.167222
#define ARadius 1000
#define G_MS_MG .00980665
volatile float acc[3]; // Accelerometer data array
void setup() {
Serial.begin(921600);
Wire.begin();
Wire.setClock(3500000);
// Initialize ACC
Serial.println("Initialize ADXL345B");
Wire.beginTransmission (ACC);
if (Wire.endTransmission ())
{
Serial.println("Could not find a valid ADXL345B sensor, check wiring!");
while (1) {};
}
// Setup accelerometer
writeTo(ACC, 0x2D, 0x08); // p.25 Power-saving features control
writeTo(ACC, 0x31, 0x00); // p.26 Put device into standby
// Interrupt will be set for active low (DUE input trigger) after DUE PIO interrupt vector set
// otherwise you get a lockup condition.
writeTo(ACC, 0x2C, 0x0E); // p.25 1600Hz data rate and reg power mode control
writeTo(ACC, 0x1E, 0x00); // p.24 X-Axis offset
writeTo(ACC, 0x1F, 0x00); // p.24 Y-Axis offset
writeTo(ACC, 0x20, 0x00); // p.24 Z-Axis offset
writeTo(ACC, 0x38, 0x00); // p.27 Bypass FIFO, Send trigger output to INT2
writeTo(ACC, 0x2F, 0x00); // p.26 Send all interrupts to INT1
writeTo(ACC, 0x2E, 0x00); // p.26 Disable DATA_READY interrupt
// Initialize PIO for output and input triggered interrupt
// Setup blinky lights for each of the interrupts PIOC:B.27/L
REG_PIOB_WPMR = 0x50494F00; // p.674 PIO Write Protect Mode (RW) 32 bit - enable write to PIOB register
REG_PIOB_PER = REG_PIOB_PSR | 1 << 27; // p.633 Enable PIO control / disable peripheral control on port B.27 'L' LED
REG_PIOB_OER = REG_PIOB_OSR | 1 << 27; // p.636 Enable output on port B.27
REG_PIOB_PUDR = REG_PIOB_PUSR | 1 << 27; // p.653 Disable pullup resistor on port B.27
REG_PIOB_CODR = 1 << 27; // Turn off B.27
// Setup interrupt inputs: C.4
REG_PMC_PCER0 = REG_PMC_PCSR0 | 0x2000; // p.542 Turn on PIOC clock, necessary for reading input
REG_PIOC_WPMR = 0x50494F00; // p.674 PIO Write Protect Mode (RW) 32 bit - enable write to PIOC register
REG_PIOC_PER = REG_PIOC_PSR | 1 << 4; // p.633 Enable PIO control / disable peripheral control on port C.4 - Arduino D36
REG_PIOC_ODR = !REG_PIOC_OSR | 1 << 4; // p.637 Enable input on port C.4
REG_PIOC_PUER = !REG_PIOC_PUSR | 1 << 4; // p.654 Enable pullup resistor on port C.4
REG_PIOC_IFDR = !REG_PIOC_IFSR | 1 << 4; // p.640 Disable glitch filter on PIO C.4
REG_PIOC_ESR = !REG_PIOC_ELSR | 1 << 4; // p.668 interrupt source is edge detection on PIO C.4
REG_PIOC_FELLSR = !REG_PIOC_FRLHSR | 1 << 4; // p.671 interrupt source is falling edge detection on PIO C.4
REG_PIOC_AIMER = REG_PIOC_AIMMR | 1 << 4; // p.664 additional interrupt modes enable on PIO C.4
REG_PIOC_IER = REG_PIOC_IMR | 1 << 4; // p.646 enable input change interrupt on PIO C.4
NVIC_EnableIRQ(PIOC_IRQn); // Enable PIOC interrupts
writeTo(ACC, 0x31, 0x2B); // p.26 Full resolution, interrupt high, RJ data format, +/-16G
writeTo(ACC, 0x2E, 0x80); // p.26 Enable DATA_READY interrupt
}
void loop() {
REG_PIOB_CODR = 1 << 27; // Turn off B.27
}
void PIOC_Handler() {
boolean dummy = (REG_PIOC_ISR >> 4); // p. 649 Read PIOC interrupt status, clear register
REG_PIOB_SODR = 1 << 27; // Turn on PIO B.27
byte buff[6];
int16_t temp[3];
//read data from accelerometer into buffer array
readFrom(ACC, AccRegAddr, 6, buff);
// Accelerometer data is Little-endian 16-bit
temp[0] = (int16_t(buff[1]) << 8) | buff[0];
temp[1] = (int16_t(buff[3]) << 8) | buff[2];
temp[2] = (int16_t(buff[5]) << 8) | buff[4];
// Uncomment for raw data
//acc[0] = temp[0];
//acc[1] = temp[1];
//acc[2] = temp[2];
// Uncomment for scaled data
acc[0] = (AA11 * (float(temp[0])-AB1) + AA12 * (float(temp[1])-AB2) + AA13 * (float(temp[2])-AB3)) * G_MS_MG;
acc[1] = (AA21 * (float(temp[0])-AB1) + AA22 * (float(temp[1])-AB2) + AA23 * (float(temp[2])-AB3)) * G_MS_MG;
acc[2] = (AA31 * (float(temp[0])-AB1) + AA32 * (float(temp[1])-AB2) + AA33 * (float(temp[2])-AB3)) * G_MS_MG;
Serial.print(acc[0], 3); Serial.print("\t"); Serial.print(acc[1], 3); Serial.print("\t"); Serial.println(acc[2], 3);
}
void writeTo(int DEVICE, uint8_t address, uint8_t val) {
Wire.beginTransmission(DEVICE); // Start transmit queue to device
Wire.write(address); // Buffer register address
Wire.write(val); // Buffer value to write
Wire.endTransmission(); // Send transmission
}
void readFrom(int DEVICE, uint8_t address, int num, uint8_t buff[]) {
Wire.beginTransmission(DEVICE); // Start transmission to MAG
Wire.write(address); // Sends address to read from
Wire.endTransmission(); // Send transmission
Wire.beginTransmission(DEVICE); // Start transmission to MAG
Wire.requestFrom(DEVICE, num); // Request 6 bytes from MAG
int l = 0;
while (Wire.available()) // ACC may send less than requested (abnormal)
{
buff[l] = Wire.read(); // Receive a byte from buffer
l++;
}
Wire.endTransmission(); // End transmission
}
I’m viewing the output on Teraterm set at 921K 7-N-1 Xon/Xoff. Yes, the Serial rate and I2C are jacked way up, but that was needed to get it to run stably. The code actually outputs scaled values of all three axes. At 1.6 kHz, the cycle time is 320 microseconds, so you would NOT be able to run at 3.2 kHz without losing something