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