feat(lib):Move custom pimoroni to personal git server
[EVA-2020-02.git] / exec / pressure / bmp388.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 import time
4 import smbus
5 import math
6
7 # define BMP388 Device I2C address
8
9 I2C_ADD_BMP388_AD0_LOW = 0x76
10 I2C_ADD_BMP388_AD0_HIGH = 0x77
11 I2C_ADD_BMP388 = I2C_ADD_BMP388_AD0_HIGH
12
13 BMP388_REG_ADD_WIA = 0x00
14 BMP388_REG_VAL_WIA = 0x50
15
16 BMP388_REG_ADD_ERR = 0x02
17 BMP388_REG_VAL_FATAL_ERR = 0x01
18 BMP388_REG_VAL_CMD_ERR = 0x02
19 BMP388_REG_VAL_CONF_ERR = 0x04
20
21 BMP388_REG_ADD_STATUS = 0x03
22 BMP388_REG_VAL_CMD_RDY = 0x10
23 BMP388_REG_VAL_DRDY_PRESS = 0x20
24 BMP388_REG_VAL_DRDY_TEMP = 0x40
25
26 BMP388_REG_ADD_CMD = 0x7E
27 BMP388_REG_VAL_EXTMODE_EN = 0x34
28 BMP388_REG_VAL_FIFI_FLUSH = 0xB0
29 BMP388_REG_VAL_SOFT_RESET = 0xB6
30
31 BMP388_REG_ADD_PWR_CTRL = 0x1B
32 BMP388_REG_VAL_PRESS_EN = 0x01
33 BMP388_REG_VAL_TEMP_EN = 0x02
34 BMP388_REG_VAL_NORMAL_MODE = 0x30
35
36 BMP388_REG_ADD_PRESS_XLSB = 0x04
37 BMP388_REG_ADD_PRESS_LSB = 0x05
38 BMP388_REG_ADD_PRESS_MSB = 0x06
39 BMP388_REG_ADD_TEMP_XLSB = 0x07
40 BMP388_REG_ADD_TEMP_LSB = 0x08
41 BMP388_REG_ADD_TEMP_MSB = 0x09
42
43 BMP388_REG_ADD_T1_LSB = 0x31
44 BMP388_REG_ADD_T1_MSB = 0x32
45 BMP388_REG_ADD_T2_LSB = 0x33
46 BMP388_REG_ADD_T2_MSB = 0x34
47 BMP388_REG_ADD_T3 = 0x35
48 BMP388_REG_ADD_P1_LSB = 0x36
49 BMP388_REG_ADD_P1_MSB = 0x37
50 BMP388_REG_ADD_P2_LSB = 0x38
51 BMP388_REG_ADD_P2_MSB = 0x39
52 BMP388_REG_ADD_P3 = 0x3A
53 BMP388_REG_ADD_P4 = 0x3B
54 BMP388_REG_ADD_P5_LSB = 0x3C
55 BMP388_REG_ADD_P5_MSB = 0x3D
56 BMP388_REG_ADD_P6_LSB = 0x3E
57 BMP388_REG_ADD_P6_MSB = 0x3F
58 BMP388_REG_ADD_P7 = 0x40
59 BMP388_REG_ADD_P8 = 0x41
60 BMP388_REG_ADD_P9_LSB = 0x42
61 BMP388_REG_ADD_P9_MSB = 0x43
62 BMP388_REG_ADD_P10 = 0x44
63 BMP388_REG_ADD_P11 = 0x45
64
65
66 class BMP388(object):
67
68 """docstring for BMP388"""
69
70 def __init__(self, address=I2C_ADD_BMP388):
71 self._address = address
72 self._bus = smbus.SMBus(0x01)
73
74 # Load calibration values.
75
76 if self._read_byte(BMP388_REG_ADD_WIA) == BMP388_REG_VAL_WIA:
77 print("Pressure sersor is BMP388!\r\n")
78 u8RegData = self._read_byte(BMP388_REG_ADD_STATUS)
79 if u8RegData & BMP388_REG_VAL_CMD_RDY:
80 self._write_byte(BMP388_REG_ADD_CMD,
81 BMP388_REG_VAL_SOFT_RESET)
82 time.sleep(0.01)
83 else:
84 print ("Pressure sersor NULL!\r\n")
85 self._write_byte(BMP388_REG_ADD_PWR_CTRL,
86 BMP388_REG_VAL_PRESS_EN
87 | BMP388_REG_VAL_TEMP_EN
88 | BMP388_REG_VAL_NORMAL_MODE)
89 self._load_calibration()
90
91 def _read_byte(self, cmd):
92 return self._bus.read_byte_data(self._address, cmd)
93
94 def _read_s8(self, cmd):
95 result = self._read_byte(cmd)
96 if result > 128:
97 result -= 256
98 return result
99
100 def _read_u16(self, cmd):
101 LSB = self._bus.read_byte_data(self._address, cmd)
102 MSB = self._bus.read_byte_data(self._address, cmd + 0x01)
103 return (MSB << 0x08) + LSB
104
105 def _read_s16(self, cmd):
106 result = self._read_u16(cmd)
107 if result > 32767:
108 result -= 65536
109 return result
110
111 def _write_byte(self, cmd, val):
112 self._bus.write_byte_data(self._address, cmd, val)
113
114 def _load_calibration(self):
115 print ("_load_calibration\r\n")
116 self.T1 = self._read_u16(BMP388_REG_ADD_T1_LSB)
117 self.T2 = self._read_u16(BMP388_REG_ADD_T2_LSB)
118 self.T3 = self._read_s8(BMP388_REG_ADD_T3)
119 self.P1 = self._read_s16(BMP388_REG_ADD_P1_LSB)
120 self.P2 = self._read_s16(BMP388_REG_ADD_P2_LSB)
121 self.P3 = self._read_s8(BMP388_REG_ADD_P3)
122 self.P4 = self._read_s8(BMP388_REG_ADD_P4)
123 self.P5 = self._read_u16(BMP388_REG_ADD_P5_LSB)
124 self.P6 = self._read_u16(BMP388_REG_ADD_P6_LSB)
125 self.P7 = self._read_s8(BMP388_REG_ADD_P7)
126 self.P8 = self._read_s8(BMP388_REG_ADD_P8)
127 self.P9 = self._read_s16(BMP388_REG_ADD_P9_LSB)
128 self.P10 = self._read_s8(BMP388_REG_ADD_P10)
129 self.P11 = self._read_s8(BMP388_REG_ADD_P11)
130
131 # print(self.T1)
132 # print(self.T2)
133 # print(self.T3)
134 # print(self.P1)
135 # print(self.P2)
136 # print(self.P3)
137 # print(self.P4)
138 # print(self.P5)
139 # print(self.P6)
140 # print(self.P7)
141 # print(self.P8)
142 # print(self.P9)
143 # print(self.P10)
144 # print(self.P11)
145
146 def compensate_temperature(self, adc_T):
147 partial_data1 = adc_T - 256 * self.T1
148 partial_data2 = self.T2 * partial_data1
149 partial_data3 = partial_data1 * partial_data1
150 partial_data4 = partial_data3 * self.T3
151 partial_data5 = partial_data2 * 262144 + partial_data4
152 partial_data6 = partial_data5 / 4294967296
153 self.T_fine = partial_data6
154 comp_temp = partial_data6 * 25 / 16384
155 return comp_temp
156
157 def compensate_pressure(self, adc_P):
158 partial_data1 = self.T_fine * self.T_fine
159 partial_data2 = partial_data1 / 0x40
160 partial_data3 = partial_data2 * self.T_fine / 256
161 partial_data4 = self.P8 * partial_data3 / 0x20
162 partial_data5 = self.P7 * partial_data1 * 0x10
163 partial_data6 = self.P6 * self.T_fine * 4194304
164 offset = self.P5 * 140737488355328 + partial_data4 \
165 + partial_data5 + partial_data6
166
167 partial_data2 = self.P4 * partial_data3 / 0x20
168 partial_data4 = self.P3 * partial_data1 * 0x04
169 partial_data5 = (self.P2 - 16384) * self.T_fine * 2097152
170 sensitivity = (self.P1 - 16384) * 70368744177664 \
171 + partial_data2 + partial_data4 + partial_data5
172
173 partial_data1 = sensitivity / 16777216 * adc_P
174 partial_data2 = self.P10 * self.T_fine
175 partial_data3 = partial_data2 + 65536 * self.P9
176 partial_data4 = partial_data3 * adc_P / 8192
177 partial_data5 = partial_data4 * adc_P / 512
178 partial_data6 = adc_P * adc_P
179 partial_data2 = self.P11 * partial_data6 / 65536
180 partial_data3 = partial_data2 * adc_P / 128
181 partial_data4 = offset / 0x04 + partial_data1 + partial_data5 \
182 + partial_data3
183 comp_press = partial_data4 * 25 / 1099511627776
184 return comp_press
185
186 def get_temperature_and_pressure_and_altitude(self):
187 """Returns pressure in Pa as double. Output value of "6386.2"equals 96386.2 Pa = 963.862 hPa."""
188
189 xlsb = self._read_byte(BMP388_REG_ADD_TEMP_XLSB)
190 lsb = self._read_byte(BMP388_REG_ADD_TEMP_LSB)
191 msb = self._read_byte(BMP388_REG_ADD_TEMP_MSB)
192 adc_T = (msb << 0x10) + (lsb << 0x08) + xlsb
193 temperature = self.compensate_temperature(adc_T)
194 xlsb = self._read_byte(BMP388_REG_ADD_PRESS_XLSB)
195 lsb = self._read_byte(BMP388_REG_ADD_PRESS_LSB)
196 msb = self._read_byte(BMP388_REG_ADD_PRESS_MSB)
197
198 adc_P = (msb << 0x10) + (lsb << 0x08) + xlsb
199 pressure = self.compensate_pressure(adc_P)
200 altitude = 4433000 * (0x01 - pow(pressure / 100.0 / 101325.0,
201 0.1903))
202
203 return (temperature, pressure, altitude)
204
205
206 if __name__ == '__main__':
207
208 import time
209
210 print("BMP388 Test Program ...\n")
211
212 bmp388 = BMP388()
213
214 while True:
215 time.sleep(0.5)
216 temperature,pressure,altitude = bmp388.get_temperature_and_pressure_and_altitude()
217 print(' Temperature = %.1f Pressure = %.2f Altitude =%.2f '%(temperature/100.0,pressure/100.0,altitude/100.0))