title: Programming Arduino with ADXL345 to raise interrupt on inactivity
body: <p>I need to use a sparkfun breakout board <a href="http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf" rel="nofollow">ADXL345</a> to detect when my motor system has stopped vibrating. I am also using a Sparkfun RedBoard (Arduino uno).</p>
  
  <p>Things I am doing to configure for this behavior: </p>
  
  <ul>
  <li>enable INACTIVITY event</li>
  <li>route INACTIVITY events to INT 1 (pin 2 on the RedBoard)</li>
  <li>raise INACTIVITY interrupt without delay</li>
  <li>set low threshold for INACTIVITY (rule out too high of a setting)</li>
  <li>INACTIVITY considers all axes</li>
  <li>clear interrupt data register</li>
  </ul>
  
  <p>Having done all these things I do not receive interrupts after going from shaking the devise to setting it down.</p>
  
  <pre><code>//Add the SPI library so we can communicate with the ADXL345 sensor
  #include &lt;SPI.h&gt;
  
  //Assign the Chip Select signal to pin 10.
  int CS=10;
  
  //This is a list of some of the registers available on the ADXL345.
  //To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
  char POWER_CTL = 0x2D;  //Power Control Register
  char DATA_FORMAT = 0x31;
  char DATAX0 = 0x32; //X-Axis Data 0
  char DATAX1 = 0x33; //X-Axis Data 1
  char DATAY0 = 0x34; //Y-Axis Data 0
  char DATAY1 = 0x35; //Y-Axis Data 1
  char DATAZ0 = 0x36; //Z-Axis Data 0
  char DATAZ1 = 0x37; //Z-Axis Data 1
  
  char THRESH_ACT               = 0x24; // Activity threshold
  char THRESH_INACT             = 0x38; // Inactivity threshold to 3g
  char TIME_INACT               = 0x26; // time before raising interrupt
  
  char INT_ENABLE               = 0x2E; // Enabling the interrupt lines
  
  char INT_MAP                  = 0x2F;
  char ACT_INACT_CTL            = 0x27; // mask byte for controlling
  
  char INT_SOURCE               = 0x30;
  
  //This buffer will hold values read from the ADXL345 registers.
  char values[10];
  //These variables will be used to hold the x,y and z axis accelerometer values.
  int x,y,z;
  
  void setup(){ 
    //Initiate an SPI communication instance.
    SPI.begin();
    //Configure the SPI connection for the ADXL345.
    SPI.setDataMode(SPI_MODE3);
    //Create a serial connection to display the data on the terminal.
    Serial.begin(9600);
  
    //Set up the Chip Select pin to be an output from the Arduino.
    pinMode(CS, OUTPUT);
    //Before communication starts, the Chip Select pin needs to be set high.
    digitalWrite(CS, HIGH);
  
    // Create an interrupt that will trigger when inactivity is detected
    attachInterrupt(0, interruptHandler, RISING);
  
    //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
    writeRegister(DATA_FORMAT, 0x01);
    //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
    writeRegister(POWER_CTL, 0x08);  //Measurement mode
  
    // Send the inactivity &amp;&amp; activity  to PIN 1
    // 0xF7 &amp;&amp; 0xEF
    writeRegister(INT_MAP,0xF7 &amp;&amp; 0xEF);
  
    // Set the inactivity threshold to 3g (0x38)
  //  writeRegister(THRESH_INACT,0x38);
    writeRegister(THRESH_INACT,1);
  
    // Raise the inact interrupt immediately after going below threshold
    writeRegister(TIME_INACT,0);
    // Map INACT event (only) to PIN 1
    writeRegister(ACT_INACT_CTL, 0x0F);
  
    // Enab  le inactivity to generate interrupts
    writeRegister(INT_ENABLE, 0x08);
  
    readRegister(INT_SOURCE, 1, values); // Clear the INT_SOURCE register
  
    Serial.println("Waiting for interrupt!");
  }
  
  void interruptHandler(){
    // readRegister(INT_SOURCE, 1, values); // Clear the INT_SOURCE register
    Serial.println("something raise an interrupt!");
  }
  
  void loop(){
    //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
    //The results of the read operation will get stored to the values[] buffer.
    readRegister(DATAX0, 6, values);
  
    //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
    //The X value is stored in values[0] and values[1].
    x = ((int)values[1]&lt;&lt;8)|(int)values[0];
    //The Y value is stored in values[2] and values[3].
    y = ((int)values[3]&lt;&lt;8)|(int)values[2];
    //The Z value is stored in values[4] and values[5].
    z = ((int)values[5]&lt;&lt;8)|(int)values[4];
  
    //Print the results to the terminal.
    Serial.print(x, DEC);
    Serial.print(',');
    Serial.print(y, DEC);
    Serial.print(',');
    Serial.println(z, DEC);      
    delay(500); 
  }
  
  //This function will write a value to a register on the ADXL345.
  //Parameters:
  //  char registerAddress - The register to write a value to
  //  char value - The value to be written to the specified register.
  void writeRegister(char registerAddress, char value){
    //Set Chip Select pin low to signal the beginning of an SPI packet.
    digitalWrite(CS, LOW);
    //Transfer the register address over SPI.
    SPI.transfer(registerAddress);
    //Transfer the desired register value over SPI.
    SPI.transfer(value);
    //Set the Chip Select pin high to signal the end of an SPI packet.
    digitalWrite(CS, HIGH);
  }
  
  //This function will read a certain number of registers starting from a specified address and store their values in a buffer.
  //Parameters:
  //  char registerAddress - The register addresse to start the read sequence from.
  //  int numBytes - The number of registers that should be read.
  //  char * values - A pointer to a buffer where the results of the operation should be stored.
  void readRegister(char registerAddress, int numBytes, char * values){
    //Since we're performing a read operation, the most significant bit of the register address should be set.
    char address = 0x80 | registerAddress;
    //If we're doing a multi-byte read, bit 6 needs to be set as well.
    if(numBytes &gt; 1)address = address | 0x40;
  
    //Set the Chip select pin low to start an SPI packet.
    digitalWrite(CS, LOW);
    //Transfer the starting register address that needs to be read.
    SPI.transfer(address);
    //Continue to read registers until we've read the number specified, storing the results to the input buffer.
    for(int i=0; i&lt;numBytes; i++){
      values[i] = SPI.transfer(0x00);
    }
    //Set the Chips Select pin high to end the SPI packet.
    digitalWrite(CS, HIGH);
  }
  </code></pre>