Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

PIC: BMP085 - Sensor de Pressão

Share:

PIC: BMP085 - Sensor de Pressão






Atmospheric Pressure Sensor BMP085 Module GY-65

BMP085 da Bosch é um sensor de pressão barométrica. Possui uma faixa de medição de entre 30000 e 110000 Pa. O BMP085 também proporciona uma medição da temperatura de 0 à 65°C.

O BMP085 tem interface I2C, então você pode facilmente comunicá-lo com seu microcontrolador através dos pinos SDA( dados ) e SCL ( clock ).

Este sensor pode ser utilizados em projetos visando a previsão do tempo, pois a pressão atmosférica está diretamente relacionado com as mudanças no clima. Também é possível utilizá-lo como medição da altitude.



PINOS
BMP085Função
VCCAlimentação (5V)
GNDGND
EOCFim da conversão (HIGH)
XCLRMaster Clear (LOW)
Reset do sensor
SCLClock
SDADados


BIBLIOTECA

#include <built_in.h>

#ifdef USE_BMP085_SOFT_I2C
        #define BMP085_I2C_Wr Soft_I2C_Write
        #define BMP085_I2C_Rd Soft_I2C_Read
        #define BMP085_I2C_Stop Soft_I2C_Stop
        #define BMP085_I2C_Start Soft_I2C_Start
        #define BMP085_Scl Soft_I2C_Scl
        #define BMP085_Sda Soft_I2C_Sda
        #define BMP085_Scl_Direction Soft_I2C_Scl_Direction
        #define BMP085_Sda_Direction Soft_I2C_Sda_Direction
#else
        #define BMP085_I2C_Wr I2C1_Wr
        #define BMP085_I2C_Rd I2C1_Rd
        #define BMP085_I2C_Stop I2C1_Stop
        #define BMP085_I2C_Start I2C1_Start
#endif

#define BMP085_ADDRESS              0xEE

#define BMP085_ULTRALOWPOWER         0
#define BMP085_STANDARD              1
#define BMP085_HIGHRES               2
#define BMP085_ULTRAHIGHRES          3

//Calibration Data
#define BMP085_CAL_AC1          0xAA //0
#define BMP085_CAL_AC2          0xAC //1
#define BMP085_CAL_AC3          0xAE //2
#define BMP085_CAL_AC4          0xB0 //3
#define BMP085_CAL_AC5          0xB2 //4
#define BMP085_CAL_AC6          0xB4 //5
#define BMP085_CAL_B1           0xB6 //6
#define BMP085_CAL_B2           0xB8 //7
#define BMP085_CAL_MB           0xBA //8
#define BMP085_CAL_MC           0xBC //9
#define BMP085_CAL_MD           0xBE //10

#define BMP085_CONTROL          0xF4
#define BMP085_TEMPDATA         0xF6
#define BMP085_PRESSUREDATA     0xF6
#define BMP085_READTEMPCMD      0x2E
#define BMP085_READPRESSURECMD  0x34

typedef struct
{
        float Temperatura;
        float Pressao;
        float Altitude;
}BMP085_Barometer;

typedef struct
{
 int AC1;
 int AC2;
 int AC3;
 unsigned AC4;
 unsigned AC5;
 unsigned AC6;
 int mB1;
 int mB2;
 int MB;
 int MC;
 int MD; 
}Calibration_Data;

Calibration_Data Cal;

void BMP085_Init()
{
char i;
  BMP085_I2C_Start();
  BMP085_I2C_Wr( BMP085_ADDRESS ); 
  BMP085_I2C_Wr( BMP085_CAL_AC1 );
  BMP085_I2C_Start();
  BMP085_I2C_Wr( BMP085_ADDRESS | 1 );
  
  for( i=0; i < 10; i++)
  {
     ((int*)&Cal)[i] = (BMP085_I2C_Rd(1) << 8) + BMP085_I2C_Rd(1);
  
  }
  ((int*)&Cal)[10] = (BMP085_I2C_Rd(1) << 8) + BMP085_I2C_Rd(0);
  BMP085_I2C_Stop();
}

void BMP085_Read( char oversampling, BMP085_Barometer *Bar )
{
char cmd = 0x34;
long UT=0, UP, _B3, _B5, _B6, X1, X2, X3, pp;
unsigned long _B4, _B7;

    
 //Read Uncompensated Temperature Value
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS );
 BMP085_I2C_Wr( BMP085_CONTROL );
 BMP085_I2C_Wr( BMP085_READTEMPCMD );
 BMP085_I2C_Stop();
    
 Delay_ms( 5 );
    
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS );
 BMP085_I2C_Wr( BMP085_TEMPDATA );
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS | 1 );
 Hi(UT) = BMP085_I2C_Rd(1);
 Lo(UT) = BMP085_I2C_Rd(0);
 BMP085_I2C_Stop();
 
 //Read Uncompensated Pressure Value
 cmd.B6 = oversampling.B0;
 cmd.B7 = oversampling.B1;
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS );
 BMP085_I2C_Wr( BMP085_CONTROL );
 BMP085_I2C_Wr( cmd );
 BMP085_I2C_Stop();

 switch(oversampling)
 {
 case 0: Delay_ms(5); break;
 case 1: Delay_ms(8); break;
 case 2: Delay_ms(14); break;
 case 3: Delay_ms(26); break;
 }
           
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS );
 BMP085_I2C_Wr( BMP085_PRESSUREDATA );
 BMP085_I2C_Start();
 BMP085_I2C_Wr( BMP085_ADDRESS | 1 );
 Higher(UP) = BMP085_I2C_Rd(1);
 Hi(UP) = BMP085_I2C_Rd(1);
 Lo(UP) = BMP085_I2C_Rd(0);
 BMP085_I2C_Stop();
 Highest(UP) = 0;
 UP >>= ( 8 - oversampling );
 
 //Calcule True Temperature
 X1 = ( UT - Cal.AC6 );
 X1 *= Cal.AC5;
 X1 >>= 15;
 
 X2 = ((long)Cal.MC << 11);
 X2 /= (X1 + Cal.MD);
    
 _B5 = X1 + X2;
    
 Bar->Temperatura = ( (_B5 + 8) >> 4 ) / 10;
     
 //Calcule True Pressure
 _B6 = _B5 - 4000;
    
 X1 = pow(_B6, 2);
 X1 >>= 12;
 X1 *= (long)Cal.mB2;
 X1 >>= 11; 
    
 X2 = ((long)Cal.AC2 * _B6);
 X2 >>= 11;
    
 X3 = X1 + X2; 
    
 _B3 = (long)Cal.AC1 * 4;
 _B3 += X3;
 _B3 <<= oversampling;
 _B3 += 2;
 _B3 >>= 2;
    
 X1 = (Cal.AC3 * _B6);
 X1 >>= 13;
 
 X2 = (_B6 * _B6);
 X2 >>= 12;
 X2 *= Cal.mB1;
 X2 >>= 8;
 X2 >>= 8;
 
 X3 = ((X1 + X2) + 2 );
 X3 >>= 2;
    
 _B4 = Cal.AC4;
 _B4 *= (unsigned long)(X3 + 32768);
 _B4 >>= 15;
 
 _B7 = (unsigned long)(UP - _B3);
 _B7 *= (unsigned long)(50000 >> oversampling);
 
 if( _B7 < 0x80000000 )
 {
   pp = ((_B7 * 2) / _B4);
 }
 else
 {
   pp = ((_B7 / _B4) * 2);
 }
    
 X1 = pow((pp >> 8), 2);
 X1 *= 1519;
 X1 >>= 15;
 
 X2 = (-7357 * pp);
 X2 >>= 8;
 X2 >>= 8;
 
 Bar->Pressao = pp + ( (X1 + X2 + 3791) >> 4);
 
 //Calcula a Altitude
 Bar->Altitude = 1 - pow( (Bar->Pressao / 101035), 0.190295 );
 Bar->Altitude *= 44330;
}

EXEMPLO
MikroC PRO PIC
/*
    BMP085 - Sensor de Pressao Digital

    MCU: PIC18F4550
    CLOCK: HS + PLL ( 48 Mhz )
    COMPILADOR: MikroC PRO PIC
*/

#include <nokia3310.h>
#include <bmp085.h>

sbit Nokia_SCE at RD0_Bit;
sbit Nokia_RST at RD1_Bit;
sbit Nokia_DC at RD2_Bit;
sbit Nokia_MOSI at RD3_Bit;
sbit Nokia_CLK at RD4_Bit;
sbit Nokia_SCE_Direction at TRISD0_Bit;
sbit Nokia_RST_Direction at TRISD1_Bit;
sbit Nokia_DC_Direction at TRISD2_Bit;
sbit Nokia_MOSI_Direction at TRISD3_Bit;
sbit Nokia_CLK_Direction at TRISD4_Bit;

char text[12];
BMP085_Barometer Bar;

void main()
{
    ADCON1 = 0x0F;

    Nokia_Init();
    Nokia_Clear();

    I2C1_Init( 100000 );
    Uart1_Init(9600);
    BMP085_Init();
    
    while(1)
    {
       BMP085_Read( 0, &Bar );
       
       LongWordToStr( Bar.Pressao, text );
       LTrim(text);
       Nokia_Set_Cursor( 0, 0 );
       Nokia_Out( "Pressao: ", BLACK );
       Nokia_Out( text , BLACK );
       Nokia_Out( " Pa", BLACK );
       
       IntToStr( Bar.Altitude, text );
       LTrim(text);
       Nokia_Set_Cursor( 0, 1 );
       Nokia_Out( "Altitude: ", BLACK );
       Nokia_Out( text , BLACK );
       Nokia_Out( "m", BLACK );

       IntToStr( Bar.Temperatura, text );
       LTrim(text);
       Nokia_Set_Cursor( 0, 2 );
       Nokia_Out( "Temp.: ", BLACK );
       Nokia_Out( text , BLACK );
       Nokia_Out( " C", BLACK );

       Delay_ms( 300 );
    }
}





No teste utilizei o módulo BMP085 modelo GY-65 comprado no Mercado Livre. Este módulo possui um regulador de tensão de 3.3V e os resistores de Pull-up e é alimentado com 5V. Se o seu módulo for de outro modelo, verifique se o mesmo pode ser ligar direto nos 5V, pois o BMP085 é alimentado com 3.3V.

DOWNLOAD
Projeto: BMP085.rar

7 comentários:

  1. Amigo, que interessante, é isso que eu necessito. Você já mexeu alguma vez com o sensor barométrico HP03M da Hope RF? estou a uns 3 meses mexendo em sensores desse tipo HP03SA e agora o HP03M e não obtive sucesso em nenhum deles... apesar de ter (quase) certeza que a leitura do AD e da EEPROM estejam certas, os valores finais que eu obtenho do sensor estão muito diferentes dos valores reais tipo a temp na sala estar 25,6ºC e ele indicar 31ºC e pressão indicar 211hpa sendo 1017 o valor real... nem imagino mais o que verificar nele para conseguir usá-lo.

    ResponderExcluir
  2. Tambem estou precisando deste componente para proteus

    ResponderExcluir
  3. Ola .
    Tenho um sensor BMP 180 como usaria ele nesse mesmo projeto , apenas substituo a biblioteca?
    grato.

    ResponderExcluir