source: rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/BME280.cpp@ 175

Last change on this file since 175 was 175, checked in by ertl-honda, 8 years ago

ライブラリを Arduino IDE 1.7.9 にupdate

File size: 8.6 KB
Line 
1/***************************************************************************
2 This is a library for the BME280 humidity, temperature & pressure sensor
3
4 Designed specifically to work with the Adafruit BME280 Breakout
5 ----> http://www.adafruit.com/products/2650
6
7 These sensors use I2C or SPI to communicate, 2 or 4 pins are required
8 to interface.
9
10 Adafruit invests time and resources providing this open source code,
11 please support Adafruit andopen-source hardware by purchasing products
12 from Adafruit!
13
14 Written by Limor Fried & Kevin Townsend for Adafruit Industries.
15 BSD license, all text above must be included in any redistribution
16 ***************************************************************************/
17#include "Arduino.h"
18#include <Wire.h>
19#include "BME280.h"
20
21
22/***************************************************************************
23 PRIVATE FUNCTIONS
24 ***************************************************************************/
25
26
27bool BME280::begin(uint8_t a) {
28 _i2caddr = a;
29
30 if (read8(BME280_REGISTER_CHIPID) != 0x60)
31 return false;
32
33 readCoefficients();
34
35 //Set before CONTROL_meas (DS 5.4.3)
36 write8(BME280_REGISTER_CONTROLHUMID, 0x05); //16x oversampling
37
38 write8(BME280_REGISTER_CONTROL, 0xB7); // 16x ovesampling, normal mode
39 return true;
40}
41
42
43/**************************************************************************/
44/*!
45 @brief Writes an 8 bit value over I2C/SPI
46*/
47/**************************************************************************/
48void BME280::write8(byte reg, byte value)
49{
50 Wire.beginTransmission((uint8_t)_i2caddr);
51 Wire.write((uint8_t)reg);
52 Wire.write((uint8_t)value);
53 Wire.endTransmission();
54}
55
56/**************************************************************************/
57/*!
58 @brief Reads an 8 bit value over I2C
59*/
60/**************************************************************************/
61uint8_t BME280::read8(byte reg)
62{
63 uint8_t value;
64
65 Wire.beginTransmission((uint8_t)_i2caddr);
66 Wire.write((uint8_t)reg);
67 Wire.endTransmission();
68 Wire.requestFrom((uint8_t)_i2caddr, (byte)1);
69 value = Wire.read();
70 return value;
71}
72
73/**************************************************************************/
74/*!
75 @brief Reads a 16 bit value over I2C
76*/
77/**************************************************************************/
78uint16_t BME280::read16(byte reg)
79{
80 uint16_t value;
81
82 Wire.beginTransmission((uint8_t)_i2caddr);
83 Wire.write((uint8_t)reg);
84 Wire.endTransmission();
85 Wire.requestFrom((uint8_t)_i2caddr, (byte)2);
86 value = (Wire.read() << 8) | Wire.read();
87
88 return value;
89}
90
91uint16_t BME280::read16_LE(byte reg) {
92 uint16_t temp = read16(reg);
93 return (temp >> 8) | (temp << 8);
94
95}
96
97/**************************************************************************/
98/*!
99 @brief Reads a signed 16 bit value over I2C
100*/
101/**************************************************************************/
102int16_t BME280::readS16(byte reg)
103{
104 return (int16_t)read16(reg);
105
106}
107
108int16_t BME280::readS16_LE(byte reg)
109{
110 return (int16_t)read16_LE(reg);
111
112}
113
114
115/**************************************************************************/
116/*!
117 @brief Reads a 24 bit value over I2C
118*/
119/**************************************************************************/
120
121uint32_t BME280::read24(byte reg)
122{
123 uint32_t value;
124
125 Wire.beginTransmission((uint8_t)_i2caddr);
126 Wire.write((uint8_t)reg);
127 Wire.endTransmission();
128 Wire.requestFrom((uint8_t)_i2caddr, (byte)3);
129
130 value = Wire.read();
131 value <<= 8;
132 value |= Wire.read();
133 value <<= 8;
134 value |= Wire.read();
135
136 return value;
137}
138
139
140/**************************************************************************/
141/*!
142 @brief Reads the factory-set coefficients
143*/
144/**************************************************************************/
145void BME280::readCoefficients(void)
146{
147 _bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1);
148 _bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2);
149 _bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3);
150
151 _bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1);
152 _bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2);
153 _bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3);
154 _bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4);
155 _bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5);
156 _bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6);
157 _bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7);
158 _bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8);
159 _bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9);
160
161 _bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1);
162 _bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2);
163 _bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3);
164 _bme280_calib.dig_H4 = (read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4+1) & 0xF);
165 _bme280_calib.dig_H5 = (read8(BME280_REGISTER_DIG_H5+1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4);
166 _bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6);
167}
168
169/**************************************************************************/
170/*!
171
172*/
173/**************************************************************************/
174float BME280::temperature(void)
175{
176 int32_t var1, var2;
177
178 int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
179 adc_T >>= 4;
180
181 var1 = ((((adc_T>>3) - ((int32_t)_bme280_calib.dig_T1 <<1))) *
182 ((int32_t)_bme280_calib.dig_T2)) >> 11;
183
184 var2 = (((((adc_T>>4) - ((int32_t)_bme280_calib.dig_T1)) *
185 ((adc_T>>4) - ((int32_t)_bme280_calib.dig_T1))) >> 12) *
186 ((int32_t)_bme280_calib.dig_T3)) >> 14;
187
188 t_fine = var1 + var2;
189
190 float T = (t_fine * 5 + 128) >> 8;
191 return T/100;
192}
193
194/**************************************************************************/
195/*!
196
197*/
198/**************************************************************************/
199float BME280::pressure(void) {
200 int64_t var1, var2, p;
201
202 temperature(); // must be done first to get t_fine
203
204 int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA);
205 adc_P >>= 4;
206
207 var1 = ((int64_t)t_fine) - 128000;
208 var2 = var1 * var1 * (int64_t)_bme280_calib.dig_P6;
209 var2 = var2 + ((var1*(int64_t)_bme280_calib.dig_P5)<<17);
210 var2 = var2 + (((int64_t)_bme280_calib.dig_P4)<<35);
211 var1 = ((var1 * var1 * (int64_t)_bme280_calib.dig_P3)>>8) +
212 ((var1 * (int64_t)_bme280_calib.dig_P2)<<12);
213 var1 = (((((int64_t)1)<<47)+var1))*((int64_t)_bme280_calib.dig_P1)>>33;
214
215 if (var1 == 0) {
216 return 0; // avoid exception caused by division by zero
217 }
218 p = 1048576 - adc_P;
219 p = (((p<<31) - var2)*3125) / var1;
220 var1 = (((int64_t)_bme280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25;
221 var2 = (((int64_t)_bme280_calib.dig_P8) * p) >> 19;
222
223 p = ((p + var1 + var2) >> 8) + (((int64_t)_bme280_calib.dig_P7)<<4);
224 return (float)p/256;
225}
226
227
228/**************************************************************************/
229/*!
230
231*/
232/**************************************************************************/
233float BME280::humidity(void) {
234
235 temperature(); // must be done first to get t_fine
236
237 int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA);
238
239 int32_t v_x1_u32r;
240
241 v_x1_u32r = (t_fine - ((int32_t)76800));
242
243 v_x1_u32r = (((((adc_H << 14) - (((int32_t)_bme280_calib.dig_H4) << 20) -
244 (((int32_t)_bme280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
245 (((((((v_x1_u32r * ((int32_t)_bme280_calib.dig_H6)) >> 10) *
246 (((v_x1_u32r * ((int32_t)_bme280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) +
247 ((int32_t)2097152)) * ((int32_t)_bme280_calib.dig_H2) + 8192) >> 14));
248
249 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
250 ((int32_t)_bme280_calib.dig_H1)) >> 4));
251
252 v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
253 v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
254 float h = (v_x1_u32r>>12);
255 return h / 1024.0;
256}
257
258/**************************************************************************/
259/*!
260 Calculates the altitude (in meters) from the specified atmospheric
261 pressure (in hPa), and sea-level pressure (in hPa).
262
263 @param seaLevel Sea-level pressure in hPa
264 @param atmospheric Atmospheric pressure in hPa
265*/
266/**************************************************************************/
267float BME280::altitude(float seaLevel)
268{
269 // Equation taken from BMP180 datasheet (page 16):
270 // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
271
272 // Note that using the equation from wikipedia can give bad results
273 // at high altitude. See this thread for more information:
274 // http://forums.adafruit.com/viewtopic.php?f=22&t=58064
275
276 float atmospheric = pressure() / 100.0F;
277 return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
278}
279
280BME280 bme280;
Note: See TracBrowser for help on using the repository browser.