I'm trying to read 2 accelerometers at a high rate (~1k Hz each) but the fastest I seem to be able to make it go is 250 Hz. I was hoping that someone might be able to help me speed it up to meet specification.
I'm using an Adafruit Flora, reading 2 ADXL345 accelerometers, and logging to an Openlog on Serial1. The code I'm using is below. Any advice on how to speed this up would be great!
#include <SPI.h>
// Chip select pins for the two accelerometers
int CS0 = 6;
int CS1 = 12;
char POWER_CTL = 0x2D; // Power control register
char DATA_FORMAT = 0x31; // Register to set the data format
char DATA_RATE = 0x2C; // Register to set the data rate
int MAX_DATA_RATE = 5000000; // maximum data rate for communication
char SIGNIFICANT_BIT = MSBFIRST; // SPI byte endianness
char CLOCK_PHASE = SPI_MODE3; // SPI clock and bit phase
// Data storage bit for reading
char DATAX0 = 0x32; //X-Axis least significant byte
char DATAX1 = 0x33; //X-Axis most significant byte
char DATAY0 = 0x34; //Y-Axis least significant byte
char DATAY1 = 0x35; //Y-Axis most significant byte
char DATAZ0 = 0x36; //Z-Axis least significant byte
char DATAZ1 = 0x37; //Z-Axis most significant byte
// output buffer to hold data read from registers
char values0[6];
char values1[6];
// variables to hold the accelerometer values
int x0, y0, z0;
int x1, y1, z1;
void setup() {
Serial1.begin(115200);
// set the onboard CS pin to output to tie it high
// to prevent arduino from going into slave mode
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
// set the SPI CS pins to high to initialize and disable
pinMode(CS0, OUTPUT);
digitalWrite(CS0, HIGH);
pinMode(CS1, OUTPUT);
digitalWrite(CS1, HIGH);
SPI.begin();
// setup sensor 0
sensorSetup(CS0);
// setup sensor 1
sensorSetup(CS1);
}
void loop() {
// read the accelerations
unsigned long t0 = micros();
readRegister(CS0, DATAX0, 6, values0);
unsigned long t1 = micros();
readRegister(CS1, DATAX0, 6, values1);
// data registers are LS byte followed by MS byte, so rearrange
x0 = (values0[1] << 8) | values0[0];
y0 = (values0[3] << 8) | values0[2];
z0 = (values0[5] << 8) | values0[4];
x1 = (values1[1] << 8) | values1[0];
y1 = (values1[3] << 8) | values1[2];
z1 = (values1[5] << 8) | values1[4];
// Send the data to the Openlog
Serial1.print("Sensor0: "); Serial1.print(t0); Serial1.print (" ");
Serial1.print(x0, DEC); Serial1.print(" ");
Serial1.print(y0, DEC); Serial1.print(" ");
Serial1.print(z0, DEC);
Serial1.print(" Sensor1: "); Serial1.print(t1); Serial1.print (" ");
Serial1.print(x1, DEC); Serial1.print(" ");
Serial1.print(y1, DEC); Serial1.print(" ");
Serial1.println(z1, DEC);
}
void writeRegister(int CS, char register_address, char value)
/* write a register over SPI
int CS = pin number of the chip select pin
char register_address = the address of the register to write
char value = the value to write to the register
*/
{
// setup the SPI transation
SPI.beginTransaction(SPISettings(MAX_DATA_RATE, SIGNIFICANT_BIT, CLOCK_PHASE));
// turn on the selected chip
digitalWrite(CS, LOW);
// let it know the resister you are writing to
SPI.transfer(register_address);
// send it the value
SPI.transfer(value);
// turn off the selected chip
digitalWrite(CS, HIGH);
// end the transaction
SPI.endTransaction();
}
void readRegister(int CS, char register_address, int num_Bytes, char *values)
/* read a register
int CS = the pin number of the chip select pin
char register_address = the address of the register to start the read.
int num_Bytes = the number of bytes to read
char *values = pointer to values array to store the read data
*/
{
// set bit 7 bit of the register to indicate pending read.
char address = 0x80 | register_address;
// multip-byte reads are signaled using bit 6
if (num_Bytes > 1) address |= 0x40;
// setup the SPI transaction
SPI.beginTransaction(SPISettings(MAX_DATA_RATE, SIGNIFICANT_BIT, CLOCK_PHASE));
// turn on the selected chip
digitalWrite(CS, LOW);
// transfer the starting address
SPI.transfer(address);
// read the registeres until we've read the specified number of bytes,
// store the resuts in the input buffer.
for (int i = 0; i < num_Bytes; i++)
{
values[i] = SPI.transfer(0);
}
// we're done here. turn chip off
digitalWrite(CS, HIGH);
// end transaction
SPI.endTransaction();
}
void sensorSetup(int CS)
/* setup the sensor
int CS = chip select pin
*/
{
// put the sensor into measure mode. This will prevent sleep
writeRegister(CS, POWER_CTL, 0x08);
char dataformat = 0;
// set the senso to full range 0000 0100
dataformat |= 0x04;
// set the range to 8g, use 0x01 for 4g; 0000 0010
dataformat |= 0x02;
// set the data format register
writeRegister(CS, DATA_FORMAT, dataformat);
// set the data rate to maximum
writeRegister(CS, DATA_RATE, 0x0F);
}