Configuring interrupt on accelerometer (LIS331HH)

I’m trying to write a program that uses an accelerometer (LIS331HH, https://www.sparkfun.com/products/10345) as the input to light LEDs. There are 6 LEDs, and each time the accelerometer records a bump, I want the interrupt to trigger, then calling a function to light the next LED in the chain and turn the previous one off. I found some code online already to read the accelerometer fine, but it didn’t use interrupts so I’ve been trying to configure those on my own. The datasheet is here (https://www.sparkfun.com/datasheets/Sen … S331HH.pdf). Also, I’m using a Pro Mini (3.3V, 8MHz, ATmega328).

Since I’m watching for a bump, I want to monitor if the inputs are either positive or negative, so I’m using interrupt 1 for high events and interrupt 2 for low events. The problem is setting the threshold that triggers the interrupt. The accelerometer provides raw readings between ±5500, which I then convert to Gs in the program. In the register that holds the threshold value of the interrupt, I only have 7 bits, giving me a maximum value of 127, so I don’t know how to get a meaningful threshold from it. Right now, the interrupt stays high all the time, even when the values are negative, so that isn’t right either. I think that might involve reading the INT1_SRC register, which I believe clears the interrupt event, but I’m not sure. My code is below (doesn’t involve LED lighting right now, just basic reading accelerometer and configuring interrupt so I can measure the interrupt on my own with a DMM and see if it gets set high on bumps). Any help would be appreciated!

// 3-axis Accelerometer
// Sparkfun Electronics Triple Axis Accelerometer Breakout - LIS331
// Arduino UNO

/* Wiring:
UNO LIS331

3.3V VCC
GND GND
10 CS 
11 SDA/SDI
12 SA0/SDO
13 SCL/SPC
*/

#include <SPI.h>
#include <stdlib.h>
#include <stdio.h>

#define SS 10 // Serial Select -> CS on LIS331
#define MOSI 11 // MasterOutSlaveIn -> SDI
#define MISO 12 // MasterInSlaveOut -> SDO
#define SCK 13 // Serial Clock -> SPC on LIS331

#define SCALE .0007324; // approximate scale factor for full range (+/-24g)
// scale factor: +/-24g = 48G range. 2^16 bits. 48/65536 = 0.0007324

// global acceleration values
double xAcc, yAcc, zAcc, total;

void setup()
{
Serial.begin(9600);

// Configure SPI
SPI_SETUP();

// Configure accelerometer
Accelerometer_Setup();
}


void loop()
{
readVal(); // get acc values and put into global variables

Serial.print(xAcc, 1);
Serial.print(",");
Serial.print(yAcc, 1);
Serial.print(",");
Serial.print(zAcc, 1);
Serial.print(",");
Serial.println(total, 1);

total = zAcc + yAcc + xAcc;

delay(10);
}

// Read the accelerometer data and put values into global variables
void readVal()
{
byte xAddressByteL = 0x28; // Low Byte of X value (the first data register)
byte readBit = B10000000; // bit 0 (MSB) HIGH means read register
byte incrementBit = B01000000; // bit 1 HIGH means keep incrementing registers
// this allows us to keep reading the data registers by pushing an empty byte
byte dataByte = xAddressByteL | readBit | incrementBit;
byte b0 = 0x0; // an empty byte, to increment to subsequent registers

digitalWrite(SS, LOW); // SS must be LOW to communicate
delay(1);
SPI.transfer(dataByte); // request a read, starting at X low byte
byte xL = SPI.transfer(b0); // get the low byte of X data
byte xH = SPI.transfer(b0); // get the high byte of X data
byte yL = SPI.transfer(b0); // get the low byte of Y data
byte yH = SPI.transfer(b0); // get the high byte of Y data
byte zL = SPI.transfer(b0); // get the low byte of Z data
byte zH = SPI.transfer(b0); // get the high byte of Z data
delay(1);
digitalWrite(SS, HIGH);

// shift the high byte left 8 bits and merge the high and low
int xVal = (xL | (xH << 8));
int yVal = (yL | (yH << 8));
int zVal = (zL | (zH << 8));

// scale the values into G's
xAcc = xVal * SCALE;
yAcc = yVal * SCALE;
zAcc = zVal * SCALE;
}

void SPI_SETUP()
{
pinMode(SS, OUTPUT);

// wake up the SPI bus
SPI.begin();

// This device reads MSB first:
SPI.setBitOrder(MSBFIRST);

/*
SPI.setDataMode()
Mode	 Clock Polarity (CPOL) Clock Phase (CPHA)
SPI_MODE0	 0	 0
SPI_MODE1	 0	 1
SPI_MODE2	 1	 0
SPI_MODE3	 1	 1
*/
SPI.setDataMode(SPI_MODE0);

/*
SPI.setClockDivider()
sets SPI clock to a fraction of the system clock
Arduino UNO system clock = 16 MHz
Mode SPI Clock
SPI_CLOCK_DIV2 8 MHz
SPI_CLOCK_DIV4 4 MHz
SPI_CLOCK_DIV8 2 MHz
SPI_CLOCK_DIV16 1 MHz
SPI_CLOCK_DIV32 500 Hz
SPI_CLOCK_DIV64 250 Hz
SPI_CLOCK_DIV128 125 Hz
*/

SPI.setClockDivider(SPI_CLOCK_DIV16); // SPI clock 1000Hz
}

void Accelerometer_Setup()
{
// Set up the accelerometer
// write to Control register 1: address 20h
byte addressByte = 0x20;
/* Bits:
PM2 PM1 PM0 DR1 DR0 Zen Yen Xen
PM2PM1PM0: Power mode (001 = Normal Mode)
DR1DR0: Data rate (00=50Hz, 01=100Hz, 10=400Hz, 11=1000Hz)
Zen, Yen, Xen: Z enable, Y enable, X enable
*/
byte ctrlRegByte = 0x37; // 00111111 : normal mode, 1000Hz, xyz enabled

// Send the data for Control Register 1
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// write to Control Register 2: address 21h
addressByte = 0x21;
// This register configures high pass filter
ctrlRegByte = 0x00; // High pass filter off

// Send the data for Control Register 2
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);


// Control Register 3 configures Interrupts
addressByte = 0x22;
/* Bits:
IHL PP_OD LIR2 I2_CFG1 I2_CFG0 LIR1 I1_CFG1 I1_CFG0
IHL: interrupt high low (0=active high)
PP_OD: push-pull/open drain selection (0=push-pull)
LIR2: latch interrupt request on INT2_SRC register (0=interrupt request not latched)
I2_CFG1, I2_CFG0: data signal on INT 2 pad control bits 
LIR1: latch interrupt request on INT1_SRC register (0=interrupt request not latched)
I1_CFG1, I1_CFG0: data signal on INT 1 pad control bits

Data signal on pad
I1(2)_CFG1      I1(2)_CFG0            INT 1(2) pad
    0                0              interrupt 1(2) source
    0                1              interrupt 1 source or interrupt 2 source
    1                0              data ready
    1                1              boot running

*/
ctrlRegByte = 0x24; // 00100100 : interrupt request latched to interrupt source 1 and interrupt source 2

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);


// write to Control Register 4: address 23h
addressByte = 0x23;
/* Bits:
BDU BLE FS1 FS0 STsign 0 ST SIM
BDU: Block data update (0=continuous update)
BLE: Big/little endian data (0=accel data LSB at LOW address)
FS1FS0: Full-scale selection (00 = +/-6G, 01 = +/-12G, 11 = +/-24G)
STsign: selft-test sign (default 0=plus)
ST: self-test enable (default 0=disabled)
SIM: SPI mode selection(default 0=4 wire interface, 1=3 wire interface)
*/
ctrlRegByte = 0x30; // 00110000 : 24G (full scale)


// Send the data for Control Register 4
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);


// Control Register for interrupt configuration (INT1_CFG)
addressByte = 0x30;
ctrlRegByte = 0x2A; // 00101010 : interrupt request enabled on high Z, high Y, high X events

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// Control Register for interrupt threshold for high events (INT1_THS)
addressByte = 0x32;
ctrlRegByte = 0x7F; // 0 0000000 : value TBD

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// Control Register for interrupt duration for high events (INT1_DURATION)
addressByte = 0x33;
ctrlRegByte = 0x02; // 0 0000010 : value TBD

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// Control Register for interrupt configuration (INT2_CFG)
addressByte = 0x34;
ctrlRegByte = 0x15; // 00010101 : interrupt request enabled on low Z, low Y, low X events

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// Control Register for interrupt threshold (INT2_THS)
addressByte = 0x36;
ctrlRegByte = 0x00; // 00000000 : value TBD

digitalWrite(SS, LOW);
delay(1);
SPI.transfer(addressByte);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

}

The data sheet is ridiculously sparse, so I suggest posting on one of the ST forums: http://my.st.com/public/STe2ecommunities/default.aspx