Raspberry Pi reading BMP085 Temperature & Pressure

Figure 1 – BMP085

Another fun little i2c device acquired cheaply via eBay.  It reads barometric pressure and temperature.  There’s some relatively simple maths to convert the outputs to something readable.

Once again, ADAFruit provide a fantastic guide and library for using the device in their Using the BMP085 with Raspberry Pi.  As in previous posts, I could have just used the ADAFruit library out of the box.  Whilst I do not feel the need to re-invent the wheel and re-code from scratch, I do like to have an understanding how it works.

Figure 2 – Readings

I drew the information from a couple of other sources:

Below is the very simple schematic for connecting the device to the Pi.

Figure 3 – Schematic

Below is the code to read and display pressure and temperature once.  This can now be found in my BMP085 library release.

import smbus
import time

class BMP085():
    OSS = 3

    def __init__(self, i2c, address):
        self.i2c = i2c
        self.address = address
        self.ac1 = self.readSignedWord(0xaa)
        self.ac2 = self.readSignedWord(0xac)
        self.ac3 = self.readSignedWord(0xae)
        self.ac4 = self.readWord(0xb0)
        self.ac5 = self.readWord(0xb2)
        self.ac6 = self.readWord(0xb4)
        self.b1 = self.readSignedWord(0xb6)
        self.b2 = self.readSignedWord(0xb8)
        self.mb = self.readSignedWord(0xba)
        self.mc = self.readSignedWord(0xbc)
        self.md = self.readSignedWord(0xbe)

    def readWord(self, reg):
        msb = self.i2c.read_byte_data(self.address, reg)
        lsb = self.i2c.read_byte_data(self.address, reg+1)
        value = (msb << 8 ) + lsb         return value     def readSignedWord(self, reg):         msb = self.i2c.read_byte_data(self.address, reg)         lsb = self.i2c.read_byte_data(self.address, reg+1)         if (msb > 127):
          msb = msb - 256
        value = (msb << 8 ) + lsb         return value     def readUT(self):         self.i2c.write_byte_data(self.address, 0xf4, 0x2e)         time.sleep(0.0045)         ut = self.readWord(0xf6)         return ut     def readTemperature(self):         ut = self.readUT()         x1 = ((ut - self.ac6) * self.ac5) >> 15
        x2 = (self.mc << 11) / (x1 + self.md)         self.b5 = x1 + x2         return ((self.b5 + 8 ) >> 4) / 10.0

    def readUP(self):
        self.i2c.write_byte_data(self.address, 0xf4, 0x34 + (self.OSS << 6))
        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         up = up >> (8 - self.OSS)
        return up

    def readPressure(self):
        up = self.readUP()

        b6 = self.b5 - 4000

        x1 = (self.b2 * (b6 * b6)>>12)>>11
        x2 = (self.ac2 * b6)>>11
        x3 = x1 + x2
        b3 = (((self.ac1 * 4 + x3)<>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<<1)/b4
        else:
            p = (b7/b4)<>8) * (p>>8)
        x1 = (x1 * 3038)>>16
        x2 = (-7357 * p)>>16
        p += (x1 + x2 + 3791)>>4

        return p

i2c = smbus.SMBus(0)
bmp085 = BMP085(i2c, 0x77)
t = bmp085.readTemperature()
p = bmp085.readPressure()

print "Temperature: %.2f C" % t
print "Pressure:    %.2f hPa" % (p / 100)

4 thoughts on “Raspberry Pi reading BMP085 Temperature & Pressure

  1. hello,
    thanks for sharing your code.
    I couldn’t get it to work though as its indentation is all broken (I copied and pasted it from your page). Have you got the source file somewhere or could you put it as plain-text on the page?
    thanks!

    • When I first started producing this blog, I struggled with getting the raw code to look good on the pages. The plugin chosen was the best I could find at formatting it well on the page. Interesting to hear it doesn’t cut & paste well.

      I’ll take your suggesting and provide links to the raw files in future posts and will update the previous ones when I have time.

      This particular file is already provided in the released python module in the downloads section. I’ll add a link to the page.

      Thanks for the suggestion & feedback.

  2. Hi Jamie,

    in the begining of your blog you mentioned that you could just have taken the ADAFruit library…. I’m afraid you better don’t…..
    There are some known issues with the way they handle I2C, and with the calculation of pressure and altitude. As such, the output of the library is incorrect.
    John Burn’s C Code seems to be more correct however (http://www.john.geek.nz/2012/08/reading-data-from-a-bosch-bmp085-with-a-raspberry-pi/).

  3. Interesting and thanks for the news. As you can read above, I chose not to just use ADAFruit’s library as I wanted to have a better understand of how it works and chose instead to refer to John Burn’s code.

Leave a Reply

Your email address will not be published. Required fields are marked *