// Read from a LIS302DL accelerometer and output to the PC
// Adam Greig, Feb 2009
// Posted to NegativeAcknowledge.com
// Released under Creative Commons 3.0 Attribution-ShareAlike License:
// http://creativecommons.org/licenses/by-sa/3.0/

//Include wire library, contains I²C code
#include <Wire.h>

//The I²C address of the accelerometer
#define I2C_ADDR 0x1C

void setup() {

  //Start Wire and the serial port
  Wire.begin();
  Serial.begin( 115200 );

  //Turn on the accelerometer, with 400Hz refresh and 8g range
  Wire.beginTransmission( I2C_ADDR );
  Wire.send( 0x20 );
  Wire.send( 0xE7 );
  Wire.endTransmission();

  //Request the WHO_AM_I register for verification
  Wire.beginTransmission( I2C_ADDR );
  Wire.send( 0x0F );
  Wire.endTransmission();
  Wire.requestFrom( I2C_ADDR, 1 );
  while( !Wire.available() ) {}
  byte rWHO_AM_I = Wire.receive();
  if( rWHO_AM_I == 0x3B ) {
    //Serial.println( "LIS302DL Accelerometer found." );
  } else {
    //Serial.println( "Could not find accelerometer, stopping." );
    while(1) {}
  }

}

//a,b,c - store data from accelerometer
byte a, b, c;
//x,y,z - store values that will be output, can be negative
int x,y,z;
//mills - store milliseconds since execution start
unsigned long mills;

void loop() {
  //Read the output registers
  Wire.beginTransmission( I2C_ADDR );
  //0xA9 means read 0x29 and auto-increment register no
  Wire.send( 0xA9 );
  Wire.endTransmission();
  //5 bytes gets us x, null, y, null, z
  Wire.requestFrom( I2C_ADDR, 5 );
  while( Wire.available() != 5 ) {}
  //Get current timestamp
  mills = millis();
  //Receive the data
  a = Wire.receive();
  Wire.receive();
  b = Wire.receive();
  Wire.receive();
  c = Wire.receive();
  //For each component, if they're positive set x,y,z appropriately
  //if they are negative (two's complement logic, so topmost bit is 1 for negative)
  //then negate them by flipping all bits and adding one, then making the result
  //negative.
  if( a & 0x80 ) {
    x = -((a ^= 0xFF)+1);
  } else {
    x = a;
  }
  if( b & 0x80 ) {
    y = -((b ^= 0xFF)+1);
  } else {
    y = b;
  }
  if( c & 0x80 ) {
    z = -((c ^= 0xFF)+1);
  } else {
    z = c;
  }
  //Output data, tab deliminated
  Serial.print( mills, DEC );
  Serial.print( '\t' );
  Serial.print( x, DEC );
  Serial.print( '\t' );
  Serial.print( y, DEC );
  Serial.print( '\t' );
  Serial.println( z, DEC );
  delay( 10 );
}