problem with accelerometer LIS331

Hi,

I’m trying to use the accelerometer LIS331 with the Arduino Uno. It works with I2C or SPI. As I don’t know enough this interfaces, I’ve searched a code already done in internet. The best I found is the one below. But I only receive 0g even if I move the accelerometer (sometimes I receives another result but almost never).The code is here and the results are attached.
Can you help me?

// 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 0.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;

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.println(zAcc, 1);

  delay(300);
}

// 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
  // Since I'm not using Interrupts, I'll leave it alone

  // 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);
}

results.rtf (1.5 KB)

This your breakout board, https://www.sparkfun.com/products/10345

Sparkfun uses the SPI interface. I would use I2C. The sensor is for 3.3V and the signals should not get a voltage of 5V ! Since the Uno uses 5V signals, and SPI is used, it might already be broken.

You could try a level shifter, or use I2C. I2C would perhaps also need a level shifter, but many times it can do without.

The code that Sparkfun provides is for a 3.3V ATmega328p as you can read in main.c

You have to make some choices here. Do you want to continue with this sensor ? More common sensors are here, http://www.adafruit.com/category/35_59 Do you want to use SPI ? If you change to I2C, you need code. Perhaps this, http://code.google.com/p/loguino/wiki/Lis331Driver If you do want to use this sensor and SPI, you should buy a level shifter for the SPI interface. They are cheap, but it's a puzzle how to connect them.

Thank you for your answer,

I really need to use this sensor, but I can choose to use I2C or SPI. When I connect it to the arduino, I feed it with the 3.3v pin alimentation. I’m trying to use this code you gave me http://code.google.com/p/loguino/wiki/Lis331Driver. But I need to use loguino and I don’t sucess to install it.

You should use the 3.3V pin to power the breakout board, but the signals for the SPI from the Arduino are 5V signals. You can't use 5V signal from the Arduino for the breakout board.

I'm sorry, is that not a driver for the I2C ? Someone used that code to write a common interface with examples : https://github.com/damellis/lis331/tree/master/LIS331

For SPI you could use a level shifter like Nick Gammon shows: http://www.gammon.com.au/forum/?id=10990

For I2C, you should add pull-up resistors to 3.3V and select the I2C bus with a pin. Can you do that, it should be in the datasheet. You have to run the i2c scanner to see if the wiring is okay for i2c. http://playground.arduino.cc/Main/I2cScanner Once the i2c scanner detects the sensor, that code to interface it should work.

Thank you

I will try it