 # Mapping BMA180 digital values to g's

Hi all,

For the last couple of days i was trying to decode digital outputs produced by my BMA180 to g’s, but got lost and want to confirm on some issues.

As much as i understand in the BMA180 there sits an analog sensor that captures the movements. Then the ADC converts the data into the range -2^(14-1) … 2^(14-1). (BMA180 is 14bit as i understand). If i set the range to ±2g then i should be able to convert the data back into g’s by

g=BMA180_output/(2^(14-1))

So that is how i think everything should be. BUT everywhere i looked i arrived at different conclusions. For example here:A Guide To using IMU (Accelerometer and Gyroscope Devices) in Embedded Applications. – Starlino Electronics , they say to first revert the data back to analog and then calculate the g’s.

So finally my questions are:

Why revert the data back to analog?
Why in most formulas I see sensitivity as a divisor not the range values i mentioned before?
Might anyone tell what would the specific formula be for 14-bit BMA180 at 2g range?

I feel like i’m missing something in the system, hopefully someone will be able to clear that up. Thanks in advance!

In case anyone is interested i’m putting the code with which i’m getting the data
(I found it on DSS circuits website):

``````byte readAccel()
{
Wire.beginTransmission(BMA180);
Wire.send(0x02);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,7) != 7){return(2);}
acc_x = Wire.receive();
acc_x |= Wire.receive() << 8;
acc_x >>= 2;
acc_y = Wire.receive();
acc_y |= Wire.receive() << 8;
acc_y >>= 2;
acc_z = Wire.receive();
acc_z |= Wire.receive() << 8;
acc_z >>= 2;
temp = Wire.receive();
}

byte initializeBMA180()
{
/*Set EEPROM image to write mode so we can change configuration*/
delay(20);
Wire.beginTransmission(BMA180);
Wire.send(0x0D);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte ee_w = Wire.receive();
ee_w |= ee_w_MASK;
Wire.beginTransmission(BMA180);
Wire.send(0x0D);
Wire.send(ee_w);
if(Wire.endTransmission()){return(1);}
delay(20);
/*Set mode configuration register to Mode 00*/
Wire.beginTransmission(BMA180);
Wire.send(0x30);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte mode_config = Wire.receive();
mode_config &= ~(mode_config_MASK);
Wire.beginTransmission(BMA180);
Wire.send(0x30);
Wire.send(mode_config);
if(Wire.endTransmission()){return(1);}
delay(20);
/*Set bandwidth to 10Hz*/
Wire.beginTransmission(BMA180);
Wire.send(0x20);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte bw = Wire.receive();
bw &= ~(bw_MASK);
bw |= 0x00 << 4;
Wire.beginTransmission(BMA180);
Wire.send(0x20);
Wire.send(bw);
if(Wire.endTransmission()){return(1);}
delay(20);
/*Set acceleration range to 2g*/
Wire.beginTransmission(BMA180);
Wire.send(0x35);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte range = Wire.receive();
range &= ~(range_MASK);
range |= 0x02 << 1 ;
Wire.beginTransmission(BMA180);
Wire.send(0x35);
Wire.send(range);
if(Wire.endTransmission()){return(1);}
delay(20);
/*Set interrupt latch state to non latching*/
Wire.beginTransmission(BMA180);
Wire.send(0x21);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte latch_int = Wire.receive();
latch_int &= ~(0x01);
Wire.beginTransmission(BMA180);
Wire.send(0x21);
Wire.send(latch_int);
if(Wire.endTransmission()){return(1);}
delay(20);
/*Set interrupt type to new data*/
Wire.beginTransmission(BMA180);
Wire.send(0x21);
if(Wire.endTransmission()){return(1);}
if(Wire.requestFrom(BMA180,1) != 1){return(2);}
byte int_type = Wire.receive();
int_type |= 0x02;
Wire.beginTransmission(BMA180);
Wire.send(0x21);
Wire.send(int_type);
if(Wire.endTransmission()){return(1);}
delay(20);
return(0);
}
``````

Setting full scale to +/-2g doesn’t necessarily mean that +2g = 8191 and -2g = -8192. They list the ADC resolution for that range as 0.25 mili-G per Least Significant Bit. I think that means 2g would be a value 8000 (2/0.00025) and -2g would be -8000 (-2/0.00025)

I think if you divide the raw value by 4000.0 (multiply by 0.00025) you will get the values in G.