Датчика BMP085 дает нам возможность не только измерять атмосферное давление но и температуру воздуха а так же отображать высоту над уровнем моря.
BMP085 является своего рода высокоточным датчиком давления с ультра-низким энергопотреблением. Отличная производительность BMP085 и точность достигает минимального значения измерения давления 0.03hPa, и это с очень низким энергопотреблением, только 3μA.
Блок схема датчика BMP085 :
Основные характеристики датчика BMP085 :
- Диапазон давления: 300 – 1100hPa
- Напряжение питания: от 3 до 5V
- LCC8 пакет: керамическом корпус (LCC)
- Размер: 2 см × 1.57cm
- Низкое энергопотребление: 5 мкА в стандартном режиме
- Точность: режим пониженного энергопотребления, разрешение 0.06hPa (0,5 м)
- Высокий линейный режим с разрешением 0.03hPa (0,25 м)
- Подключение: протокол связи I2C
- Возможность измерения температуры
- Время отклика: 7.5ms
- Ток в режиме ожидания: 0,1 мкA
- Устраняет необходимость использования внешней тактовой цепи
- Температурная компенсация
Контакты датчика BMP085 :
Датчик имеет 6 контактов для подключения к разным устройствам
Подключение датчика BMP085 :
Для подключения датчика BMP085 к arduino нам понадобится только 4 контакта:
- Vcc – подключаем к питанию +5в
- SDA – SDA на плате arduino (A4)
- SCL – SCL на плате arduino (A5)
- GND – подключаем к питанию -5в
После успешного подключения датчика, требуется установить библиотеку для работы с датчиком.
У нас есть две библиотеки для работы с датчиком давления и мы их рассмотрим чуть позже, а для начала скачайте обе библиотеки.
Библиотека для работы с датчиком атмосферного давления BMP085 от Adafruit
Библиотека для работы с датчиком давления BMP085
Для начала рассмотрим библиотеку Adafruit BMP085, после установки которой открываем тестовый скетч BMP085test
#include <Wire.h>
#include <Adafruit_BMP085.h>
// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here
Adafruit_BMP085 bmp;
void setup() {
Serial.begin(9600);
if (!bmp.begin()) {
Serial.println("Could not find a valid BMP085 sensor, check wiring!");
while (1) {}
}
}
void loop() {
Serial.print("Temperature = ");
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.readPressure());
Serial.println(" Pa");
// Calculate altitude assuming 'standard' barometric
// pressure of 1013.25 millibar = 101325 Pascal
Serial.print("Altitude = ");
Serial.print(bmp.readAltitude());
Serial.println(" meters");
// you can get a more precise measurement of altitude
// if you know the current sea level pressure which will
// vary with weather and such. If it is 1015 millibars
// that is equal to 101500 Pascals.
Serial.print("Real altitude = ");
Serial.print(bmp.readAltitude(101500));
Serial.println(" meters");
Serial.println();
delay(500);
}
и загружаем его в нашу плату arduino uno , потом открываем монитор порта и смотрим показания датчика
Temperature = 23.93 *C температура в градусах Цельсия
Pressure = 98918 Pa атмосферное давление в Паскаля
Altitude = 201.76 meters высота над уровнем моря в метрах при стандартном давлении 1013.25 миллибар = 101325 Па (автоматически определенная высота )
Real altitude = 215.91 meters высота над уровнем моря в метрах при установленном давлении 1015 миллибар = 101500 Па ( значение можно установить вручную в миллибарах для более точного отображения высоты)
С показаниями датчика мы разобрались, а теперь можно переходить к второй библиотеке BMP085
у которой есть три тестовых скетча для демонстрации работы датчика давления.
Для начала откроем первый скетч BMP085_output
// BMP085_output
// by Filipe Vieira
// Simple example of library usage with almost every BMP085 and lib features being used.
#include <Wire.h>
#include <BMP085.h>
BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0, Altitude = 0;
void setup(void) {
Serial.begin(9600);
Wire.begin();
delay(1000);
dps.init();
showall();
Serial.println("Registers dump");
Serial.println("==========================================================");
dumpRegisters();
Serial.println("Calibration data");
Serial.println("==========================================================");
dps.dumpCalData();
delay(5000);
}
void loop(void) {
dps.getTemperature(&Temperature);
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
Serial.print("Temp(C):");
Serial.print(Temperature);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
}
void showall(void) {
Serial.println("Current BMP085 settings");
Serial.println("==========================================================");
Serial.print("device address = 0x");
Serial.println(dps.getDevAddr(), HEX);
Serial.print("Mode = ");
switch (dps.getMode()) {
case MODE_ULTRA_LOW_POWER:
Serial.println("MODE_ULTRA_LOW_POWER");
break;
case MODE_STANDARD:
Serial.println("MODE_STANDARD");
break;
case MODE_HIGHRES:
Serial.println("MODE_HIGHRES");
break;
case MODE_ULTRA_HIGHRES:
Serial.println("MODE_ULTRA_HIGHRES");
break;
}
}
void dumpRegisters() {
byte ValidRegisterAddr[]={0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,
0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xF6,0xF7,0xF8,0xF9};
byte _b, i, totregisters = sizeof(ValidRegisterAddr);
Serial.println("---dump start---");
Serial.println("Register address|Register data");
Serial.println("Reg.address(hex,dec) Reg.data(bin,hex,dec)");
for (i=0;i<totregisters;i++){
Serial.print("0x");
Serial.print(ValidRegisterAddr[i], HEX);
Serial.print(",");
Serial.print(ValidRegisterAddr[i], DEC);
Serial.print(",");
dps.readmem(ValidRegisterAddr[i], 1, &_b);
Serial.print("b");
print_bits(_b);
Serial.print(",0x");
Serial.print(_b,HEX);
Serial.print(",");
Serial.println(_b,DEC);
}
Serial.println("---dump end---");
}
void print_bits(byte val){
int i;
for(i=7; i>=0; i--)
Serial.print(val >> i & 1, BIN);
}
/* void print_unit16(uint16_t val){
int i;
for(i=15; i>=0; i--)
Serial.print(val >> i & 1, BIN);
}
*/
После заливки скетча в arduino uno открываем монитор порта и смотрим
Скетч определил адрес устройства device address = 0x77 ( может нам потребоваться при подключении нескольких датчиков одновременно ) и сделал калибровку всех параметров , а потом отобразил значения температуры Temp(C):239, высоты Alt(cm):-188 и давления Pressure(Pa):98901 —- в основном этот скетч служит для общего тестирования датчика BMP085.
Далее мы откроем тестовый скетч BMP085_test1
// BMP085_test1
// by Filipe Vieira
// Simple test of BMP085 output using default settings.
// This example requires AUTO_UPDATE_TEMPERATURE to be true in bmp085.h otherwise temperature will not update.
// IMPORTANT!! To get correct values you MUST CHANGE init() parameters, in
// this example I've set 250m based on GPS data for my location.
#include <Wire.h>
#include <BMP085.h>
BMP085 dps = BMP085(); // Digital Pressure Sensor
long Temperature = 0, Pressure = 0, Altitude = 0;
void setup(void) {
Serial.begin(9600);
Wire.begin();
delay(1000);
// uncomment for different initialization settings
//dps.init(); // QFE (Field Elevation above ground level) is set to 0 meters.
// same as init(MODE_STANDARD, 0, true);
//dps.init(MODE_STANDARD, 101850, false); // 101850Pa = 1018.50hPa, false = using Pa units
// this initialization is useful for normalizing pressure to specific datum.
// OR setting current local hPa information from a weather station/local airport (QNH).
dps.init(MODE_ULTRA_HIGHRES, 25000, true); // 250 meters, true = using meter units
// this initialization is useful if current altitude is known,
// pressure will be calculated based on TruePressure and known altitude.
// note: use zeroCal only after initialization.
// dps.zeroCal(101800, 0); // set zero point
}
void loop(void) {
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
}
Здесь скетч простой и для настройки датчика давления нам потребуется минимум усилий. А точнее если нам известно высоту над уровнем моря в том месте , где мы будем измерять давление то мы просто в строке
dps.init(MODE_ULTRA_HIGHRES, 25000, true); // 250 meters, true = using meter units
// this initialization is useful if current altitude is known,
// pressure will be calculated based on TruePressure and known altitude.
меняем значение 25000 на нашу высоту , например 20900 — что значит что наша высота составляет 209 метров над уровнем моря
dps.init(MODE_ULTRA_HIGHRES, 20900, true); // 250 meters, true = using meter units
// this initialization is useful if current altitude is known,
// pressure will be calculated based on TruePressure and known altitude.
загружаем после этого скетч в ардуино и смотрим через монитор порта наши значения высоты и атмосферного давления
Ну а теперь переходим к третьему тестовому скетчу BMP085_test2
// BMP085_test2
// by Filipe Vieira
// Simple test of BMP085 output using default settings using dynamic update.
// In order to take full advantage of dynamic measurement, automatic temperature updates must be disabled.
// To disable automatic updates set AUTO_UPDATE_TEMPERATURE to false in bmp085.h.
// IMPORTANT!! To get correct values you MUST CHANGE init() parameters, in
// this example I've set 250m based on GPS data for my location.
#include <Wire.h>
#include <BMP085.h>
BMP085 dps = BMP085(); // Digital Pressure Sensor
long Pressure = 0, Altitude = 0;
unsigned long time1=0;
void setup(void) {
Serial.begin(9600);
Wire.begin();
delay(1000);
// uncomment for different initialization settings
//dps.init(); // QFE (Field Elevation above ground level) is set to 0 meters.
// same as init(MODE_STANDARD, 0, true);
//dps.init(MODE_STANDARD, 101850, false); // 101850Pa = 1018.50hPa, false = using Pa units
// this initialization is useful for normalizing pressure to specific datum.
// OR setting current local hPa information from a weather station/local airport (QNH).
dps.init(MODE_STANDARD, 25000, true); // 250 meters, true = using meter units
// this initialization is useful if current altitude is known,
// pressure will be calculated based on TruePressure and known altitude.
// note: use zeroCal only after initialization.
// dps.zeroCal(101800, 0); // set zero point
}
void loop(void) {
// calculate temperature every 1 sec (dynamic measurement)
// NOTE: in order to take full advantage of dynamic measurement set AUTO_UPDATE_TEMPERATURE to false in bmp085.h
if (((millis() - time1)/1000.0) >= 1.0) {
dps.calcTrueTemperature();
time1 = millis();
}
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
}
Настройка BMP085_test2 производится аналогично BMP085_test1 но в тестовом скетче номер 2 есть небольшое отличие, а именно он измеряет температуру динамически с интервалом в 1 секунду.
Но при загрузке скетча BMP085_test2 и открытии монитора порта мы не увидим отображения среднего значения температуры или просто температуры при загрузке BMP085_test1
Для того чтобы отображалась температура а не только значения высоты и давления, нам потребуется добавить в скетчи несколько строк кода, а именно в строку
long Pressure = 0, Altitude = 0;
меняем на
long Temperature = 0, Pressure = 0, Altitude = 0;
потом строки
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
меняем на
dps.getTemperature(&Temperature);
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
и строки
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
меняем на
Serial.print("Temp(C):");
Serial.print(Temperature);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
после этого загружаем скетч в arduino uno и открываем монитор порта
Теперь как мы видим у нас появилось отображение температуры в мониторе порта , но данные отображаются не очень красиво, и это мы будем менять. Для начала поменяем вывод на более удобный.
Например отобразим температуру в формате Temp(C): 23.7 высоту в метрах Alt(m):250.19 а давление в мм.рт.ст. Pressure(mm):764.1
Для этого строчки кода
Serial.print("Temp(C):");
Serial.print(Temperature);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
меняем на
Serial.print("Temp(C):");
Serial.print(Temperature*0.1,1);
Serial.print(" Alt(m):");
Serial.print(Altitude*0.01);
Serial.print(" Pressure(mm):");
Serial.println(Pressure/133.3,1);
Заливаем скетч и открываем монитор порта
И видим что теперь у нас данные отображаются более удобно и красиво.
|