Electronic – arduino – Data from BMA180 accelerometer into arduino is sporadic

accelerometerarduinoi2cserial

I've been trying to get a BMA180 (I'm on my second one already) to send a continuous stream of accel data via a serial port (eventually bluetooth but that's a problem for a different day). I've looked at and tried to emulate numerous examples and consistently come across the problem of data coming in "fits and starts". One packet, wait a second or two, a few more packets, etc etc. Usually this ends in the data stopping all together a
fter 5, 10, 50 chunks.

My wiring is as show here but I have VIO unconnected. When VIO is tied to 3.3V, my output is all 0's. :
wiring of hookup between board and arduino

This is my code, which is adapted from several other sources:

#include <Wire.h>
#define DEVICE ((byte)0x40)  
#define DATA_X0      0x02   
#define AXIS_SHIFT   2   
#define DELAY_RATE   500

int counter = 0;


static void readFrom(byte address, byte num, byte *buff) {
  Wire.beginTransmission(DEVICE); 
  Wire.write(address);      
  Wire.endTransmission(); 

  Wire.requestFrom(DEVICE, num);  
  num = Wire.available();

  while(num-- > 0) {
    *(buff++) = Wire.read(); // receive a byte
  }
}

void setup()
{
  Wire.begin();          // join i2c bus (address optional for master)
  Serial.begin(115200);  // start serial for output
  Serial.flush();
  delay(15);
}

void loop()
{
  digitalWrite(13, HIGH); 
  int axis[5] = {0x0101, 0, 0, 0, 0};
  readFrom(DATA_X0, 6, (byte*)(axis+1)); 

  axis[1] = axis[1] ;
  axis[2] = axis[2] ;
  axis[3] = axis[3] ;

  axis[4] = axis[1] + axis[2] + axis[3];
  Serial.println("");
  Serial.println(axis[1]);
  Serial.println(axis[2]);
  Serial.println(axis[3]);
  Serial.println(axis[4]);
  counter++;

  delay(100);              
  digitalWrite(13, LOW);  
  delay(100);             
}

This is what I get coming into the serial monitor, in weird sporadic thrusts:

-879
321
17077
16519

-411
345
16761
16695

249
0
0
249

……..etc……
I suspect the 249 /0 /0/ 249 chunk is the temperature because it will go up and down a little although the application of my desk lamp caused all data to cease.
I am baffled. The 'L' LED on the arduino blinks when the packets get pushed out so I think it's not a serial port problem. I would really appreciate any ideas here.

Best Answer

I2C is a bi-directional data bus. You appear to be using a uni-directional level translator (likely http://www.sparkfun.com/products/8745) wired such that it can only pass data from the low voltage side to the high voltage one, and not the reverse. This will prevent you from sending commands to the Accelerometer to request data, so you would only see anything if it decided to produce data on its own. (EDIT: apparently the convert is at least somewhat bi-directional)

Further, you must tie the VIO high. By leaving it floating you are probably letting noise trigger the chip somehow to occasionally produce data.

Also note that I2C requires pullup resistors.

Switching to SPI might be an option as in that case each pin would be un-directional, however you need to drive 3 outputs from the 5v to 3.3v side (/CS, SCK, MOSI) and your existing translator only supports 2. You could build something for the third from discretes.

If you left CS and SDO unconnected you might be able to operate the chip in stand alone mode where it would reliably produce data by itself, but then you would have to make the program capable of catching the data whenever it appears, perhaps by using an interrupt (or a polling loop if you can guarantee nothing else is going on).

Here is a tutorial on modifying the Arduino itself to run on 3.3v, thus eliminating the level conversion problem: http://www.adafruit.com/blog/2011/04/19/tutorial-tuesday-converting-an-arduino-to-3-3v/