Tutorial: como utilizar o Breakout de Sensor de pressão barométrica com Arduino

Neste tutorial vamos mostrar como utilizar o breakout sensor de pressão barométrica com Arduino. Este breakout serve para medir pressão barométrica, altitude e temperatura. A sua comunicação é por I2C (SDA, SCL) o que torna fácil sua implementação. Para maiores informações, clique aqui!

Primeiramente, faça a seguinte ligação:

Cuidado! O sensor é alimentado por 3,3V! Depois de ter feito as ligações da figura acima, vamos para a programação exemplo, a qual está disponibilizada aqui, para a IDE do Arduino versão 1.0:

#include <Wire.h>

#define BMP085_ADDRESS 0x77 // I2C address of BMP085

const unsigned char OSS = 0; // Oversampling Setting

// Calibration values
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;

// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;

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

bmp085Calibration();
}

void loop()
{
float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
float pressure = bmp085GetPressure(bmp085ReadUP());
float atm = pressure / 101325; // "standard atmosphere"
float altitude = calcAltitude(pressure); //Uncompensated caculation - in Meters

Serial.print("Temperature: ");
Serial.print(temperature, 2); //display 2 decimal places
Serial.println("deg C");

Serial.print("Pressure: ");
Serial.print(pressure, 0); //whole number only.
Serial.println(" Pa");

Serial.print("Standard Atmosphere: ");
Serial.println(atm, 4); //display 4 decimal places

Serial.print("Altitude: ");
Serial.print(altitude, 2); //display 2 decimal places
Serial.println(" M");

Serial.println();//line break

delay(1000); //wait a second and get values again.
}

// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
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);
}

// Calculate temperature in deg C
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;
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up){
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)OSS) + 2)>>2;

// Calculate B4
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;
}

// Read 1 byte from the BMP085 at 'address'
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();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
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;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT(){
unsigned int ut;

// Write 0x2E into Register 0xF4
// This requests a temperature reading
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();

// Wait at least 4.5ms
delay(5);

// Read two bytes from registers 0xF6 and 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP(){

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

// Write 0x34+(OSS6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS6));
Wire.endTransmission();

// Wait for conversion, delay time dependent on OSS
delay(2 + (3OSS));

// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
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); // start transmission to device
Wire.write(address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
}

int readRegister(int deviceAddress, byte address){

int v;
Wire.beginTransmission(deviceAddress);
Wire.write(address); // register to read
Wire.endTransmission();

Wire.requestFrom(deviceAddress, 1); // read a byte

while(!Wire.available()) {
// waiting
}

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;
}

A comunicação com o Arduino é feita por I2C (SDA, SCL). A calibração está dentro da programação acima, dentro da função bmp085Calibration(). Esta função precisa ser colocada no começo do programa, caso contrário o sensor barométrico não funcionará adequadamente, pois sua precisão depende da calibração. A função bmp085GetPressure(unsigned long up) obtém a pressão do tempo atual em Pascal. A função bmp085GetTemperature(unsigned int ut) obtém a temperatura do tempo atual em graus Celsius. E a função calcAltitude(float pressure) calcula a altitude do local a partir da pressão barométrica adquirida.

Agora, conecte seu Arduino e abra a IDE do Arduino versão 1.0, cole a programação acima. Selecione a versão da placa Arduino (UNO, Duemilanove, etc) e a porta (COMx, ttyUSBx, ttyACMx, etc). Clique em "UPLOAD". Agora abra a "Serial Monitor" e selecione o baud para "9600" e "No line ending". Você verá as informações como a figura abaixo:

Sabendo que a altitude de São Paulo é de 760 metros em média e a altitude é calculada a partir da pressão barométrica, podemos concluir que a precisão é muito boa, já que a altitude mostrada é de 724,84 metros.

E é isso! Esperamos que tenha gostado! Caso tiver duvídas, poste aqui mesmo neste blog! Para sugestões de tutoriais, clique aqui! Para ver outros tutoriais e projetos desenvolvidos pela equipe LdG e por outros garagistas, clique aqui e aqui, respectivamente! Até a próxima!

Referências:

http://www.labdegaragem.org/loja/index.php/34-sensores/breakout-de-...

http://www.sparkfun.com/products/9694

http://bildr.org/2011/06/bmp085-arduino/

http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Pressure/BST...

http://www.sparkfun.com/tutorials/253

Exibições: 10249

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Matheus Romero da mata em 29 março 2016 às 12:20

Preciso fazer a leitura de 3 sensores desse ao mesmo tempo, cruzar os dados, para pesquisa em túnel de vento, porem este sensor utiliza saída I2C, como faço para ligar mais sensores iguais a este em paralelo, e fazer a medida de cada um sem interferências.

Comentário de Glauco Poltronieri em 28 fevereiro 2014 às 12:10

bom dia,

o código esta apresentando problemas ao fazer upload para o arduino na linha

 x2 = ((long)mc 11)/(x1 + md);

alguém poderia auxiliar ?????

obrigado

Comentário de valdir coan em 17 novembro 2013 às 20:40

Boa Noite a todos , eu preciso de uma ajuda

alguém ai sabe como alterar a frequência de um servo de 50 hz para 125 hz ????

aguardo.

Comentário de Sidney Alves Bastos em 8 novembro 2013 às 17:37

Adorei o que o Diego falou. Sou da área farmacêutica e vivo isso diariamente.

Comentário de Diego Pazze em 23 setembro 2013 às 11:01

Sim existe utilidade, em laboratórios onde á salas limpas e usado para medir uma cascata de pressão que garante que a pressão do ambiente esta positiva. Em laboratórios que se trabalha com virós e o inverso, a pressão tem que estar negativa. 

Comentário de Francisco Dórea Nascimento em 8 setembro 2013 às 17:33

Até no meu comentário o operador foi suprimido! A propósito, meu sensor está apresentando leituras erradas e uso o arduino uno rev 3, isto tem algo a ver? (temperadutra 190ºC, altitude negativa -655m, etc.)

Alguem tem alguma dica?

Comentário de Francisco Dórea Nascimento em 8 setembro 2013 às 17:30

Prezados, o código fonte acima não pode ser copiado e colado no arduino por conter um erro que aparece em várias partes do código. O erro é que na publicacao o operador "" (sinal de menor duas vezes, descolamento binário) foi suprimido, alterando as fórmulas. Deve haver uma maneira de apresentar o código corretamente. Isso dever ser por conta algum filtro do sitio, que impede a inserção de código html, ou coisa semelhante.

Comentário de Fredman Carlos de Moraes em 21 março 2013 às 18:30

Isso Sidney atraves da pressão podemos determinar a probalidade de chuvas sim.

Comentário de Sidney Alves Bastos em 21 março 2013 às 17:30

Existe alguma utilidade conhecer a pressão barométrica?

Parece que quando vai chover a pressão cai?

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço