]> git.itanic.dy.fi Git - BME280_driver/blob - README.md
ce5eb3643847a5b8d41db957d8ad9ec968b779bf
[BME280_driver] / README.md
1 # BME280 sensor API\r
2 ## Introduction\r
3 This package contains the Bosch Sensortec's BME280 pressure sensor driver (sensor API)\r
4 \r
5 The sensor driver package includes bme280.c, bme280.h and bme280_defs.h files.\r
6 \r
7 ## Version\r
8 File          | Version | Date\r
9 --------------|---------|------------\r
10 bme280.c      |  3.4.2  | 21 Jan 2020\r
11 bme280.h      |  3.4.2  | 21 Jan 2020\r
12 bme280_defs.h |  3.4.2  | 21 Jan 2020\r
13 \r
14 ## Integration details\r
15 * Integrate bme280.h, bme280_defs.h and bme280.c file in to the project.\r
16 * Include the bme280.h file in your code like below.\r
17 ``` c\r
18 #include "bme280.h"\r
19 ```\r
20 \r
21 ## File information\r
22 * bme280_defs.h : This header file has the constants, macros and datatype declarations.\r
23 * bme280.h : This header file contains the declarations of the sensor driver APIs.\r
24 * bme280.c : This source file contains the definitions of the sensor driver APIs.\r
25 \r
26 ## Supported sensor interfaces\r
27 * SPI 4-wire\r
28 * I2C\r
29 \r
30 SPI 3-wire is currently not supported in the API.\r
31 ## Usage guide\r
32 ### Initializing the sensor\r
33 To initialize the sensor, user need to create a device structure. User can do this by \r
34 creating an instance of the structure bme280_dev. After creating the device strcuture, user \r
35 need to fill in the various parameters as shown below.\r
36 \r
37 #### Example for SPI 4-Wire\r
38 ``` c\r
39 struct bme280_dev dev;\r
40 int8_t rslt = BME280_OK;\r
41 \r
42 /* Sensor_0 interface over SPI with native chip select line */\r
43 dev.dev_id = 0;\r
44 dev.intf = BME280_SPI_INTF;\r
45 dev.read = user_spi_read;\r
46 dev.write = user_spi_write;\r
47 dev.delay_ms = user_delay_ms;\r
48 \r
49 rslt = bme280_init(&dev);\r
50 ```\r
51 #### Example for I2C\r
52 ``` c\r
53 struct bme280_dev dev;\r
54 int8_t rslt = BME280_OK;\r
55 \r
56 dev.dev_id = BME280_I2C_ADDR_PRIM;\r
57 dev.intf = BME280_I2C_INTF;\r
58 dev.read = user_i2c_read;\r
59 dev.write = user_i2c_write;\r
60 dev.delay_ms = user_delay_ms;\r
61 \r
62 rslt = bme280_init(&dev);\r
63 ```\r
64 Regarding compensation functions for temperature,pressure and humidity we have two implementations.\r
65 1) Double precision floating point version\r
66 2) Integer version\r
67 \r
68 By default, integer version is used in the API. If the user needs the floating point version, the user has to uncomment BME280_FLOAT_ENABLE macro in bme280_defs.h file or add that to the compiler flags.\r
69 \r
70 In integer compensation functions, we also have below two implementations for pressure.\r
71 1) For 32 bit machine.\r
72 2) For 64 bit machine.\r
73 \r
74 By default, 64 bit variant is used in the API. If the user wants 32 bit variant, the user can disable the\r
75 macro BME280_64BIT_ENABLE in bme280_defs.h file.\r
76 \r
77 ### Sensor data units\r
78 > The sensor data units depends on the following macros being enabled or not, \r
79 > (in bme280_defs.h file or as compiler macros)\r
80 >   * BME280_FLOAT_ENABLE\r
81 >   * BME280_64BIT_ENABLE\r
82 \r
83 In case of the macro "BME280_FLOAT_ENABLE" enabled,\r
84 The outputs are in double and the units are\r
85 \r
86     - °C for temperature\r
87     - % relative humidity\r
88     - Pascal for pressure\r
89 \r
90 In case if "BME280_FLOAT_ENABLE" is not enabled, then it is\r
91 \r
92     - int32_t for temperature with the units 100 * °C\r
93     - uint32_t for humidity with the units 1024 * % relative humidity\r
94     - uint32_t for pressure\r
95          If macro "BME280_64BIT_ENABLE" is enabled, which it is by default, the unit is 100 * Pascal\r
96          If this macro is disabled, Then the unit is in Pascal\r
97 \r
98 ### Stream sensor data\r
99 #### Stream sensor data in forced mode\r
100 \r
101 ``` c\r
102 int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)\r
103 {\r
104     int8_t rslt;\r
105     uint8_t settings_sel;\r
106         uint32_t req_delay;\r
107     struct bme280_data comp_data;\r
108 \r
109     /* Recommended mode of operation: Indoor navigation */\r
110     dev->settings.osr_h = BME280_OVERSAMPLING_1X;\r
111     dev->settings.osr_p = BME280_OVERSAMPLING_16X;\r
112     dev->settings.osr_t = BME280_OVERSAMPLING_2X;\r
113     dev->settings.filter = BME280_FILTER_COEFF_16;\r
114 \r
115     settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;\r
116 \r
117     rslt = bme280_set_sensor_settings(settings_sel, dev);\r
118         \r
119         /*Calculate the minimum delay required between consecutive measurement based upon the sensor enabled\r
120      *  and the oversampling configuration. */\r
121     req_delay = bme280_cal_meas_delay(&dev->settings);\r
122 \r
123     printf("Temperature, Pressure, Humidity\r\n");\r
124     /* Continuously stream sensor data */\r
125     while (1) {\r
126         rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);\r
127         /* Wait for the measurement to complete and print data @25Hz */\r
128         dev->delay_ms(req_delay);\r
129         rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);\r
130         print_sensor_data(&comp_data);\r
131     }\r
132     return rslt;\r
133 }\r
134 \r
135 void print_sensor_data(struct bme280_data *comp_data)\r
136 {\r
137 #ifdef BME280_FLOAT_ENABLE\r
138         printf("%0.2f, %0.2f, %0.2f\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);\r
139 #else\r
140         printf("%ld, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);\r
141 #endif\r
142 }\r
143 ```\r
144 ##### Stream sensor data in normal mode\r
145 ``` c\r
146 int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)\r
147 {\r
148         int8_t rslt;\r
149         uint8_t settings_sel;\r
150         struct bme280_data comp_data;\r
151 \r
152         /* Recommended mode of operation: Indoor navigation */\r
153         dev->settings.osr_h = BME280_OVERSAMPLING_1X;\r
154         dev->settings.osr_p = BME280_OVERSAMPLING_16X;\r
155         dev->settings.osr_t = BME280_OVERSAMPLING_2X;\r
156         dev->settings.filter = BME280_FILTER_COEFF_16;\r
157         dev->settings.standby_time = BME280_STANDBY_TIME_62_5_MS;\r
158 \r
159         settings_sel = BME280_OSR_PRESS_SEL;\r
160         settings_sel |= BME280_OSR_TEMP_SEL;\r
161         settings_sel |= BME280_OSR_HUM_SEL;\r
162         settings_sel |= BME280_STANDBY_SEL;\r
163         settings_sel |= BME280_FILTER_SEL;\r
164         rslt = bme280_set_sensor_settings(settings_sel, dev);\r
165         rslt = bme280_set_sensor_mode(BME280_NORMAL_MODE, dev);\r
166 \r
167         printf("Temperature, Pressure, Humidity\r\n");\r
168         while (1) {\r
169                 /* Delay while the sensor completes a measurement */\r
170                 dev->delay_ms(70);\r
171                 rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);\r
172                 print_sensor_data(&comp_data);\r
173         }\r
174 \r
175         return rslt;\r
176 }\r
177 \r
178 void print_sensor_data(struct bme280_data *comp_data)\r
179 {\r
180 #ifdef BME280_FLOAT_ENABLE\r
181         printf("%0.2f, %0.2f, %0.2f\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);\r
182 #else\r
183         printf("%ld, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);\r
184 #endif\r
185 }\r
186 ```\r
187 \r
188 ### Templates for function pointers\r
189 ``` c\r
190 \r
191 void user_delay_ms(uint32_t period)\r
192 {\r
193     /*\r
194      * Return control or wait,\r
195      * for a period amount of milliseconds\r
196      */\r
197 }\r
198 \r
199 int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)\r
200 {\r
201     int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */\r
202 \r
203     /*\r
204      * The parameter dev_id can be used as a variable to select which Chip Select pin has\r
205      * to be set low to activate the relevant device on the SPI bus\r
206      */\r
207 \r
208     /*\r
209      * Data on the bus should be like\r
210      * |----------------+---------------------+-------------|\r
211      * | MOSI           | MISO                | Chip Select |\r
212      * |----------------+---------------------|-------------|\r
213      * | (don't care)   | (don't care)        | HIGH        |\r
214      * | (reg_addr)     | (don't care)        | LOW         |\r
215      * | (don't care)   | (reg_data[0])       | LOW         |\r
216      * | (....)         | (....)              | LOW         |\r
217      * | (don't care)   | (reg_data[len - 1]) | LOW         |\r
218      * | (don't care)   | (don't care)        | HIGH        |\r
219      * |----------------+---------------------|-------------|\r
220      */\r
221 \r
222     return rslt;\r
223 }\r
224 \r
225 int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)\r
226 {\r
227     int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */\r
228 \r
229     /*\r
230      * The parameter dev_id can be used as a variable to select which Chip Select pin has\r
231      * to be set low to activate the relevant device on the SPI bus\r
232      */\r
233 \r
234     /*\r
235      * Data on the bus should be like\r
236      * |---------------------+--------------+-------------|\r
237      * | MOSI                | MISO         | Chip Select |\r
238      * |---------------------+--------------|-------------|\r
239      * | (don't care)        | (don't care) | HIGH        |\r
240      * | (reg_addr)          | (don't care) | LOW         |\r
241      * | (reg_data[0])       | (don't care) | LOW         |\r
242      * | (....)              | (....)       | LOW         |\r
243      * | (reg_data[len - 1]) | (don't care) | LOW         |\r
244      * | (don't care)        | (don't care) | HIGH        |\r
245      * |---------------------+--------------|-------------|\r
246      */\r
247 \r
248     return rslt;\r
249 }\r
250 \r
251 int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)\r
252 {\r
253     int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */\r
254 \r
255     /*\r
256      * The parameter dev_id can be used as a variable to store the I2C address of the device\r
257      */\r
258 \r
259     /*\r
260      * Data on the bus should be like\r
261      * |------------+---------------------|\r
262      * | I2C action | Data                |\r
263      * |------------+---------------------|\r
264      * | Start      | -                   |\r
265      * | Write      | (reg_addr)          |\r
266      * | Stop       | -                   |\r
267      * | Start      | -                   |\r
268      * | Read       | (reg_data[0])       |\r
269      * | Read       | (....)              |\r
270      * | Read       | (reg_data[len - 1]) |\r
271      * | Stop       | -                   |\r
272      * |------------+---------------------|\r
273      */\r
274 \r
275     return rslt;\r
276 }\r
277 \r
278 int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)\r
279 {\r
280     int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */\r
281 \r
282     /*\r
283      * The parameter dev_id can be used as a variable to store the I2C address of the device\r
284      */\r
285 \r
286     /*\r
287      * Data on the bus should be like\r
288      * |------------+---------------------|\r
289      * | I2C action | Data                |\r
290      * |------------+---------------------|\r
291      * | Start      | -                   |\r
292      * | Write      | (reg_addr)          |\r
293      * | Write      | (reg_data[0])       |\r
294      * | Write      | (....)              |\r
295      * | Write      | (reg_data[len - 1]) |\r
296      * | Stop       | -                   |\r
297      * |------------+---------------------|\r
298      */\r
299 \r
300     return rslt;\r
301 }\r
302 \r
303 ```\r
304 \r
305 ## Copyright (C) 2016 - 2017 Bosch Sensortec GmbH