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