Interfacing with a BMA180 Accelerometer

I recently got a BMA180 accelerometer from here: http://www.sparkfun.com/commerce/product_info.php?products_id=9723

I previously got an ADXL345 accelerometer to work with i2c and my duemilanove card, but I'm not having much luck with this new one. I've tried SPI and i2c, and neither of them work with the BMA180.

I tried to use the supplied example code, which used SPI, but it didn't work.

Are there any suggestions on how I can use this accelerometer? An example working wiring diagram would help too. Tutorials are nice too.

I'm rather new to this I2C and SPI interface stuff.

I tried to convert the C code to equivalent Arduino library code, but I don't think it's a coding problem at the moment. It did compile eventually, but it hung while trying to read a register.

The problem I suspect is happening is that my wiring isn't working. It works at 3.3 volts, and the Arduino Duemilanove works at 5 volts. When I hooked it up for i2c, I think it's shorting out.

With my last try, I was using this for my wiring diagram Live Fast - Code Young: ADXL345 accelerometer breakout board + Arduino and Processing but VDD and VIO are connected to the same 3.3 supply voltage.

Hello Everyone,

I purchased two BMA180 Accelerometers without double checking all of the specs (big mistake!) and now I have been working to understand I2C and the Wire Library. After the past three days of working I have finally achieved a consistent and correct output. I thought I would share my findings since there is very little information about using this accelerometer with an Arduino.

I am using an Arduino Mini 04 and have soldered extra pins to Analog 3 and 4 to allow me the use of the Wire library. It is important to note that the BMA180 is not a 5v device, it operates in many different ranges but all are below the 5v that the Arduino uses. It is ok to power the BMA180 with the 3.3v rail of an Arduino Duemilanove but the Wire library needs the signal at 5v.

For my setup, it was necessary to purchase a Logic Level Converter (Sparkfun sku: BOB-08745). Because communication with I2C is bidirectional, I had to wire both the clock and signal line to the TX path on the logic level converter. This means that I need one converter for one Accelerometer. No big deal, these guys only cost 2 bucks.

An I2C setup needs to have pullup resistors on both lines, on an Arduino Duemilanove the Wire library enables pullups by default, with the Arduino Mini, the information on this subject is ambiguous. One source includes the pullup resistors, another source has you change part of the Wire library code and recompile... thus enabling the pullups on the Mini. I have selected two 10k resistors and used them on the I2C wires on the 5V side of the logic level converter.

If everything is wired correctly, it will respond to its address and it will always return the value 3 when asked for its ID. Checking the ID is a good way to confirm that the chip is up and running. The C example code on the Sparkfun website is very helpful in understanding how to access and change the register values on the chip.

One thing that I can recommend is to thoroughly read the BMA180 datasheet. Page 21 of the PDF gives you all of the register values and the breakdown of the bits contained in each value. Look to the individual register descriptions to see the binary values they accept.

For a beginner like me, communicating in binary and hex looked impossible at first. I spent many hours trying to break down the example code for the BMA180 on the Sparkfun site and it has started to click. The BitwiseAnd section of the Arduino reference should help de-mystify some of the binary arithmetic concepts used in the example code.

I hope this information helps someone, below is the code that I have used to setup the BMA180 and then read a constant stream of the x acceleration value.

Here is the code for my main file.

#include <Wire.h>

#define address 0x40

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  initBMA180();
  delay(2000);
}

void loop()
{

  readAccel();  

  delay(10);
}

In my Arduino IDE I keep the BMA functions in a separate tab.

int x;

void readAccel()
{
  int temp, result;

  temp = 0;

  while(temp != 1)
  {
    Wire.beginTransmission(address);
    Wire.send(0x03); 
    Wire.requestFrom(address, 1);
    while(Wire.available()) 
    {
      temp = Wire.receive() & 0x01;
    }
  }

  Wire.beginTransmission(address);
  Wire.send(0x02);
  Wire.requestFrom(address, 1);
  while(Wire.available()) 
  {
    temp |= Wire.receive();
    temp = temp >> 2;
  }
  Serial.print("X = ");
  Serial.println(temp);
  result = Wire.endTransmission();
}

void initBMA180()
{
  int temp, result, error;

  Wire.beginTransmission(address);
  Wire.send(0x00);
  Wire.requestFrom(address, 1);
  while(Wire.available()) 
  {
    temp = Wire.receive();
  }
  Serial.print("Id = ");
  Serial.println(temp);
  result = Wire.endTransmission();
  checkResult(result);
  if(result > 0)
  {
    error = 1;
  }  
  delay(10);
  if(temp == 3)
  {
    // Connect to the ctrl_reg1 register and set the ee_w bit to enable writing.
    Wire.beginTransmission(address);
    Wire.send(0x0D);
    Wire.send(B0001);
    result = Wire.endTransmission();
    checkResult(result);
    if(result > 0)
    {
      error = 1;
    }
    delay(10);
    // Connect to the bw_tcs register and set the filtering level to 10hz.
    Wire.beginTransmission(address);
    Wire.send(0x20);
    Wire.send(B00001000);
    result = Wire.endTransmission();
    checkResult(result);
    if(result > 0)
    {
      error = 1;
    }
    delay(10);
    // Connect to the offset_lsb1 register and set the range to +- 2.
    Wire.beginTransmission(address);
    Wire.send(0x35);
    Wire.send(B0100);
    result = Wire.endTransmission();
    checkResult(result);
    if(result > 0)
    {
      error = 1;
    }
    delay(10);
  }

  if(error == 0)
  {
    Serial.print("BMA180 Init Successful"); 
  }
}

void checkResult(int result)
{
  if(result >= 1)
  {
    Serial.print("PROBLEM..... Result code is ");
    Serial.println(result);
  } 
  else
  {
    Serial.println("Read/Write success");
  }
}

void readId()
{
  int temp, result;

  Wire.beginTransmission(address);
  Wire.send(0x00);
  Wire.requestFrom(address, 1);
  while(Wire.available()) 
  {
    temp = Wire.receive();
  }
  Serial.print("Id = ");
  Serial.println(temp);
  result = Wire.endTransmission();
  checkResult(result);  
  delay(10);
}

Here are a few links on Arduino and I2C that helped me find my solution.

http://www.nearfuturelaboratory.com/2007/01/11/arduino-and-twi/

http://www.neufeld.newton.ks.us/electronics/?p=241

m.ryandesign,

Your information is great, I am a student here in Mexico and i am trying to do something similar, could you show a schematic of how you connected the arduino, the BMA180 and the level converter all together, I am having some difficulty understanding how everything works together

Thank you very much, I really appreciate it

zermanik,

Thank's for your compliment, I am glad that my post has helped. Here is a very rough sketch that I did to illustrate the connections.

The Logic Level Converter was no picnic to setup, I made a bunch of simple mistakes that I should have avoided. One mistake I made was assuming that the board would step down my 5v source to 3.3v but that is not the case. To operate the logic level converter, it needs a 5v source and a 3.3v source. Since the I2C lines are bi-directional, we use the TX path for both.... the RX paths are unused. I am using the Arduino Mini so my I2C pins are analog 3 and 4. For a larger Arduino I believe the pins are analog 5 and 6.

Has anyone had luck triggering the interrupts with the BMA180?

I am trying to configure the board to set the INT pin to HIGH when a double tap occurs. I have set the proper bits in the register but the BMA180 still does not send interrupts.

Any insight? Has anyone out there used any of this accelerometers interrupt features?

I did that for the ADXL345 .. it's a different chip but it still may be useful.. you can find it on the post Exploring the advanced features of the ADXL345 Accelerometer: single & double tap, activity, inactivity, free fall, power saving from my blog.