通过上一章,相信各位对树莓派I2C编程有一定的了解了,今天我们继续使用I2C来控制BMP180压强传感器。BMP180压强传感器操作原理比较简单,开机先通过I2C读取出AC1,AC2,AC3,AC4,AC5,AC6,B1,B2,MB,MC,MD等寄存器的值,这些寄存器的值作为校准时使用。如何读取温度寄存器,压强寄存器的值,根据下图公式算出测得的当前温度和压强。

本章主要讲解python程序,使大家熟悉python编程。关于bcm2835,wiringpi程序具体可参看Pioneer600示例程序。
驱动文件bmp180.py
| 004 | # BMP085 defaultaddress. | 
| 008 | BMP180_ULTRALOWPOWER     = 0 | 
| 011 | BMP180_ULTRAHIGHRES      = 3 | 
| 014 | BMP180_CAL_AC1           = 0xAA  # R   Calibration data (16 bits) | 
| 015 | BMP180_CAL_AC2           = 0xAC  # R   Calibration data (16 bits) | 
| 016 | BMP180_CAL_AC3           = 0xAE  # R   Calibration data (16 bits) | 
| 017 | BMP180_CAL_AC4           = 0xB0  # R   Calibration data (16 bits) | 
| 018 | BMP180_CAL_AC5           = 0xB2  # R   Calibration data (16 bits) | 
| 019 | BMP180_CAL_AC6           = 0xB4  # R   Calibration data (16 bits) | 
| 020 | BMP180_CAL_B1            = 0xB6  # R   Calibration data (16 bits) | 
| 021 | BMP180_CAL_B2            = 0xB8  # R   Calibration data (16 bits) | 
| 022 | BMP180_CAL_MB            = 0xBA  # R   Calibration data (16 bits) | 
| 023 | BMP180_CAL_MC            = 0xBC  # R   Calibration data (16 bits) | 
| 024 | BMP180_CAL_MD            = 0xBE  # R   Calibration data (16 bits) | 
| 026 | BMP180_TEMPDATA          = 0xF6 | 
| 027 | BMP180_PRESSUREDATA      = 0xF6 | 
| 030 | BMP180_READTEMPCMD       = 0x2E | 
| 031 | BMP180_READPRESSURECMD   = 0x34 | 
| 035 |     def __init__(self, address=BMP180_I2CADDR, mode=BMP180_STANDARD): | 
| 037 |         self._address = address | 
| 038 |         self._bus = smbus.SMBus(1) | 
| 039 |         # Load calibration values. | 
| 040 |         self._load_calibration() | 
| 041 |     def _read_byte(self,cmd): | 
| 042 |         returnself._bus.read_byte_data(self._address,cmd) | 
| 044 |     def _read_u16(self,cmd): | 
| 045 |         MSB = self._bus.read_byte_data(self._address,cmd) | 
| 046 |         LSB = self._bus.read_byte_data(self._address,cmd+1) | 
| 047 |         return(MSB << 8) + LSB | 
| 049 |     def _read_s16(self,cmd): | 
| 050 |         result = self._read_u16(cmd) | 
| 051 |         ifresult > 32767:result -= 65536 | 
| 054 |     def _write_byte(self,cmd,val): | 
| 055 |         self._bus.write_byte_data(self._address,cmd,val) | 
| 057 |     def _load_calibration(self): | 
| 059 |         self.cal_AC1 = self._read_s16(BMP180_CAL_AC1)   # INT16 | 
| 060 |         self.cal_AC2 = self._read_s16(BMP180_CAL_AC2)   # INT16 | 
| 061 |         self.cal_AC3 = self._read_s16(BMP180_CAL_AC3)   # INT16 | 
| 062 |         self.cal_AC4 = self._read_u16(BMP180_CAL_AC4)   # UINT16 | 
| 063 |         self.cal_AC5 = self._read_u16(BMP180_CAL_AC5)   # UINT16 | 
| 064 |         self.cal_AC6 = self._read_u16(BMP180_CAL_AC6)   # UINT16 | 
| 065 |         self.cal_B1  = self._read_s16(BMP180_CAL_B1)     # INT16 | 
| 066 |         self.cal_B2  = self._read_s16(BMP180_CAL_B2)     # INT16 | 
| 067 |         self.cal_MB  = self._read_s16(BMP180_CAL_MB)     # INT16 | 
| 068 |         self.cal_MC  = self._read_s16(BMP180_CAL_MC)     # INT16 | 
| 069 |         self.cal_MD  = self._read_s16(BMP180_CAL_MD)     # INT16 | 
| 071 |     def read_raw_temp(self): | 
| 072 |         """Reads the raw (uncompensated) temperature from the sensor.""" | 
| 073 |         self._write_byte(BMP180_CONTROL, BMP180_READTEMPCMD) | 
| 074 |         time.sleep(0.005)  # Wait 5ms | 
| 075 |         MSB = self._read_byte(BMP180_TEMPDATA) | 
| 076 |         LSB = self._read_byte(BMP180_TEMPDATA+1) | 
| 077 |         raw = (MSB << 8) + LSB | 
| 080 |     def read_raw_pressure(self): | 
| 081 |         """Reads the raw (uncompensated) pressure level from the sensor.""" | 
| 082 |         self._write_byte(BMP180_CONTROL, BMP180_READPRESSURECMD + (self._mode << 6)) | 
| 083 |         ifself._mode == BMP180_ULTRALOWPOWER: | 
| 085 |         elif self._mode == BMP180_HIGHRES: | 
| 087 |         elif self._mode == BMP180_ULTRAHIGHRES: | 
| 091 |         MSB = self._read_byte(BMP180_PRESSUREDATA) | 
| 092 |         LSB = self._read_byte(BMP180_PRESSUREDATA+1) | 
| 093 |         XLSB = self._read_byte(BMP180_PRESSUREDATA+2) | 
| 094 |         raw = ((MSB << 16) + (LSB << 8) + XLSB) >> (8 - self._mode) | 
| 097 |     def read_temperature(self): | 
| 098 |         """Gets the compensated temperature in degrees celsius.""" | 
| 099 |         UT = self.read_raw_temp() | 
| 101 |         X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15 | 
| 102 |         X2 = (self.cal_MC << 11) / (X1 + self.cal_MD) | 
| 104 |         temp = ((B5 + 8) >> 4) / 10.0 | 
| 107 |     def read_pressure(self): | 
| 108 |         """Gets the compensated pressure in Pascals.""" | 
| 109 |         UT = self.read_raw_temp() | 
| 110 |         UP = self.read_raw_pressure() | 
| 113 |         X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15 | 
| 114 |         X2 = (self.cal_MC << 11) / (X1 + self.cal_MD) | 
| 117 |         # Pressure Calculations | 
| 119 |         X1 = (self.cal_B2 * (B6 * B6) >> 12) >> 11 | 
| 120 |         X2 = (self.cal_AC2 * B6) >> 11 | 
| 122 |         B3 = (((self.cal_AC1 * 4 + X3) << self._mode) + 2) / 4 | 
| 124 |         X1 = (self.cal_AC3 * B6) >> 13 | 
| 125 |         X2 = (self.cal_B1 * ((B6 * B6) >> 12)) >> 16 | 
| 126 |         X3 = ((X1 + X2) + 2) >> 2 | 
| 127 |         B4 = (self.cal_AC4 * (X3 + 32768)) >> 15 | 
| 128 |         B7 = (UP - B3) * (50000 >> self._mode) | 
| 134 |         X1 = (p >> 8) * (p >> 8) | 
| 135 |         X1 = (X1 * 3038) >> 16 | 
| 136 |         X2 = (-7357 * p) >> 16 | 
| 138 |         p = p + ((X1 + X2 + 3791) >> 4) | 
| 141 |     def read_altitude(self, sealevel_pa=101325.0): | 
| 142 |         """Calculates the altitude in meters.""" | 
| 143 |         # Calculation taken straight from section 3.6 of the datasheet. | 
| 144 |         pressure = float(self.read_pressure()) | 
| 145 |         altitude = 44330.0 * (1.0 - pow(pressure / sealevel_pa, (1.0/5.255))) | 
| 148 |     def read_sealevel_pressure(self, altitude_m=0.0): | 
| 149 |         """Calculates the pressure at sealevel when given a known altitude in | 
| 150 |         meters. Returns a value in Pascals.""" | 
| 151 |         pressure = float(self.read_pressure()) | 
| 152 |         p0 = pressure / pow(1.0 - altitude_m/44330.0, 5.255) | 
主文件bmp180_example.py
| 04 | from BMP180 import BMP180 | 
| 06 | # Initialise the BMP085 anduseSTANDARD mode (defaultvalue) | 
| 07 | # bmp = BMP085(0x77, debug=True) | 
| 10 | # To specify a different operating mode, uncomment one of the following: | 
| 11 | # bmp = BMP085(0x77, 0)  # ULTRALOWPOWER Mode | 
| 12 | # bmp = BMP085(0x77, 1)  # STANDARD Mode | 
| 13 | # bmp = BMP085(0x77, 2)  # HIRES Mode | 
| 14 | # bmp = BMP085(0x77, 3)  # ULTRAHIRES Mode | 
| 16 |     temp = bmp.read_temperature() | 
| 18 | # Read the current barometric pressure level | 
| 19 |     pressure = bmp.read_pressure() | 
| 21 | # To calculate altitude based on an estimated mean sea level pressure | 
| 22 | # (1013.25 hPa) call the functionasfollows, but this won't be very accurate | 
| 23 |     altitude = bmp.read_altitude() | 
| 25 | # To specify a more accurate altitude, enter the correct mean sea level | 
| 26 | # pressure level.  For example, ifthe current pressure level is 1023.50 hPa | 
| 27 | # enter 102350 since we includetwo decimal places in the integer value | 
| 28 | # altitude = bmp.readAltitude(102350) | 
| 30 |     print "Temperature: %.2f C"% temp | 
| 31 |     print "Pressure:    %.2f hPa"% (pressure / 100.0) | 
| 32 |     print "Altitude:     %.2f\n"% altitude |