НАЗАД

Барометр. Применение датчика BMP180

Датчик BMP180 – датчик давления.

Для пример приводится два листинга программы работы с датчиком.

Пример программы ниже:

#include
#define ADDR_SENSOR 119 //0x77 // Адрес сенсора для I2C
int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
// Переменные для хранения данных калибровки из чипа BMP180
uint16_t ac4, ac5, ac6;
// Переменные для хранения данных калибровки из чипа BMP180
// Ultra Low Power OSS = 0, OSD = 5ms
// Standard OSS = 1, OSD = 8ms
// High OSS = 2, OSD = 14ms
// Ultra High Resolution OSS = 3, OSD = 26ms
const uint8_t oss = 3;
// Выбор режима точности
const uint8_t osd = 26;
// Настройка соответствующей задержки для режима точности
float T, P; // Настройка глобальных переменных для замера температуры и давления
void setup()
{
Wire.begin(); // Активация I2C
Serial.begin(9600); // Настройка последовательного порта
SENSOR_INIT(); // Инициализация датчика давления
delay(100);
}
void loop()
{
int32_t b5;
b5 = t_measure(); // Чтение и вычисление температуры
Serial.print("t_measure: ");
Serial.print(T, 2);
Serial.print(" C, ");
Serial.print(1.8 * T + 32.0, 2);
Serial.println(" F");
P = p_measure(b5); // Чтение и вычисление давления
Serial.print("p_measure: ");
Serial.print(P, 2);
Serial.print(" Pa, ");
P=P/100;
Serial.print(P * 0.0295299830714, 2);
Serial.println(" inHg");
Serial.println("");
delay(500); // Задержка в цикле
}
//Функция чтения одного байта
uint8_t one_byte_read(uint8_t addr)
{
uint8_t value;
Wire.beginTransmission(ADDR_SENSOR); // Начало передачи на устройство
Wire.write(addr);
// Отправка адреса регистра, из которого будет выполнено чтение
Wire.endTransmission(); // Завершение передачи
Wire.requestFrom(ADDR_SENSOR, 1); // Запрос одного с устройства
if(Wire.available() >= 1)
{
value = Wire.read(); // Получение одного байта
}
}
//Функция чтения двух байта
uint16_t two_byte_read(uint8_t addr)
{
unsigned char msb, lsb;
Wire.beginTransmission(ADDR_SENSOR); // Начало передачи на устройство
Wire.write(addr);
// Отправка адреса регистра, из которого будет выполнено чтение
Wire.endTransmission(); // Завершение передачи
Wire.requestFrom(ADDR_SENSOR, 2); // Запрос двух байт с устройства
if(Wire.available()<3)
{
msb = Wire.read(); //Чтение первого байта
lsb = Wire.read(); //Чтение второго байта
}
return (uint16_t) msb<<8|lsb;
}
//Функция инициации сенсора
void SENSOR_INIT()
{
ac1 = two_byte_read(0xAA);
ac2 = two_byte_read(0xAC);
ac3 = two_byte_read(0xAE);
ac4 = two_byte_read(0xB0);
ac5 = two_byte_read(0xB2);
ac6 = two_byte_read(0xB4);
b1 = two_byte_read(0xB6);
b2 = two_byte_read(0xB8);
mb = two_byte_read(0xBA);
mc = two_byte_read(0xBC);
md = two_byte_read(0xBE);
Serial.println("");
Serial.println("Sensor calibration data:");
Serial.print(F("AC1 = "));
Serial.println(ac1);
Serial.print(F("AC2 = "));
Serial.println(ac2);
Serial.print(F("AC3 = "));
Serial.println(ac3);
Serial.print(F("AC4 = "));
Serial.println(ac4);
Serial.print(F("AC5 = "));
Serial.println(ac5);
Serial.print(F("AC6 = "));
Serial.println(ac6);
Serial.print(F("B1 = "));
Serial.println(b1);
Serial.print(F("B2 = "));
Serial.println(b2);
Serial.print(F("MB = "));
Serial.println(mb);
Serial.print(F("MC = "));
Serial.println(mc);
Serial.print(F("MD = "));
Serial.println(md);
Serial.println("");
}
//Функция измерения давления
float p_measure(int32_t b5)
{
int32_t x1, x2, x3, b3, b6, p,
uint32_t b4, b7;
UP = read_p_measure(); // Чтение «сырых» данных давления
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15;
b7 = ((uint32_t)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 = p + ((x1 + x2 + 3791) >> 4);
return p;
}
//Функция чтения замера температуры
int32_t t_measure()
{
int32_t x1, x2, b5, UT;
Wire.beginTransmission(ADDR_SENSOR);
// Начало передачи на устройство
Wire.write(0xf4);
// Отправка адреса, из которого будут производится чтение
Wire.write(0x2e);
// Отправка адреса, из которого будут производится чтение
Wire.endTransmission(); // Завершение передачи
delay(10);
UT = two_byte_read(0xf6);
Serial.println(UT);
// Calculate true t_measure
x1 = (UT - (int32_t)ac6) * (int32_t)ac5 >> 15;
x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md);
b5 = x1 + x2;
T = (b5 + 8) >> 4;
T = T / 10.0;
// Преобразование в градусы цельсия
return b5;
}
//Функция чтения замера давления
int32_t read_p_measure()
{
int32_t value;
Wire.beginTransmission(ADDR_SENSOR); // Начало передачи на устройство
Wire.write(0xf4);
// Отправка адреса, из которого будут производится чтение
Wire.write(0x34 + (oss << 6));
// Отправка адреса, из которого будут производится чтение
Wire.endTransmission(); // Завершение передачи
delay(osd); // Задержка в соответствии с выбранным режимом
Wire.beginTransmission(ADDR_SENSOR);
Wire.write(0xf6);
// Отправка адреса, из которого будут производится чтение Wire.endTransmission();
Wire.requestFrom(ADDR_SENSOR, 3); // Запрос трех байт
if(Wire.available() >= 3)
{
value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 - oss);
}
return value; // Возврат значения
}