#!/usr/bin/env python import smbus import time import math class bmp180class: 'Class for working with BMP180 pressure sensor' def __init__(self): self.bus = smbus.SMBus(1) self.BMP180_ADDRESS = 0x77 # sensor address use detect # calibration variables self.ac1 = 0 self.ac2 = 0 self.ac3 = 0 self.ac4 = 0 self.ac5 = 0 self.ac6 = 0 self.b1 = 0 self.b2 = 0 self.mb = 0 self.mc = 0 self.md = 0 self.oss = 3 # oversampling setting (0..3) self.altitude = 48 # 31 # location high in meters self.__PressureCompensate = 0 self.__Temperature = 0 def bmp180ReadInt(self, addr,reg): MSB = self.bus.read_byte_data(addr, reg) LSB = self.bus.read_byte_data(addr, reg + 1) return int((MSB << 8) + LSB) def bmp180ReadTriplet(self, addr,reg): MSB = self.bus.read_byte_data(addr, reg) LSB = self.bus.read_byte_data(addr, reg + 1) XLSB = self.bus.read_byte_data(addr, reg + 2) return long((MSB << 16) + (LSB << 8) + XLSB) def int2signed_short(self, intvalue): # input data is two bytes from sensor stored in integer # ouput is signed short from these bytes value between -32767 and 32767 return (intvalue & 32767) - (intvalue & 32768) def bmp180Init(self): # load calibration data self.ac1 = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xAA)) self.ac2 = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xAC)) self.ac3 = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xAE)) self.ac4 = self.bmp180ReadInt(self.BMP180_ADDRESS,0xB0) self.ac5 = self.bmp180ReadInt(self.BMP180_ADDRESS,0xB2) self.ac6 = self.bmp180ReadInt(self.BMP180_ADDRESS,0xB4) self.b1 = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xB6)) self.b2 = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xB8)) self.mb = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xBA)) self.mc = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xBC)) self.md = self.int2signed_short(self.bmp180ReadInt(self.BMP180_ADDRESS,0xBE)) def CalculateSeaLevelPressure(self,local_pressure): # Calculate sea level air pressure # altitude = 31 # location high in meters # float temperature = 283; // K temperature_k = self.__Temperature + 273.15 sea_level_pressure = local_pressure/math.exp((-9.81 * 0.0289644 * self.altitude)/(8.314 * temperature_k)) return sea_level_pressure def get_temperature(self): # perform temperature measurement self.bus.write_byte_data(self.BMP180_ADDRESS, 0xF4, 0x2E) time.sleep(0.05) #wait 4.5 ms # read raw value ut = self.bmp180ReadInt(self.BMP180_ADDRESS,0xF6) # calculate temperature value x1 = ((ut - self.ac6)*self.ac5) >> 15 x2 = (self.mc << 11)/(x1 + self.md) self.__PressureCompensate = x1 + x2 # value used in pressure calculation self.__Temperature = ((self.__PressureCompensate + 8)>>4) /10.0 return self.__Temperature def get_pressure(self): # before first pressure measurement do one temperature measurement count = 0 # perform pressure measurement self.bus.write_byte_data(self.BMP180_ADDRESS, 0xF4, 0x34+(self.oss<<6)) # time.sleep(0.08) #wait minimum 4.5 - 76.5 ms (see BMP180 data sheet) # wait until Sco bit is set to 0 means measuerment completed while (count < 1000) and ((self.bus.read_byte_data(self.BMP180_ADDRESS, 0xF4) & 0x20) > 0): # print 'The count is:', count count = count + 1 # read raw pressure value up = self.bmp180ReadTriplet(self.BMP180_ADDRESS,0xF6)>>(8-self.oss) # Calculation b6 = self.__PressureCompensate - 4000 x1 = (self.b2 * (b6 * b6)>>12)>>11 x2 = (self.ac2 * b6)>>11 x3 = x1 + x2 b3 = ((((self.ac1)*4 + x3)<>2 # Calculate B4 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)<<1 x1 = (p>>8) * (p>>8) x1 = (x1 * 3038)>>16 x2 = (-7357 * p)>>16 p += (x1 + x2 + 3791)>>4 p = p / 100 # hPa return p #-------------------------------------------------------- # class usage test bmp180 = bmp180class() # make class instance # load calibration data bmp180.bmp180Init() # you have to read temperature before geting pressure measurement print("Temperature: {0} C").format(round(bmp180.get_temperature(),1)) # get pressure pressure = bmp180.get_pressure() print("Local air pressure: {0} hPa").format(round(pressure,1)) print("Sea level pressure: {0} hPa").format(round(bmp180.CalculateSeaLevelPressure(pressure), 1))