forked from fossasia/pslab-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBMP180.py
More file actions
118 lines (98 loc) · 3.79 KB
/
BMP180.py
File metadata and controls
118 lines (98 loc) · 3.79 KB
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
from __future__ import print_function
import time
from numpy import int16
def connect(route, **args):
return BMP180(route, **args)
class BMP180:
ADDRESS = 0x77
REG_CONTROL = 0xF4
REG_RESULT = 0xF6
CMD_TEMP = 0x2E
CMD_P0 = 0x34
CMD_P1 = 0x74
CMD_P2 = 0xB4
CMD_P3 = 0xF4
oversampling = 0
NUMPLOTS = 3
PLOTNAMES = ['Temperature', 'Pressure', 'Altitude']
name = 'Altimeter BMP180'
def __init__(self, I2C, **args):
self.ADDRESS = args.get('address', self.ADDRESS)
self.I2C = I2C
self.MB = self.__readInt__(0xBA)
self.c3 = 160.0 * pow(2, -15) * self.__readInt__(0xAE)
self.c4 = pow(10, -3) * pow(2, -15) * self.__readUInt__(0xB0)
self.b1 = pow(160, 2) * pow(2, -30) * self.__readInt__(0xB6)
self.c5 = (pow(2, -15) / 160) * self.__readUInt__(0xB2)
self.c6 = self.__readUInt__(0xB4)
self.mc = (pow(2, 11) / pow(160, 2)) * self.__readInt__(0xBC)
self.md = self.__readInt__(0xBE) / 160.0
self.x0 = self.__readInt__(0xAA)
self.x1 = 160.0 * pow(2, -13) * self.__readInt__(0xAC)
self.x2 = pow(160, 2) * pow(2, -25) * self.__readInt__(0xB8)
self.y0 = self.c4 * pow(2, 15)
self.y1 = self.c4 * self.c3
self.y2 = self.c4 * self.b1
self.p0 = (3791.0 - 8.0) / 1600.0
self.p1 = 1.0 - 7357.0 * pow(2, -20)
self.p2 = 3038.0 * 100.0 * pow(2, -36)
self.T = 25
print('calib:', self.c3, self.c4, self.b1, self.c5, self.c6, self.mc, self.md, self.x0, self.x1, self.x2,
self.y0, self.y1, self.p0, self.p1, self.p2)
self.params = {'setOversampling': [0, 1, 2, 3]}
self.name = 'BMP180 Altimeter'
self.initTemperature()
self.readTemperature()
self.initPressure()
self.baseline = self.readPressure()
def __readInt__(self, addr):
return int16(self.__readUInt__(addr))
def __readUInt__(self, addr):
vals = self.I2C.readBulk(self.ADDRESS, addr, 2)
v = 1. * ((vals[0] << 8) | vals[1])
return v
def initTemperature(self):
self.I2C.writeBulk(self.ADDRESS, [self.REG_CONTROL, self.CMD_TEMP])
time.sleep(0.005)
def readTemperature(self):
vals = self.I2C.readBulk(self.ADDRESS, self.REG_RESULT, 2)
if len(vals) == 2:
T = (vals[0] << 8) + vals[1]
a = self.c5 * (T - self.c6)
self.T = a + (self.mc / (a + self.md))
return self.T
else:
return False
def setOversampling(self, num):
self.oversampling = num
def initPressure(self):
os = [0x34, 0x74, 0xb4, 0xf4]
delays = [0.005, 0.008, 0.014, 0.026]
self.I2C.writeBulk(self.ADDRESS, [self.REG_CONTROL, os[self.oversampling]])
time.sleep(delays[self.oversampling])
def readPressure(self):
vals = self.I2C.readBulk(self.ADDRESS, self.REG_RESULT, 3)
if len(vals) == 3:
P = 1. * (vals[0] << 8) + vals[1] + (vals[2] / 256.0)
s = self.T - 25.0
x = (self.x2 * pow(s, 2)) + (self.x1 * s) + self.x0
y = (self.y2 * pow(s, 2)) + (self.y1 * s) + self.y0
z = (P - x) / y
self.P = (self.p2 * pow(z, 2)) + (self.p1 * z) + self.p0
return self.P
else:
return False
def altitude(self):
# baseline pressure needs to be provided
return (44330.0 * (1 - pow(self.P / self.baseline, 1 / 5.255)))
def sealevel(self, P, A):
'''
given a calculated pressure and altitude, return the sealevel
'''
return (P / pow(1 - (A / 44330.0), 5.255))
def getRaw(self):
self.initTemperature()
self.readTemperature()
self.initPressure()
self.readPressure()
return [self.T, self.P, self.altitude()]