BMA180 library with multiple configurable ranges. Based on the Sensor_test by Bo Carøe.

Dependents:   Sensor_test_2_0 KalmanFilter

Fork of BMA180 by Bo Carøe

BMA180.cpp

Committer:
cdonate
Date:
2012-08-15
Revision:
2:c7eb9f15e026
Parent:
1:cd2316c8a187

File content as of revision 2:c7eb9f15e026:

#include "mbed.h"
#include "BMA180.h"

#define I2CADR_W(ADR)           (ADR<<1&0xFE)
#define I2CADR_R(ADR)           (ADR<<1|0x01)

//Initialization
BMA180::BMA180(I2C & I2CBus_, Timer & GlobalTime_)
    : I2CBus(I2CBus_),
      GlobalTime(GlobalTime_)
{}

void BMA180::Init()
{
    //Zeroing
    for(int i= 0; i < 3; i++)
    {
        Offset[i]= 0.0;
        RawAcc[i]= 0;
        Acc[i]= 0;
    }
    
       
    //BMA180 initialization
    char tx[2];
    char rx[1];
    
    //Write on EEPROM enable
    tx[0]= 0x0D;
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 1);
    I2CBus.read (I2CADR_R(BMA180_ADRESS), rx, 1);
    tx[1]= rx[0] & 0xEF | (0x01<<4);
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 2);
    
    //Mode: Low-Noise
    tx[0]= 0x30;
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 1);
    I2CBus.read (I2CADR_R(BMA180_ADRESS), rx, 1);
    tx[1]= rx[0] & 0xFC | (0x00<<0);
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 2);
    
    //Range: +-1.5g
    // +-1g:0x00 | +-1.5g:0x01 | +-2g:0x02 | +-3g:0x03 |  +-4g:0x04 |  +-8g:0x05 |  +-16g:0x06 | 
    tx[0]= 0x35;
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 1);
    I2CBus.read (I2CADR_R(BMA180_ADRESS), rx, 1);
    tx[1]= rx[0] & 0xF1 | (0x01<<1);
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 2);
    
    //Bandwidth filters: 10Hz    
    tx[0]= 0x20;
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 1);
    I2CBus.read (I2CADR_R(BMA180_ADRESS), rx, 1);
    tx[1]= rx[0] & 0x0F | (0x00<<4);
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 2);
      
    Update();
}


//Read raw data
void BMA180::ReadRawData()
{
    //Read acceleration on all 3 axis
    char tx[1];
    char rx[6];
    
    tx[0]= 0x02;
    I2CBus.write(I2CADR_W(BMA180_ADRESS), tx, 1);
    I2CBus.read (I2CADR_R(BMA180_ADRESS), rx, 6); 
    
    //Assemble the individual bytes from the 16-bit value
    //The last 2 bits must be "cut off" since the values came in 14-bit form
    RawAcc[0]= (rx[1]<<8|rx[0]) & 0xFFFC;
    RawAcc[1]= (rx[3]<<8|rx[2]) & 0xFFFC;
    RawAcc[2]= (rx[5]<<8|rx[4]) & 0xFFFC;
    RawAcc[0]/= 4;
    RawAcc[1]/= 4;
    RawAcc[2]/= 4;
}
   
//Update-Method
void BMA180::Update()
{
    //Read acceleration on all 3 axis
    ReadRawData();
    
    //Conversions
    Acc[0]= fConvMPSS * ((float)(RawAcc[0]) + Offset[0]);
    Acc[1]= fConvMPSS * ((float)(RawAcc[1]) + Offset[1]);
    Acc[2]= fConvMPSS * ((float)(RawAcc[2]) + Offset[2]);
}

//Calibration
void BMA180::Calibrate(int ms, const short * pRaw1g)
{
    float AvgCalibAcc[3]= {0.0, 0.0, 0.0};    
    float AvgCalibSampels= 0.0;
    
    //End of calibration calculated in milliseconds
    int CalibEnd= GlobalTime.read_ms() + ms;
    
    while(GlobalTime.read_ms() < CalibEnd)
    {    
        //Read raw data
        ReadRawData();
        
        //Averaging
        AvgCalibAcc[0]+= (float)RawAcc[0];
        AvgCalibAcc[1]+= (float)RawAcc[1];
        AvgCalibAcc[2]+= (float)RawAcc[2];
        AvgCalibSampels+= 1.0;
        
        wait_ms(2);
    }
    
    //Collected enough data now form the average
    Offset[0]= -((float)(pRaw1g[0]) + AvgCalibAcc[0] / AvgCalibSampels);
    Offset[1]= -((float)(pRaw1g[1]) + AvgCalibAcc[1] / AvgCalibSampels);
    Offset[2]= -((float)(pRaw1g[2]) + AvgCalibAcc[2] / AvgCalibSampels);
}
void BMA180::userCalibration(short * Raw1g){
        
        long media[3] = {0,0,0};
        
        int count = 0;
        
        int endCal = GlobalTime.read_ms() + 500;
    
        while(GlobalTime.read_ms() < endCal){
                        
                    media[0] = media[0] + (float)RawAcc[0];
                    media[1] = media[1] + (float)RawAcc[1];  
                    media[2] = media[2] + (float)RawAcc[2];    
                    count++;      
                }
        Raw1g[0] = -(media[0]/count);
        Raw1g[1] = -(media[1]/count);
        Raw1g[2] = -(media[2]/count);    
 }