forked from SInsurance/vehicleAccidentDetectior
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbmp085.py
122 lines (99 loc) · 4.24 KB
/
bmp085.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import i2cutils as I2CUtils
import smbus
import time
class BMP085(object):
'''
Simple BMP085 implementation
Datasheet: http://www.adafruit.com/datasheets/BMP085_DataSheet_Rev.1.0_01July2008.pdf
'''
CALIB_BLOCK_ADDRESS = 0xAA
CALIB_BLOCK_SIZE = 22
def __init__(self, bus, address, name, oss=3):
'''
Constructor
'''
self.bus = bus
self.address = address
self.name = name
self.calibration = I2CUtils.i2c_read_block(bus, address, BMP085.CALIB_BLOCK_ADDRESS, BMP085.CALIB_BLOCK_SIZE)
self.oss = oss
self.temp_wait_period = 0.004
self.pressure_wait_period = 0.0255 # Conversion time
def twos_compliment(self, val):
if (val >= 0x8000):
return -((0xffff - val) + 1)
else:
return val
def get_word(self, array, index, twos):
val = (array[index] << 8) + array[index + 1]
if twos:
return self.twos_compliment(val)
else:
return val
def calculate(self):
# The sensor has a block of factory set calibration values we need to read
# these are then used in a length calculation to get the temperature and pressure
# copy these into convenience variables
ac1 = self.get_word(self.calibration, 0, True)
ac2 = self.get_word(self.calibration, 2, True)
ac3 = self.get_word(self.calibration, 4, True)
ac4 = self.get_word(self.calibration, 6, False)
ac5 = self.get_word(self.calibration, 8, False)
ac6 = self.get_word(self.calibration, 10, False)
b1 = self.get_word(self.calibration, 12, True)
b2 = self.get_word(self.calibration, 14, True)
mb = self.get_word(self.calibration, 16, True)
mc = self.get_word(self.calibration, 18, True)
md = self.get_word(self.calibration, 20, True)
oss = self.oss
# This code is a direct translation from the datasheet
# and should be optimised for real world use
# Read raw temperature
I2CUtils.i2c_write_byte(self.bus, self.address, 0xF4, 0x2E) # Tell the sensor to take a temperature reading
time.sleep(self.temp_wait_period) # Wait for the conversion to take place
temp_raw = I2CUtils.i2c_read_word_signed(self.bus, self.address, 0xF6)
I2CUtils.i2c_write_byte(self.bus, self.address, 0xF4, 0x34 + (self.oss << 6)) # Tell the sensor to take a pressure reading
time.sleep(self.pressure_wait_period) # Wait for the conversion to take place
pressure_raw = ((I2CUtils.i2c_read_byte(self.bus, self.address, 0xF6) << 16) \
+ (I2CUtils.i2c_read_byte(self.bus, self.address, 0xF7) << 8) \
+ (I2CUtils.i2c_read_byte(self.bus, self.address, 0xF8))) >> (8 - self.oss)
# Calculate temperature
x1 = ((temp_raw - ac6) * ac5) / 32768
x2 = (mc * 2048) / (x1 + md)
b5 = x1 + x2
t = (b5 + 8) / 16
# Now calculate the pressure
b6 = b5 - 4000
x1 = (b2 * (b6 * b6 >> 12)) >> 11
x2 = ac2 * b6 >> 11
x3 = x1 + x2
b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2
x1 = (ac3 * b6) >> 13
x2 = (b1 * (b6 * b6 >> 12)) >> 16
x3 = ((x1 + x2) + 2) >> 2
b4 = ac4 * (x3 + 32768) >> 15
b7 = (pressure_raw - b3) * (50000 >> oss)
if (b7 < 0x80000000):
p = (b7 * 2) / b4
else:
p = (b7 / b4) * 2
x1 = (p >> 8) * (p >> 8)
x1 = (x1 * 3038) >> 16
x2 = (-7357 * p) >> 16
p = p + ((x1 + x2 + 3791) >> 4)
return(t / 10., p / 100.)
def read_pressure(self):
(temperature, pressure) = self.calculate()
return pressure
def read_temperature(self):
(temperature, pressure) = self.calculate()
return temperature
def read_temperature_and_pressure(self):
return self.calculate()
if __name__ == "__main__":
#define i2c
bus = smbus.SMBus(I2CUtils.i2c_raspberry_pi_bus_number())
#instaciate bmp sensor
bmp085 = BMP085(bus, 0x77 , "BMP085")
#print tempreture and pressure
print bmp085.read_temperature_and_pressure()