After a few weeks of waiting, I’ve finally received two breakout boards with BMP085 barometric pressure sensors.
These little chips can run from as low as 1.8V to 3.6V, and measure atmospheric pressure within a 300-1100hPa range, as well as temperature within -40 – 85C range.
They provide a standard I2C interface, so connecting them to Raspberry Pi, Arduino, MSP430 Launchpad etc. is quite easy.
You can get these sensors from Sparkfun, Adafruit (~$20) or (like I did) from Dealextreme (~$8).
I’m planning to use them with MSP430 Launchpad to create a wireless environment monitor (together with an air humidity sensor).
On the photo above, you can also see a RFM23B transceiver (on the right, connected to R-Pi’s SPI port) – I’m in a process of writing a C library for it, compatible with both Linux and MSP430.
Raspberry will become a wireless data acquisition server 😉
Here’s a little quick’n’dirty Python script which reads, processes and displays current temperature and air pressure read from BMP085.
The temperature and pressure calculation code is based on the BMP085 Datasheet
Note, that because it talks with the hardware, it has to be executed as root…
#!/usr/bin/python from smbus import SMBus from time import sleep from ctypes import c_short addr = 0x77 oversampling = 3 # 0..3 bus = SMBus(0); # 0 for R-Pi Rev. 1, 1 for Rev. 2 # return two bytes from data as a signed 16-bit value def get_short(data, index): return c_short((data[index] << 8) + data[index + 1]).value # return two bytes from data as an unsigned 16-bit value def get_ushort(data, index): return (data[index] << 8) + data[index + 1] (chip_id, version) = bus.read_i2c_block_data(addr, 0xD0, 2) print "Chip Id:", chip_id, "Version:", version print print "Reading calibration data..." # Read whole calibration EEPROM data cal = bus.read_i2c_block_data(addr, 0xAA, 22) # Convert byte data to word values ac1 = get_short(cal, 0) ac2 = get_short(cal, 2) ac3 = get_short(cal, 4) ac4 = get_ushort(cal, 6) ac5 = get_ushort(cal, 8) ac6 = get_ushort(cal, 10) b1 = get_short(cal, 12) b2 = get_short(cal, 14) mb = get_short(cal, 16) mc = get_short(cal, 18) md = get_short(cal, 20) print "Starting temperature conversion..." bus.write_byte_data(addr, 0xF4, 0x2E) sleep(0.005) (msb, lsb) = bus.read_i2c_block_data(addr, 0xF6, 2) ut = (msb << 8) + lsb print "Starting pressure conversion..." bus.write_byte_data(addr, 0xF4, 0x34 + (oversampling << 6)) sleep(0.04) (msb, lsb, xsb) = bus.read_i2c_block_data(addr, 0xF6, 3) up = ((msb << 16) + (lsb << 8) + xsb) >> (8 - oversampling) print "Calculating temperature..." x1 = ((ut - ac6) * ac5) >> 15 x2 = (mc << 11) / (x1 + md) b5 = x1 + x2 t = (b5 + 8) >> 4 print "Calculating pressure..." b6 = b5 - 4000 b62 = b6 * b6 >> 12 x1 = (b2 * b62) >> 11 x2 = ac2 * b6 >> 11 x3 = x1 + x2 b3 = (((ac1 * 4 + x3) << oversampling) + 2) >> 2 x1 = ac3 * b6 >> 13 x2 = (b1 * b62) >> 16 x3 = ((x1 + x2) + 2) >> 2 b4 = (ac4 * (x3 + 32768)) >> 15 b7 = (up - b3) * (50000 >> oversampling) p = (b7 * 2) / b4 #p = (b7 / b4) * 2 x1 = (p >> 8) * (p >> 8) x1 = (x1 * 3038) >> 16 x2 = (-7357 * p) >> 16 p = p + ((x1 + x2 + 3791) >> 4) print print "Temperature:", t/10.0, "C" print "Pressure:", p / 100.0, "hPa"
Script’s sample output:
root@raspi:~/bmp085# ./bmp_test.py Chip Id: 85 Version: 2 Reading calibration data... Starting temperature conversion... Starting pressure conversion... Calculating temperature... Calculating pressure... Temperature: 23.4 C Pressure: 979.64 hPa
Hi, thanks for great piece of python code! I use it to read barometric pressure from the sensor connected to my RasPi.
But sometimes it returns bad value. I execute this code every 15 minutes and this is what I get:
2013-07-24 05:15:02 0962.3
2013-07-24 05:30:02 0962.1
2013-07-24 05:45:02 1050.5
2013-07-24 06:00:02 0962.2
2013-07-24 06:15:02 0962.2
I tried to change power from 3.3V to 5V and back with no change.
One more hint – when I used Adafruits code, the error occurred much more often, but values were lower – for example 560 or 760.
I would appreciate any help. Thanks, best regards, PetrN