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...
Comentar
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.
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
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.
Adorei o que o Diego falou. Sou da área farmacêutica e vivo isso diariamente.
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.
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?
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.
Isso Sidney atraves da pressão podemos determinar a probalidade de chuvas sim.
Existe alguma utilidade conhecer a pressão barométrica?
Parece que quando vai chover a pressão cai?
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por
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)