Raspberry Pi BMP085: точные показания температуры и давления по I2C
Бош BMP085 — компактный, дешёвый I2C-датчик, выдающий точные измерения барометрического давления и температуры. Куплен на eBay за пару долларов, он идеален для метеостанций, высотомеров или любого проекта, требующего надёжных экологических данных.
Хотя руководство Adafruit по BMP085 и их библиотека дают готовое решение, погружение в код даёт глубокое понимание формул компенсации, превращающих сырые данные датчика в человекочитаемые значения. Ниже я объединяю референс Adafruit с собственной Python-реализацией, демонстрируя, как именно работает датчик.
- Учебник Маартена Дамена по Bus Pirate (архив) — отличная диагностика I2C.
- Python-порт C-кода Джона Бернса — GitHub репозиторий.
Подключение BMP085 к Raspberry Pi простое: VCC к 3,3 В, GND к земле, SDA к GPIO2, SCL к GPIO3. I2C-адрес по умолчанию — 0x77.
# I2C-адрес BMP085
BMP085_ADDR = 0x77
Python-реализация
import smbus
import time
class BMP085:
# Настройка передискретизации (0–3). 3 даёт максимальную точность.
OSS = 3
def __init__(self, i2c, address=BMP085_ADDR):
self.i2c = i2c
self.address = address
# Калибровочные коэффициенты — читаются из EEPROM один раз
self.ac1 = self._read_signed(0xAA)
self.ac2 = self._read_signed(0xAC)
self.ac3 = self._read_signed(0xAE)
self.ac4 = self._read_unsigned(0xB0)
self.ac5 = self._read_unsigned(0xB2)
self.ac6 = self._read_unsigned(0xB4)
self.b1 = self._read_signed(0xB6)
self.b2 = self._read_signed(0xB8)
self.mb = self._read_signed(0xBA)
self.mc = self._read_signed(0xBC)
self.md = self._read_signed(0xBE)
def _read_unsigned(self, reg):
msb = self.i2c.read_byte_data(self.address, reg)
lsb = self.i2c.read_byte_data(self.address, reg + 1)
return (msb << 8) + lsb
def _read_signed(self, reg):
val = self._read_unsigned(reg)
return val - 65536 if val > 32767 else val
def _read_ut(self):
# Запуск измерения температуры
self.i2c.write_byte_data(self.address, 0xF4, 0x2E)
time.sleep(0.0045)
return self._read_unsigned(0xF6)
def read_temperature(self):
ut = self._read_ut()
x1 = ((ut - self.ac6) * self.ac5) >> 15
x2 = (self.mc << 11) // (x1 + self.md)
self.b5 = x1 + x2
temp = (self.b5 + 8) >> 4 # в 0,1 °C
return temp / 10.0
def _read_up(self):
# Запуск измерения давления с выбранным OSS
cmd = 0x34 + (self.OSS << 6)
self.i2c.write_byte_data(self.address, 0xF4, cmd)
delay = (2 + (3 << self.OSS)) / 1000.0
time.sleep(delay)
msb = self.i2c.read_byte_data(self.address, 0xF6)
lsb = self.i2c.read_byte_data(self.address, 0xF7)
xlsb = self.i2c.read_byte_data(self.address, 0xF8)
up = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.OSS)
return up
def read_pressure(self):
up = self._read_up()
b6 = self.b5 - 4000
x1 = (self.b2 * (b6 * b6) >> 12) >> 11
x2 = (self.ac2 * b6) >> 11
x3 = x1 + x2
b3 = (((self.ac1 * 4 + x3) << self.OSS) + 2) >> 2
x1 = (self.ac3 * b6) >> 13
x2 = (self.b1 * (b6 * b6) >> 12) >> 16
x3 = ((x1 + x2) + 2) >> 2
b4 = (self.ac4 * (x3 + 32768)) >> 15
b7 = (up - b3) * (50000 >> self.OSS)
if b7 < 0x80000000:
p = (b7 * 2) // b4
else:
p = (b7 // b4) << 1
p = ((p + 1) * 1) >> 1
x1 = (p >> 8) * (p >> 8)
x1 = (x1 * 3038) >> 16
x2 = (-7357 * p) >> 16
p = p + ((x1 + x2 + 3791) >> 4)
return p # в Па
# Пример использования
bus = smbus.SMBus(1) # I2C-шина Raspberry Pi
bmp = BMP085(bus)
print(f"Temperature: {bmp.read_temperature():.2f} °C")
print(f"Pressure: {bmp.read_pressure() / 100:.2f} hPa")
Скрипт выполняет полную калибровочную процедуру, описанную в даташите Bosch BMP085. Запуск программы печатает температуру в Цельсиях и давление в гектопаскалях, готовые для использования в любом Python-приложении.
Зачем писать свой код?
Использование библиотеки Adafruit экономит время, но понимание математики датчика даёт возможность настраивать частоту дискретизации, работать с потоком сырых данных или портировать код на другие микроконтроллеры. Будь вы хоббистом или инженером, освоение внутренностей BMP085 добавит ценный навык в ваш инструментарий.
Производственный процесс
- Сборка логгера температуры на Raspberry Pi с $5 I2C датчиком
- Точный температурный профиль Raspberry Pi с Python, SQLite и LabVIEW
- Подключение нескольких DS18B20 1-Wire датчиков к Raspberry Pi для точного мониторинга температуры
- Raspberry Pi сетевой монитор температуры и влажности — руководство по DIY сборке
- Как считывать температуру с DS18B20 на Raspberry Pi 2
- Профессиональный мониторинг температуры на Raspberry Pi с датчиком DS18B20
- Измерение температуры на Raspberry Pi с датчиками Maxim 1-Wire и мостом DS2482 I2C
- ИК-датчик температуры TMP006 с Raspberry Pi: библиотека Python и руководство по настройке
- Создание удалённого датчика температуры на Raspberry Pi и Python — пошаговое руководство
- Бесшовный мониторинг температуры и влажности на Raspberry Pi с EzTemp