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

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

1.7.10のファイルに更新

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