|
@@ -1,141 +1,134 @@
|
1
|
|
-# Distributed with a free-will license.
|
2
|
|
-# Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
|
3
|
|
-# BMP180
|
4
|
|
-# This code is designed to work with the BMP180_I2CS I2C Mini Module available from ControlEverything.com.
|
5
|
|
-# https://www.controleverything.com/content/Pressure?sku=BMP180_I2CS#tabs-0-product_tabset-2
|
6
|
|
-
|
7
|
|
-import smbus
|
8
|
|
-import threading
|
9
|
1
|
import time
|
10
|
2
|
|
11
|
|
-from . import logger
|
|
3
|
+from . import logger, background_task, DEBUG
|
|
4
|
+if not DEBUG:
|
|
5
|
+ import smbus
|
12
|
6
|
|
13
|
7
|
|
14
|
|
-class bmp_180(object):
|
|
8
|
+class bmp_180(background_task):
|
|
9
|
+ RUN_SLEEP_TIME = 0.5
|
|
10
|
+ SMBUS_DELAY = 0.5
|
|
11
|
+ MIN_REFRESH_RATE = RUN_SLEEP_TIME + 3 * SMBUS_DELAY
|
15
|
12
|
KEY_TEMPERATURE = 'temperature'
|
16
|
13
|
KEY_PRESSURE = 'pressure'
|
17
|
14
|
KEY_TIME = 'time'
|
18
|
15
|
|
19
|
16
|
def __init__(self, data_callback=None):
|
20
|
17
|
self.__data_callback__ = data_callback
|
21
|
|
- # Initial the dht device, with data pin connected to:
|
22
|
|
- self.__active__ = True
|
23
|
|
- self.__thread__ = threading.Thread(target=self.run, args=())
|
24
|
|
- self.__thread__.daemon = True # Daemonize thread
|
25
|
|
- self.__thread__.start() # Start the execution
|
26
|
|
-
|
27
|
|
- def run(self):
|
28
|
|
- while self.__active__:
|
29
|
|
- data = self.__bmp_data_transmission__()
|
30
|
|
- if data is not None:
|
31
|
|
- logger.debug('BMP-Communication: Successfully: %s', repr(data))
|
32
|
|
- if self.__data_callback__ is not None:
|
33
|
|
- self.__data_callback__(**data)
|
34
|
|
- time.sleep(0.5)
|
|
18
|
+ # Initialise background_task
|
|
19
|
+ background_task.__init__(self)
|
35
|
20
|
|
36
|
|
- def close(self):
|
37
|
|
- self.__active__ = False
|
38
|
|
- self.__thread__.join()
|
39
|
|
-
|
40
|
|
- def __del__(self):
|
41
|
|
- self.close()
|
|
21
|
+ def __run__(self):
|
|
22
|
+ data = self.__bmp_data_transmission__()
|
|
23
|
+ if data is not None:
|
|
24
|
+ logger.debug('BMP-Communication: Successfully: %s', repr(data))
|
|
25
|
+ if self.__data_callback__ is not None:
|
|
26
|
+ self.__data_callback__(**data)
|
42
|
27
|
|
43
|
28
|
def __bmp_data_transmission__(self):
|
44
|
|
- rv = {}
|
45
|
|
- # Get I2C bus
|
46
|
|
- bus = smbus.SMBus(1)
|
47
|
|
-
|
48
|
|
- # BMP180 address, 0x77(119)
|
49
|
|
- # Read data back from 0xAA(170), 22 bytes
|
50
|
|
- data = bus.read_i2c_block_data(0x77, 0xAA, 22)
|
51
|
|
-
|
52
|
|
- # Convert the data
|
53
|
|
- AC1 = data[0] * 256 + data[1]
|
54
|
|
- if AC1 > 32767 :
|
55
|
|
- AC1 -= 65535
|
56
|
|
- AC2 = data[2] * 256 + data[3]
|
57
|
|
- if AC2 > 32767 :
|
58
|
|
- AC2 -= 65535
|
59
|
|
- AC3 = data[4] * 256 + data[5]
|
60
|
|
- if AC3 > 32767 :
|
61
|
|
- AC3 -= 65535
|
62
|
|
- AC4 = data[6] * 256 + data[7]
|
63
|
|
- AC5 = data[8] * 256 + data[9]
|
64
|
|
- AC6 = data[10] * 256 + data[11]
|
65
|
|
- B1 = data[12] * 256 + data[13]
|
66
|
|
- if B1 > 32767 :
|
67
|
|
- B1 -= 65535
|
68
|
|
- B2 = data[14] * 256 + data[15]
|
69
|
|
- if B2 > 32767 :
|
70
|
|
- B2 -= 65535
|
71
|
|
- MB = data[16] * 256 + data[17]
|
72
|
|
- if MB > 32767 :
|
73
|
|
- MB -= 65535
|
74
|
|
- MC = data[18] * 256 + data[19]
|
75
|
|
- if MC > 32767 :
|
76
|
|
- MC -= 65535
|
77
|
|
- MD = data[20] * 256 + data[21]
|
78
|
|
- if MD > 32767 :
|
79
|
|
- MD -= 65535
|
80
|
|
-
|
81
|
|
- time.sleep(0.5)
|
82
|
|
-
|
83
|
|
- # BMP180 address, 0x77(119)
|
84
|
|
- # Select measurement control register, 0xF4(244)
|
85
|
|
- # 0x2E(46) Enable temperature measurement
|
86
|
|
- bus.write_byte_data(0x77, 0xF4, 0x2E)
|
87
|
|
-
|
88
|
|
- time.sleep(0.5)
|
|
29
|
+ if not DEBUG:
|
|
30
|
+ rv = {}
|
|
31
|
+ # Get I2C bus
|
|
32
|
+ bus = smbus.SMBus(1)
|
|
33
|
+
|
|
34
|
+ # BMP180 address, 0x77(119)
|
|
35
|
+ # Read data back from 0xAA(170), 22 bytes
|
|
36
|
+ data = bus.read_i2c_block_data(0x77, 0xAA, 22)
|
|
37
|
+
|
|
38
|
+ # Convert the data
|
|
39
|
+ AC1 = data[0] * 256 + data[1]
|
|
40
|
+ if AC1 > 32767 :
|
|
41
|
+ AC1 -= 65535
|
|
42
|
+ AC2 = data[2] * 256 + data[3]
|
|
43
|
+ if AC2 > 32767 :
|
|
44
|
+ AC2 -= 65535
|
|
45
|
+ AC3 = data[4] * 256 + data[5]
|
|
46
|
+ if AC3 > 32767 :
|
|
47
|
+ AC3 -= 65535
|
|
48
|
+ AC4 = data[6] * 256 + data[7]
|
|
49
|
+ AC5 = data[8] * 256 + data[9]
|
|
50
|
+ AC6 = data[10] * 256 + data[11]
|
|
51
|
+ B1 = data[12] * 256 + data[13]
|
|
52
|
+ if B1 > 32767 :
|
|
53
|
+ B1 -= 65535
|
|
54
|
+ B2 = data[14] * 256 + data[15]
|
|
55
|
+ if B2 > 32767 :
|
|
56
|
+ B2 -= 65535
|
|
57
|
+ MB = data[16] * 256 + data[17]
|
|
58
|
+ if MB > 32767 :
|
|
59
|
+ MB -= 65535
|
|
60
|
+ MC = data[18] * 256 + data[19]
|
|
61
|
+ if MC > 32767 :
|
|
62
|
+ MC -= 65535
|
|
63
|
+ MD = data[20] * 256 + data[21]
|
|
64
|
+ if MD > 32767 :
|
|
65
|
+ MD -= 65535
|
|
66
|
+
|
|
67
|
+ time.sleep(self.SMBUS_DELAY)
|
|
68
|
+
|
|
69
|
+ # BMP180 address, 0x77(119)
|
|
70
|
+ # Select measurement control register, 0xF4(244)
|
|
71
|
+ # 0x2E(46) Enable temperature measurement
|
|
72
|
+ bus.write_byte_data(0x77, 0xF4, 0x2E)
|
|
73
|
+
|
|
74
|
+ time.sleep(self.SMBUS_DELAY)
|
|
75
|
+
|
|
76
|
+ # BMP180 address, 0x77(119)
|
|
77
|
+ # Read data back from 0xF6(246), 2 bytes
|
|
78
|
+ # temp MSB, temp LSB
|
|
79
|
+ data = bus.read_i2c_block_data(0x77, 0xF6, 2)
|
|
80
|
+
|
|
81
|
+ # Convert the data
|
|
82
|
+ temp = data[0] * 256 + data[1]
|
|
83
|
+
|
|
84
|
+ # BMP180 address, 0x77(119)
|
|
85
|
+ # Select measurement control register, 0xF4(244)
|
|
86
|
+ # 0x74(116) Enable pressure measurement, OSS = 1
|
|
87
|
+ bus.write_byte_data(0x77, 0xF4, 0x74)
|
|
88
|
+
|
|
89
|
+ time.sleep(self.SMBUS_DELAY)
|
|
90
|
+
|
|
91
|
+ # BMP180 address, 0x77(119)
|
|
92
|
+ # Read data back from 0xF6(246), 3 bytes
|
|
93
|
+ # pres MSB1, pres MSB, pres LSB
|
|
94
|
+ data = bus.read_i2c_block_data(0x77, 0xF6, 3)
|
|
95
|
+
|
|
96
|
+ rv[self.KEY_TIME] = int(time.time())
|
89
|
97
|
|
90
|
|
- # BMP180 address, 0x77(119)
|
91
|
|
- # Read data back from 0xF6(246), 2 bytes
|
92
|
|
- # temp MSB, temp LSB
|
93
|
|
- data = bus.read_i2c_block_data(0x77, 0xF6, 2)
|
|
98
|
+ # Convert the data
|
|
99
|
+ pres = ((data[0] * 65536) + (data[1] * 256) + data[2]) / 128
|
|
100
|
+ # Callibration for Temperature
|
|
101
|
+ X1 = (temp - AC6) * AC5 / 32768.0
|
|
102
|
+ X2 = (MC * 2048.0) / (X1 + MD)
|
|
103
|
+ B5 = X1 + X2
|
|
104
|
+ rv[self.KEY_TEMPERATURE] = ((B5 + 8.0) / 16.0) / 10.0
|
|
105
|
+
|
|
106
|
+ # Calibration for Pressure
|
|
107
|
+ B6 = B5 - 4000
|
|
108
|
+ X1 = (B2 * (B6 * B6 / 4096.0)) / 2048.0
|
|
109
|
+ X2 = AC2 * B6 / 2048.0
|
|
110
|
+ X3 = X1 + X2
|
|
111
|
+ B3 = (((AC1 * 4 + X3) * 2) + 2) / 4.0
|
|
112
|
+ X1 = AC3 * B6 / 8192.0
|
|
113
|
+ X2 = (B1 * (B6 * B6 / 2048.0)) / 65536.0
|
|
114
|
+ X3 = ((X1 + X2) + 2) / 4.0
|
|
115
|
+ B4 = AC4 * (X3 + 32768) / 32768.0
|
|
116
|
+ B7 = ((pres - B3) * (25000.0))
|
|
117
|
+ pressure = 0.0
|
|
118
|
+ if B7 < 2147483648:
|
|
119
|
+ pressure = (B7 * 2) / B4
|
|
120
|
+ else :
|
|
121
|
+ pressure = (B7 / B4) * 2
|
|
122
|
+ X1 = (pressure / 256.0) * (pressure / 256.0)
|
|
123
|
+ X1 = (X1 * 3038.0) / 65536.0
|
|
124
|
+ X2 = ((-7357) * pressure) / 65536.0
|
|
125
|
+ rv[self.KEY_PRESSURE] = (pressure + (X1 + X2 + 3791) / 16.0) / 100
|
94
|
126
|
|
95
|
|
- # Convert the data
|
96
|
|
- temp = data[0] * 256 + data[1]
|
97
|
|
-
|
98
|
|
- # BMP180 address, 0x77(119)
|
99
|
|
- # Select measurement control register, 0xF4(244)
|
100
|
|
- # 0x74(116) Enable pressure measurement, OSS = 1
|
101
|
|
- bus.write_byte_data(0x77, 0xF4, 0x74)
|
102
|
|
-
|
103
|
|
- time.sleep(0.5)
|
104
|
|
-
|
105
|
|
- # BMP180 address, 0x77(119)
|
106
|
|
- # Read data back from 0xF6(246), 3 bytes
|
107
|
|
- # pres MSB1, pres MSB, pres LSB
|
108
|
|
- data = bus.read_i2c_block_data(0x77, 0xF6, 3)
|
109
|
|
-
|
110
|
|
- rv[self.KEY_TIME] = time.time()
|
111
|
|
-
|
112
|
|
- # Convert the data
|
113
|
|
- pres = ((data[0] * 65536) + (data[1] * 256) + data[2]) / 128
|
114
|
|
- # Callibration for Temperature
|
115
|
|
- X1 = (temp - AC6) * AC5 / 32768.0
|
116
|
|
- X2 = (MC * 2048.0) / (X1 + MD)
|
117
|
|
- B5 = X1 + X2
|
118
|
|
- rv[self.KEY_TEMPERATURE] = ((B5 + 8.0) / 16.0) / 10.0
|
119
|
|
-
|
120
|
|
- # Calibration for Pressure
|
121
|
|
- B6 = B5 - 4000
|
122
|
|
- X1 = (B2 * (B6 * B6 / 4096.0)) / 2048.0
|
123
|
|
- X2 = AC2 * B6 / 2048.0
|
124
|
|
- X3 = X1 + X2
|
125
|
|
- B3 = (((AC1 * 4 + X3) * 2) + 2) / 4.0
|
126
|
|
- X1 = AC3 * B6 / 8192.0
|
127
|
|
- X2 = (B1 * (B6 * B6 / 2048.0)) / 65536.0
|
128
|
|
- X3 = ((X1 + X2) + 2) / 4.0
|
129
|
|
- B4 = AC4 * (X3 + 32768) / 32768.0
|
130
|
|
- B7 = ((pres - B3) * (25000.0))
|
131
|
|
- pressure = 0.0
|
132
|
|
- if B7 < 2147483648:
|
133
|
|
- pressure = (B7 * 2) / B4
|
134
|
|
- else :
|
135
|
|
- pressure = (B7 / B4) * 2
|
136
|
|
- X1 = (pressure / 256.0) * (pressure / 256.0)
|
137
|
|
- X1 = (X1 * 3038.0) / 65536.0
|
138
|
|
- X2 = ((-7357) * pressure) / 65536.0
|
139
|
|
- rv[self.KEY_PRESSURE] = (pressure + (X1 + X2 + 3791) / 16.0) / 100
|
140
|
|
-
|
141
|
|
- return rv
|
|
127
|
+ return rv
|
|
128
|
+ else:
|
|
129
|
+ time.sleep(3 * self.SMBUS_DELAY)
|
|
130
|
+ return {
|
|
131
|
+ self.KEY_PRESSURE: 1717.,
|
|
132
|
+ self.KEY_TEMPERATURE: 17.17,
|
|
133
|
+ self.KEY_TIME: int(time.time())
|
|
134
|
+ }
|