Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

Raspberry Pi BMP085: Accurate Temperature & Pressure Readings via I2C

The Bosch BMP085 is a compact, low‑cost I2C sensor that delivers precise barometric pressure and temperature measurements. Acquired from eBay for a few dollars, it’s an ideal component for weather stations, altitude loggers, or any project that needs reliable environmental data.

While Adafruit’s BMP085 guide and library provide a turnkey solution, diving into the code gives deeper insight into the compensation formulas that transform raw sensor data into human‑readable values. Below, I combine the Adafruit reference with my own Python implementation to demonstrate exactly how the sensor works.

Wiring the BMP085 to a Raspberry Pi is straightforward: connect VCC to 3.3 V, GND to ground, SDA to GPIO2, and SCL to GPIO3. The I2C address is 0x77 by default.

# BMP085 I2C address
BMP085_ADDR = 0x77

Python Implementation

import smbus
import time

class BMP085:
    # Oversampling setting (0–3).  3 gives the best accuracy.
    OSS = 3

    def __init__(self, i2c, address=BMP085_ADDR):
        self.i2c = i2c
        self.address = address
        # Calibration coefficients – read from EEPROM once.
        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):
        # Trigger temperature measurement
        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  # in 0.1°C
        return temp / 10.0

    def _read_up(self):
        # Trigger pressure measurement with selected 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  # in Pa

# Example usage
bus = smbus.SMBus(1)  # Raspberry Pi I2C bus
bmp = BMP085(bus)
print(f"Temperature: {bmp.read_temperature():.2f} °C")
print(f"Pressure:    {bmp.read_pressure() / 100:.2f} hPa")

The script performs the full calibration routine as described in Bosch’s BMP085 datasheet. Running the program prints temperature in Celsius and pressure in hectopascals, ready for use in any Python application.

Why Build Your Own?

Using the Adafruit library saves time, but understanding the math behind the sensor empowers you to tweak sampling rates, handle raw data streams, or port the code to other microcontrollers. Whether you’re a hobbyist or a seasoned engineer, mastering the BMP085’s internals adds a valuable skill to your toolkit.

Manufacturing process

  1. Build a Raspberry Pi Temperature Logger with a $5 I2C Sensor
  2. Accurate Raspberry Pi Temperature Profiling with Python, SQLite, and LabVIEW
  3. Raspberry Pi Temperature & Humidity Network Monitor – DIY Setup Guide
  4. How to Read Temperature with a DS18B20 on Raspberry Pi 2
  5. Professional Raspberry Pi Temperature Monitoring with DS18B20
  6. Measuring Temperature on Raspberry Pi with Maxim 1‑Wire Sensors and DS2482 I2C Bridge
  7. Build a Remote Temperature Sensor with Raspberry Pi and Python – Step‑by‑Step Guide
  8. Accurate Temperature Monitoring in a Server Closet with Raspberry Pi
  9. Build a Multi‑Sensor Temperature & Light Monitoring System with Raspberry Pi & DS18B20
  10. Build a Raspberry Pi Home Temperature Monitor with MCP9808, InfluxDB & Grafana