Skip to content
This repository was archived by the owner on Dec 20, 2018. It is now read-only.

Commit 64872bd

Browse files
committed
Initial commit.
1 parent 6445001 commit 64872bd

File tree

6 files changed

+580
-0
lines changed

6 files changed

+580
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build/
2+
dist/
3+
*.egg-info
4+
*.pyc

Adafruit_BMP/BMP085.py

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# Copyright (c) 2014 Adafruit Industries
2+
# Author: Tony DiCola
3+
#
4+
# Permission is hereby granted, free of charge, to any person obtaining a copy
5+
# of this software and associated documentation files (the "Software"), to deal
6+
# in the Software without restriction, including without limitation the rights
7+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
# copies of the Software, and to permit persons to whom the Software is
9+
# furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in
12+
# all copies or substantial portions of the Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
# THE SOFTWARE.
21+
import logging
22+
import time
23+
24+
import Adafruit_GPIO.I2C as I2C
25+
26+
27+
# BMP085 default address.
28+
BMP085_I2CADDR = 0x77
29+
30+
# Operating Modes
31+
BMP085_ULTRALOWPOWER = 0
32+
BMP085_STANDARD = 1
33+
BMP085_HIGHRES = 2
34+
BMP085_ULTRAHIGHRES = 3
35+
36+
# BMP085 Registers
37+
BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits)
38+
BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits)
39+
BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits)
40+
BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits)
41+
BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits)
42+
BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits)
43+
BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits)
44+
BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits)
45+
BMP085_CAL_MB = 0xBA # R Calibration data (16 bits)
46+
BMP085_CAL_MC = 0xBC # R Calibration data (16 bits)
47+
BMP085_CAL_MD = 0xBE # R Calibration data (16 bits)
48+
BMP085_CONTROL = 0xF4
49+
BMP085_TEMPDATA = 0xF6
50+
BMP085_PRESSUREDATA = 0xF6
51+
52+
# Commands
53+
BMP085_READTEMPCMD = 0x2E
54+
BMP085_READPRESSURECMD = 0x34
55+
56+
57+
class BMP085(object):
58+
def __init__(self, mode=BMP085_STANDARD, address=BMP085_I2CADDR,
59+
busnum=I2C.get_default_bus()):
60+
self._logger = logging.getLogger('Adafruit_BMP.BMP085')
61+
# Check that mode is valid.
62+
if mode not in [BMP085_ULTRALOWPOWER, BMP085_STANDARD, BMP085_HIGHRES, BMP085_ULTRAHIGHRES]:
63+
raise ValueError('Unexpected mode value {0}. Set mode to one of BMP085_ULTRALOWPOWER, BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES'.format(mode))
64+
self._mode = mode
65+
# Create I2C device.
66+
self._device = I2C.Device(address, busnum)
67+
# Load calibration values.
68+
self._load_calibration()
69+
70+
def _load_calibration(self):
71+
self.cal_AC1 = self._device.readS16BE(BMP085_CAL_AC1) # INT16
72+
self.cal_AC2 = self._device.readS16BE(BMP085_CAL_AC2) # INT16
73+
self.cal_AC3 = self._device.readS16BE(BMP085_CAL_AC3) # INT16
74+
self.cal_AC4 = self._device.readU16BE(BMP085_CAL_AC4) # UINT16
75+
self.cal_AC5 = self._device.readU16BE(BMP085_CAL_AC5) # UINT16
76+
self.cal_AC6 = self._device.readU16BE(BMP085_CAL_AC6) # UINT16
77+
self.cal_B1 = self._device.readS16BE(BMP085_CAL_B1) # INT16
78+
self.cal_B2 = self._device.readS16BE(BMP085_CAL_B2) # INT16
79+
self.cal_MB = self._device.readS16BE(BMP085_CAL_MB) # INT16
80+
self.cal_MC = self._device.readS16BE(BMP085_CAL_MC) # INT16
81+
self.cal_MD = self._device.readS16BE(BMP085_CAL_MD) # INT16
82+
self._logger.debug('AC1 = {0:6d}'.format(self.cal_AC1))
83+
self._logger.debug('AC2 = {0:6d}'.format(self.cal_AC2))
84+
self._logger.debug('AC3 = {0:6d}'.format(self.cal_AC3))
85+
self._logger.debug('AC4 = {0:6d}'.format(self.cal_AC4))
86+
self._logger.debug('AC5 = {0:6d}'.format(self.cal_AC5))
87+
self._logger.debug('AC6 = {0:6d}'.format(self.cal_AC6))
88+
self._logger.debug('B1 = {0:6d}'.format(self.cal_B1))
89+
self._logger.debug('B2 = {0:6d}'.format(self.cal_B2))
90+
self._logger.debug('MB = {0:6d}'.format(self.cal_MB))
91+
self._logger.debug('MC = {0:6d}'.format(self.cal_MC))
92+
self._logger.debug('MD = {0:6d}'.format(self.cal_MD))
93+
94+
def _load_datasheet_calibration(self):
95+
# Set calibration from values in the datasheet example. Useful for debugging the
96+
# temp and pressure calculation accuracy.
97+
self.cal_AC1 = 408
98+
self.cal_AC2 = -72
99+
self.cal_AC3 = -14383
100+
self.cal_AC4 = 32741
101+
self.cal_AC5 = 32757
102+
self.cal_AC6 = 23153
103+
self.cal_B1 = 6190
104+
self.cal_B2 = 4
105+
self.cal_MB = -32767
106+
self.cal_MC = -8711
107+
self.cal_MD = 2868
108+
109+
def read_raw_temp(self):
110+
"""Reads the raw (uncompensated) temperature from the sensor."""
111+
self._device.write8(BMP085_CONTROL, BMP085_READTEMPCMD)
112+
time.sleep(0.005) # Wait 5ms
113+
raw = self._device.readU16BE(BMP085_TEMPDATA)
114+
self._logger.debug('Raw temp 0x{0:X} ({1})'.format(raw & 0xFFFF, raw))
115+
return raw
116+
117+
def read_raw_pressure(self):
118+
"""Reads the raw (uncompensated) pressure level from the sensor."""
119+
self._device.write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (self._mode << 6))
120+
if self._mode == BMP085_ULTRALOWPOWER:
121+
time.sleep(0.005)
122+
elif self._mode == BMP085_HIGHRES:
123+
time.sleep(0.014)
124+
elif self._mode == BMP085_ULTRAHIGHRES:
125+
time.sleep(0.026)
126+
else:
127+
time.sleep(0.008)
128+
msb = self._device.readU8(BMP085_PRESSUREDATA)
129+
lsb = self._device.readU8(BMP085_PRESSUREDATA+1)
130+
xlsb = self._device.readU8(BMP085_PRESSUREDATA+2)
131+
raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self._mode)
132+
self._logger.debug('Raw pressure 0x{0:04X} ({1})'.format(raw & 0xFFFF, raw))
133+
return raw
134+
135+
def read_temperature(self):
136+
"""Gets the compensated temperature in degrees celsius."""
137+
UT = self.read_raw_temp()
138+
# Datasheet value for debugging:
139+
#UT = 27898
140+
# Calculations below are taken straight from section 3.5 of the datasheet.
141+
X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15
142+
X2 = (self.cal_MC << 11) / (X1 + self.cal_MD)
143+
B5 = X1 + X2
144+
temp = ((B5 + 8) >> 4) / 10.0
145+
self._logger.debug('Calibrated temperature {0} C'.format(temp))
146+
return temp
147+
148+
def read_pressure(self):
149+
"""Gets the compensated pressure in Pascals."""
150+
UT = self.read_raw_temp()
151+
UP = self.read_raw_pressure()
152+
# Datasheet values for debugging:
153+
#UT = 27898
154+
#UP = 23843
155+
# Calculations below are taken straight from section 3.5 of the datasheet.
156+
# Calculate true temperature coefficient B5.
157+
X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15
158+
X2 = (self.cal_MC << 11) / (X1 + self.cal_MD)
159+
B5 = X1 + X2
160+
self._logger.debug('B5 = {0}'.format(B5))
161+
# Pressure Calculations
162+
B6 = B5 - 4000
163+
self._logger.debug('B6 = {0}'.format(B6))
164+
X1 = (self.cal_B2 * (B6 * B6) >> 12) >> 11
165+
X2 = (self.cal_AC2 * B6) >> 11
166+
X3 = X1 + X2
167+
B3 = (((self.cal_AC1 * 4 + X3) << self._mode) + 2) / 4
168+
self._logger.debug('B3 = {0}'.format(B3))
169+
X1 = (self.cal_AC3 * B6) >> 13
170+
X2 = (self.cal_B1 * ((B6 * B6) >> 12)) >> 16
171+
X3 = ((X1 + X2) + 2) >> 2
172+
B4 = (self.cal_AC4 * (X3 + 32768)) >> 15
173+
self._logger.debug('B4 = {0}'.format(B4))
174+
B7 = (UP - B3) * (50000 >> self._mode)
175+
self._logger.debug('B7 = {0}'.format(B7))
176+
if B7 < 0x80000000:
177+
p = (B7 * 2) / B4
178+
else:
179+
p = (B7 / B4) * 2
180+
X1 = (p >> 8) * (p >> 8)
181+
X1 = (X1 * 3038) >> 16
182+
X2 = (-7357 * p) >> 16
183+
p = p + ((X1 + X2 + 3791) >> 4)
184+
self._logger.debug('Pressure {0} Pa'.format(p))
185+
return p
186+
187+
def read_altitude(self, sealevel_pa=101325.0):
188+
"""Calculates the altitude in meters."""
189+
# Calculation taken straight from section 3.6 of the datasheet.
190+
pressure = float(self.read_pressure())
191+
altitude = 44330.0 * (1.0 - pow(pressure / sealevel_pa, (1.0/5.255)))
192+
self._logger.debug('Altitude {0} m'.format(altitude))
193+
return altitude
194+
195+
def read_sealevel_pressure(self, altitude_m=0.0):
196+
"""Calculates the pressure at sealevel when given a known altitude in
197+
meters. Returns a value in Pascals."""
198+
pressure = float(self.read_pressure())
199+
p0 = pressure / pow(1.0 - altitude_m/44330.0, 5.255)
200+
self._logger.debug('Sealevel pressure {0} Pa'.format(p0))
201+
return p0

Adafruit_BMP/__init__.py

Whitespace-only changes.

examples/simpletest.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Can enable debug output by uncommenting:
2+
#import logging
3+
#logging.basicConfig(level=logging.DEBUG)
4+
5+
import Adafruit_BMP.BMP085 as BMP085
6+
7+
# Default constructor will pick a default I2C bus.
8+
#
9+
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
10+
# from the main GPIO header and the library will figure out the bus number based
11+
# on the Pi's revision.
12+
#
13+
# For the Beaglebone Black the library will assume bus 1 by default, which is
14+
# exposed with SCL = P9_19 and SDA = P9_20.
15+
sensor = BMP085.BMP085()
16+
17+
# Optionally you can override the bus number:
18+
#sensor = BMP085.BMP085(busnum=2)
19+
20+
# You can also optionally change the BMP085 mode to one of BMP085_ULTRALOWPOWER,
21+
# BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES. See the BMP085
22+
# datasheet for more details on the meanings of each mode (accuracy and power
23+
# consumption are primarily the differences). The default mode is STANDARD.
24+
#sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)
25+
26+
print 'Temp = {0:0.2f} *C'.format(sensor.read_temperature())
27+
print 'Pressure = {0:0.2f} Pa'.format(sensor.read_pressure())
28+
print 'Altitude = {0:0.2f} m'.format(sensor.read_altitude())
29+
print 'Sealevel Pressure = {0:0.2f} Pa'.format(sensor.read_sealevel_pressure())

0 commit comments

Comments
 (0)