4
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ What's a "BMA180"? \$\endgroup\$ – Leon Heller Dec 17 '11 at 16:09
  • 1
    \$\begingroup\$ @LeonHeller It's the 3:30 from Atlanta to Boston isn't it? \$\endgroup\$ – Majenko Dec 17 '11 at 16:10
  • 1
    \$\begingroup\$ So sorry. It's an accelerometer. See here: sparkfun.com/products/9723 \$\endgroup\$ – Kardasis Dec 17 '11 at 16:34
  • \$\begingroup\$ @Kardasis, do you have VIO disconnected both from the level shifting board and the actual module? \$\endgroup\$ – Kortuk Dec 17 '11 at 16:59
  • \$\begingroup\$ Someone forgot the datasheet link, I get the frustration, but two downvotes? Could someone explain. It does look like someone is trying to solve an electronics problem, even if they are starting out. For the level of defense of off topic questions I find this astounding. \$\endgroup\$ – Kortuk Dec 17 '11 at 17:00
3
\$\begingroup\$

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/

\$\endgroup\$
  • \$\begingroup\$ The sparkfun page for the level converter says that it is compatible with I2C and I'm pretty sure that the requests are getting to the chip (at least sometimes) because the data coming out is correct acceleration data in x,y,z), it just isn't coming predictably or continuously. As for pull-up resistors, I think they're built into the logic level converter. \$\endgroup\$ – Kardasis Dec 17 '11 at 17:28
  • 1
    \$\begingroup\$ @Kardasis - Possibly, but you must connect the VIO for reliable operation. That you get 0's when you do so indicates you are not successfully making a request for data - most likely when you do get data it is "by accident" \$\endgroup\$ – Chris Stratton Dec 17 '11 at 17:36
  • \$\begingroup\$ O BOY! You're right about the VIO. What you failed to notice is that I'm a total n00b / yutz and the LED that I connected from the SDI pin to ground was apparently pulling the pin low. Uggggg. Thanks for the help. \$\endgroup\$ – Kardasis Dec 17 '11 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.