I2C interface of Bosch BMP085 pressure/temperature sensor.

bmp085.cpp

Committer:
davernm
Date:
2013-04-14
Revision:
3:9c82e6a0172a
Parent:
2:4ebe4d41b588

File content as of revision 3:9c82e6a0172a:

/*This code was written as an example program for students advancing from C programming to C++.
// 
//



 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *


Test code:
//
//
//
//
//this program uses a ticker to read the BMP085 every 5 seconds and updates the lcd with
//the pressure and temperature reading

#include "mbed.h"
#include "TextLCD.h"
#include "bmp085.h"


void doConv(void);
void dispVals(long T,long P);

//Three different constructors:

BMP085 X(p28,p27,p5,3);//create an instance,using an EOC pin and oss set to 3 
//BMP085 X(p28,p27,3);//create an instance without an EOC pin, oss 3
//BMP085 X(p28,p27);//create an instance, no EOC, oss will default to 0
TextLCD lcd(p7, p6, p8, p9, p10, p11);

Ticker myT;

int main() {
  
    myT.attach(&doConv,5); //every 5 seconds
    X.readCal(); //read calibration data 
    doConv(); //call once
    while(1)
    {
    //do something
    }
    
 
}


void dispVals(long T,long P)//display data on the lcd
{
  lcd.locate(0,0); //lcd line 1
   
   char buf[20],*P1="Temp:",*P2="Press:";
   lcd.printf(P2);
   lcd.locate(strlen(P2),0);
   float p=(float)P;
   p/=100;//convert to milli bar
   sprintf(buf,"%.2f",p);
   lcd.printf("%s",buf);
    
   lcd.locate(0,1); // lcd line 2
   lcd.printf(P1);
   float t=(float)T;
   t/=10;//convert to deg C
   sprintf(buf,"%.2f",t);
   lcd.locate(strlen(P1),1);
   lcd.printf("%s",buf);
    
    
 }
void doConv(void)
{
    long UT,UP,T,P;
  

  UT=X.readUT(); //read uncompensated temperature
  UP= X.readUP(); //read uncompensated pressure
  X.calVals(UT,UP,&T,&P); //calculate temperature and pressure
  dispVals(T,P); //dsiplay resuls on lcd
}
  
*/
#include "mbed.h"
#include "bmp085.h"

    BMP085:: BMP085(PinName sda,PinName scl,int Oss):i2c(sda,scl){
  //this constructor does not use an end of conversion pin
     i2c.frequency(50000);
     flag=false;
     oss=Oss;
    }
  BMP085::BMP085(PinName sda,PinName scl):i2c(sda,scl){
  //this version has no end  of conversion, and has the oversampling 
  //default to 0.
     i2c.frequency(50000);
     flag=false;
     oss=0;//default to 0
     
    }
      BMP085::BMP085(PinName sda,PinName scl, PinName EOC,int Oss) : i2c(sda,scl)  {
      //end of conversion pin is used as well as oss being set 
      //
   EOCptr = new DigitalIn(EOC);
     i2c.frequency(50000);
     flag=true; //eoc pin is present
     oss=Oss;
     
    }
   


void BMP085::calVals(long UT,long UP, long *Temp,long *Pre)//see data sheet for calculations
{

    long X1,X2,X3,B6,B3,B7,p,B5,T;
    unsigned long B4;
    
    X1=((UT-AC6)*AC5)>>15; 
    X2=(MC<<11)/(X1+MD);
    B5=X1+X2;
    T=(B5+8)>>4;
    
    *Temp=T;
    B6=B5-4000;
    X1=(B6*B6)/4096;
    X1*=B2;
    X1>>=11; 
    X2=(AC2*B6)/2048;
    X3=X1+X2;
    B3=(((AC1*4+X3)<<oss)+2)/4;
    X1=(AC3*B6)>>13;
    X2=(B6*B6)>>12;
    X2*=B1;
    X2>>=16;
    X3=((X1+X2)+2)>>2;
    B4=(AC4*(unsigned long)(X3+32768))/32768;
    B7=((unsigned long)(UP-B3)*(50000>>oss));
    
    if (B7<0x80000000) p=(B7*2)/B4;
    
    else p=(B7/B4)*2;
    X1=(p>>8)*(p>>8);
    X1=(X1*3038)>>16;
    X2=(-7357*p)>>16;
    p+=(X1+X2+3791)>>4;
    *Pre=p;
   
    
        
 }
    
long BMP085::readUT(void) //uncompensated temperature 
{
     float delVals[]={4.5,7.5,13.5,25.5}; //data sheet values
    char wReg[2]; // write 0x2e into reg 0xf4
     wReg[0] = 0xF4;
     wReg[1] = 0x2E; 
     i2c.write(0xee, wReg, 2);
    if (!flag)wait_ms(delVals[oss]);
    //use EOC
    else while (EOCptr->read()==0); //wait for 1
                // uncompensated temperature
    char cmd = 0xF6;// read reg 0xf6
    i2c.write(0xee, &cmd, 1);

    char Arr[2];
    i2c.read(0xef,Arr,2);
    long UT=(Arr[0]<<8)|Arr[1];
    return UT;
}
    

       
long BMP085::readUP(void)//uncompensated pressure
{ 
     float delVals[]={4.5,7.5,13.5,25.5}; //data sheet values
     char wReg[2]; // write 0x34 into reg 0xf4
     wReg[0] = 0xF4;
     wReg[1] = 0x34+(oss<<6); 
     i2c.write(0xee, wReg, 2);
     if (!flag)wait_ms(delVals[oss]);
   else while (EOCptr->read()==0);
     char cmd=0xf6;
     i2c.write(0xee,&cmd,1);
     char Arr[3];
     i2c.read(0xef,Arr,3); //3 byte data
     long UP=((Arr[0]<<16)|(Arr[1]<<8)|Arr[2])>>(8-oss);

     
     return UP;
} 
     
void BMP085::readCal(void)//read the onboard calibration data
{
    int i;
    char addr=0xaa;
    char dumArr[1];
    
    for (i=0;i<22;i++)
    {
        i2c.write(0xee,&addr,1); 
        i2c.read(0xef,dumArr,1);
        Vals[i]=dumArr[0];
        addr++;
    }
   AC1=(Vals[0]<<8)|Vals[1];
   AC2=(Vals[2]<<8)|Vals[3];
   AC3=(Vals[4]<<8)|Vals[5];
   AC4=(Vals[6]<<8)|Vals[7];
   AC5=(Vals[8]<<8)|Vals[9];
   AC6=(Vals[10]<<8)|Vals[11];
   B1=(Vals[12]<<8)|Vals[13];
   B2=(Vals[14]<<8)|Vals[15];
   MB=(Vals[16]<<8)|Vals[17];
   MC=(Vals[18]<<8)|Vals[19];
   MD=(Vals[20]<<8)|Vals[21];  
 
 }