Sensor de pressão barométrica com Arduino

bmp085

O BMP085 é um componente (sucessor do SMD500) que pertence a uma nova geração de sensores de pressão com alta precisão.

O consumo reduzido dos seus componentes foi optimizado para o uso em Smartphones, PDAs, sistemas de navegação GPS, etc. O módulo funciona com uma tensão de 1,8 a 3,6V e o intervalo de leitura de pressão varia de 300 a 1100 hPa (hectoPascal), o que permite determinar altitudes desde 9000 metros acima do nível do mar, até -500m. A conexão com o controlador é feita por apenas 2 pinos, usando a interface I2C.

Material:

1 Sensor barométrico BMP085.

Montagem:

ligação_bmp085

Código Arduino:


#include <Wire.h>

#define BMP085_ADDRESS 0x77

const unsigned char OSS = 0;

int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

long b5;

void setup(){
Serial.begin(9600);
Wire.begin();

bmp085Calibration();
}

void loop()
{
float temperature = bmp085GetTemperature(bmp085ReadUT());
float pressure = bmp085GetPressure(bmp085ReadUP());
float atm = pressure / 101325;
float altitude = calcAltitude(pressure);
Serial.print("Temperature: ");
Serial.print(temperature, 2);
Serial.println("deg C");

Serial.print("Pressure: ");
Serial.print(pressure, 0);
Serial.println(" Pa");

Serial.print("Standard Atmosphere: ");
Serial.println(atm, 4);

Serial.print("Altitude: ");
Serial.print(altitude, 2);
Serial.println(" M");

Serial.println();

delay(1000);
}

void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}

float bmp085GetTemperature(unsigned int ut){
long x1, x2;

x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc 11)/(x1 + md);
b5 = x1 + x2;

float temp = ((b5 + 8)>>4);
temp = temp /10;

return temp;
}

long bmp085GetPressure(unsigned long up){
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;

x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)OSS) + 2)>>2;

x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b71)/b4;
else
p = (b7/b4)1;

x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;

long temp = p;
return temp;
}

char bmp085Read(unsigned char address)
{
unsigned char data;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;

return Wire.read();
}

int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();

return (int) msb8 | lsb;
}

unsigned int bmp085ReadUT(){
unsigned int ut;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();

delay(5);

ut = bmp085ReadInt(0xF6);
return ut;
}

unsigned long bmp085ReadUP(){

unsigned char msb, lsb, xlsb;
unsigned long up = 0;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS6));
Wire.endTransmission();

delay(2 + (3OSS));

msb = bmp085Read(0xF6);
lsb = bmp085Read(0xF7);
xlsb = bmp085Read(0xF8);

up = (((unsigned long) msb 16) | ((unsigned long) lsb 8) | (unsigned long) xlsb) >> (8-OSS);

return up;
}

void writeRegister(int deviceAddress, byte address, byte val) {
Wire.beginTransmission(deviceAddress);
Wire.write(address);
Wire.write(val);
Wire.endTransmission();
}

int readRegister(int deviceAddress, byte address){

int v;
Wire.beginTransmission(deviceAddress);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(deviceAddress, 1);

while(!Wire.available()) {
}

v = Wire.read();
return v;
}

float calcAltitude(float pressure){

float A = pressure/101325;
float B = 1/5.25588;
float C = pow(A,B);
C = 1 - C;
C = C /0.0000225577;

return C;
}

Observação:

A calibração já está efetuada no código do Arduino, dentro da função bmp085Calibration(). Esta função necessita de ser colocada no início do código pois, caso contrário, o sensor barométrico pode não funcionar adequadamente, porque a sua precisão depende da calibração. A função bmp085GetPressure(unsigned long up) obtém a pressão exata do momento, em Pascal. A função bmp085GetTemperature(unsigned int ut) obtém a temperatura exata do momento, em graus Celsius. E a função calcAltitude(float pressure) calcula a altitude do local a partir da pressão barométrica adquirida.

serial monitor

Agora pessoal, é só pegar no vosso arduino, dar uma vista de olhos a este tutorial e começar a desenvolver o vosso projecto! Se ainda não tiveres o material necessário para o projecto, encontra-o aqui na nossa loja Boxelectronica.

Comentários no Facebook