Arduino & LIS302DL

February 13, 2009

in Sensors, Tinkering

Ages ago I bought an LIS302DL from Sparkfun. One of the old (little bit) messed up ones, but still 3 axis accelerometer with I2C output. No external parts. No pain. Fine!

Before I go in any further investigation. I need to get it up & running with my arduino (actually an boarduino – but who cares?). Read all the nifty details after the break.

The hookup is very easy (but a little bit off standard) – remember we use I2C:

  • VCC is connected to pin 13 – so you can power this from the arduino. But you should also be able to power it directly from VCC. Remember it was 3.3V
  • GND is connected to GND – this was a bit obvious.
  • SCL is connected to analog pin 5 (arduino’s I2C SCL)
  • SCA is connect to analog pin 4 (arduino’s I2C SCA)
  • MISO was tied to GND – in order to select the I2C address 28 – tie this to VCC and you got address 29 – if you want to use two LIS302DL – there is perhaps some reason for this – who knows?
  • INT2 is connected to pin 2 – in order to be able to use the interrupt. I did not – who knows? Perhaps I will do it later

The basic setup was the same as with my ADJD experiments. A 3.3V breadboard and the same I2C-routines for reading and setting registers:

void writeRegister(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);
  Wire.send(v);
  Wire.endTransmission();
}

unsigned char readRegister(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  v = Wire.receive();
  return v;
}

First of all we power up the LIS302DL and initialize it:

void setupLIS() {

  Serial.println("Setting up LIS302DL");

  pinMode(LIS302_POWER_PIN, OUTPUT); //the power pin
  pinMode(LIS302_INT2_PIN, INPUT); //the int2 pin

  digitalWrite(LIS302_POWER_PIN,LOW); //switch off the LIS302

  Wire.begin();        // join i2c bus (address optional for master)

}

void startLIS() {

  Serial.println("Powering up LIS302DL");
  digitalWrite(LIS302_POWER_PIN,HIGH); //switch off the LIS302

  delay(POWER_UP_DELAY);
  writeRegister(CTRL_REG1 , _BV(CTRL_PD) | _BV(CTRL_XEN) | _BV(CTRL_YEN) | _BV(CTRL_ZEN));

  //read who am i
  char myself = readRegister(REGISTER_WHO_AM_I);
  if (myself == WHO_AM_I_RESULT) {
    Serial.println("yippie got an lis302DL!");
  } else {
    Serial.print("found an ");
    Serial.print(myself, HEX);
    Serial.println("! very strange!");
  }
}

The routine setupLIS() does the basic initialization while startLIS() does everything to power it up (I put it in two routines since I thought I would write an power down routine – but this did not happen until now).
Most of the magic is in the routine

  writeRegister(CTRL_REG1 , _BV(CTRL_PD) | _BV(CTRL_XEN) | _BV(CTRL_YEN) | _BV(CTRL_ZEN));

It stops internal power down (CTRL_PD), and enables all three axis for detection. After this is done I check if the LIS302DL does correctly report to ‘who am I’ – register 0x0f. This is more or less an sanity check (as you can see by the diagnostic output).
After you have down the right initialization magic the readout is an charm:

  char x = readRegister(X_OUT);
  char y = readRegister(Y_OUT);
  char z = readRegister(Z_OUT);

Right now I just read it out every 100ms – you could of courser do it in a more sophisticated way by waiting until new data is ready by watching the status registers or using interrupts. But there is always something better to do. Perhaps I will add it later.

And before you ask how to do it yourself: Check the source code!

{ 15 comments… read them below or add one }

Leave a Comment

{ 3 trackbacks }