I finally have communication between an Arduino and an ADXL345 accelerometer over SPI!
I used the SPI library from the Arduino playground but was still having trouble so in the end resorted to following the example source code provided by sparkfun for the ATmega328.
The following listing is copied straight from my Arduino environment.
#include <Spi.h>
/*
BalanceBot
Read from an accelerometer ADXL345.
ADXL345 max clock speed is 5MHz, default arduino CLKi/o is 16MHz/64 (OK)
***SPI Pins***
SCK PB5 13
MISO PB4 12
MOSI PB3 11
SS Any 10
Ben Caldwell
*/
byte tmp;
byte readData; //The byte that data read from SPI interface will be stored in
byte fifo[6]; //data read for x,y,z axis from the accelerometer's FIFO buffer
float x,y,z; //The ranged x,y,z data
float range; //The range of the x,y,z data returned
// The setup() method runs once, when the sketch starts
void setup() {
Serial.begin(9600);
Spi.mode((1<<SPE) | (1<<MSTR) | (1<<CPOL) | (1<<CPHA) | (1<<SPR1) | (1<<SPR0));
Serial.println("Starting Setup");
//Set SS high, slave disabled waiting to pull low for first exchange
digitalWrite(SS_PIN, HIGH);
delay(4000);
//Wait for POWER_CTL register to go to correct state
readData = 0x00;
while (readData != 0x28)
{
//POWER_CTL register: measure
digitalWrite(SS_PIN, LOW);
Spi.transfer(0x2D);
Spi.transfer(0x28); //Measure
digitalWrite(SS_PIN, HIGH);
delay(5);
digitalWrite(SS_PIN, LOW);
Spi.transfer(1<<7 | 0x2D); //Set "read" MSb
readData = Spi.transfer(0x00); //Send dummy byte to keep clock pulse going!
digitalWrite(SS_PIN, HIGH);
Serial.print("POWER_CTL: ");
Serial.println(readData, HEX);
delay(1000);
}
//Set FORMAT
digitalWrite(SS_PIN, LOW);
Spi.transfer(0x31);
Spi.transfer(0x08);
digitalWrite(SS_PIN, HIGH);
delay(5);
//Readback FORMAT
digitalWrite(SS_PIN, LOW);
Spi.transfer(1<<7 | 0x31);
readData = Spi.transfer(0x00);
digitalWrite(SS_PIN, HIGH);
readData = readData & 0x03;
switch (readData)
{
case 0:
range = 2.0;
break;
case 1:
range = 4.0;
break;
case 2:
range = 8.0;
break;
case 3:
range = 16.0;
break;
}
Serial.print("FORMAT: ");
Serial.println(readData, HEX);
//Set FIFO
digitalWrite(SS_PIN, LOW);
Spi.transfer(0x38);
Spi.transfer(0x00);
digitalWrite(SS_PIN, HIGH);
delay(5);
//Readback FIFO
digitalWrite(SS_PIN, LOW);
Spi.transfer(1<<7 | 0x38);
readData = Spi.transfer(0x00);
digitalWrite(SS_PIN, HIGH);
Serial.print("FIFO: ");
Serial.println(readData, HEX);
delay(4000);
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
//All x,y,z data must be read from FIFO in a multiread burst
digitalWrite(SS_PIN, LOW);
//Start reading at 0x32 and set "Read" and "Multi" bits
Spi.transfer(1<<7 | 1<<6 | 0x32);
for (int i=0; i<6; i++)
{
fifo[i] = Spi.transfer(0x00);
}
digitalWrite(SS_PIN, HIGH);
delay(5);
//The measurements in the FIFO 10bit
x = (float)((fifo[1]<<8) | fifo[0]) * range / 512.0;
y = (float)((fifo[3]<<8) | fifo[2]) * range / 512.0;
z = (float)((fifo[5]<<8) | fifo[4]) * range / 512.0;
Serial.println("********************");
Serial.print("[X,Y,Z](g): [");
Serial.print(x);
Serial.print(",");
Serial.print(y);
Serial.print(",");
Serial.print(z);
Serial.println("]");
delay(1000);
}
References
- The SEN-09156 breakout board:
http://www.sparkfun.com/commerce/product_info.php?products_id=9156 - Sparkfun example code:
http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345-talktest.zip - Arduino SPI library:
http://www.arduino.cc/playground/Code/Spi