Датчик давления BMP085- используется для измерения атмосферного давления,для,например предсказания смены погоды.
Кроме давления датчик выводит и данные о температуре.
Технические характеристики:
Напряжение питания 1.62V - 3.6V.
Интерфейс подключения I2C.
В продаже встречаются готовые платы как с стабилизатором,так и без него.Учитывайте это.
Примерная цена 3.5$.
Появились в продаже новая версия датчика - BMP180 ,цена которого менее 2.5$ . Подключение и работа с ним аналогична BMP085. Готовый модуль на фото имеет встроенный стабилизатор на 3.3в . Питание можно подключать как на вход 3.3в так и на вход vcc.
Подключение к arduina:
Для Duemilanove и Uno: SDA к выводу A4 ,SCL к A5 .У Arduina Mega подключается на соотвествующие выводы.Остальные выводы GND на GND,VCC на вывод 3.3в(если нет стабилизатора) или 5в(если есть стабилизатор).
#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/133.322, 2); //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 = (b7<<1)/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) msb<<8 | 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+(OSS<<6) into register 0xF4 // Request a pressure reading w/ oversampling setting Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission(); // Wait for conversion, delay time dependent on OSS delay(2 + (3<<OSS)); // 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; }
Подключение к Stellaris LaunchPad:
Используя карту пинов подключются SDA и SCL на соотвествующие выводы.И конечно же GND на GND,VCC к 3.3в(если нет стабилизатора) или 5в(если есть стабилизатор).
Работает скетч от arduino,кроме подпрограммы calcAltitude.
Работа в Linux системах ,в том числе с Raspberry PI в Raspbian:
Датчик подключается к SDA и SCL на соотвествующие выводы.И конечно же не забываем GND на GND,VCC к 3.3в(если нет стабилизатора) или 5в(если есть стабилизатор).У Raspberry PI шина I2C имеется на GPIO контактах,а при подключении датчика к обычному компьютеру можно использовать такой переходник.
код на с++ . компиляция командой gcc -Wall -o BMP085 ./smbus.c ./bmp085.c
Необходимо указать номер I2C порта в строке 71 (char *fileName = "/dev/i2c-порт";)
Дополнительная библиотека smbus (smbus.c и smbus.h ) для debian/raspbian , должна находится в той же папке при компиляции.
Для работы с Raspberry необходима установленная библиотека для работы с GPIO bcm2835.
В Linux Suse дополнительные библиотеки не требуются ,компилируется командой gcc -Wall -o BMP085 ./bmp085.c ,а так же необходимо закаментировать строки #include <linux/i2c.h> и #include "smbus.h" .
Запуск примера командой ./BMP085
Работа в Windows через USB
Подключение датчика на компьютер с windows поддерживается через I2C-USB переходник.
Приложение для работы с датчиком bmp085_win (Обновлено 5.12.14 !!). Написано на Си .Откомпилировано для windows используя cygwin.
Стороннее приложение для работы в датчиками BMP085/180 и DHT11/22 ссылка.
Обсуждение приложения на форуме.
Беспроводной вариант подключения
Используя 2.4ггц модули nRF, например на базе nRF24LE1
Подключение датчика используя wi-fi технологии
Используя ESP8266 модуль датчик можно подключить к wi-fi сети.