4
4
# This libraries are adapted from :bme280.rb => lukasjapan/i2c-bme280.
5
5
# https://github.com/lukasjapan/i2c-bme280
6
6
#
7
- # refer to BST-BME280_DS001-12 .pdf
8
- # https://ae-bst.resource. bosch.com/media/_tech/media /datasheets/BST-BME280_DS001-12 .pdf
7
+ # refer to BST-BME280-DS001-24(bst-bme280-ds002 .pdf)
8
+ # https://www. bosch-sensortec .com/media/boschsensortec/downloads /datasheets/bst-bme280-ds002 .pdf
9
9
#
10
10
11
11
module SENSOR
@@ -22,7 +22,7 @@ def init
22
22
# BME280 register setting
23
23
set_register
24
24
25
- # read trimming parameter
25
+ # read trimming parameter
26
26
read_trim_params
27
27
self
28
28
end
@@ -53,27 +53,59 @@ def humidity
53
53
54
54
private
55
55
56
- # Suggested settings for indoor navigation, BST-BME280_DS001-12.pdf (page: 18)
56
+
57
+
57
58
def set_register
59
+ # IIR filter coefficient
60
+ # filter off => 0b000
61
+ # filter x2 => 0b001
62
+ # filter X4 => 0b010
63
+ # filter x8 => 0b011
64
+ # filter x16 => 0b100
65
+ #
66
+ # oversampling (Temperature, Humidity, Pressure)
67
+ # sampling none => 0b000
68
+ # sampling x1 => 0b001
69
+ # sampling X2 => 0b010
70
+ # sampling x4 => 0b011
71
+ # sampling x8 => 0b100
72
+ # sampling x16 => 0b101
73
+ #
74
+ # sensor mode
75
+ # sleep => 0b00
76
+ # forced => 0b01
77
+ # normal => 0b11
78
+ #
79
+ # standby time [ms]
80
+ # 0.5 => 0b000
81
+ # 62.5 => 0b001
82
+ # 125 => 0b010
83
+ # 250 => 0b011
84
+ # 500 => 0b100
85
+ # 1000 => 0b101
86
+ # 10 => 0b110
87
+ # 20 => 0b111
88
+ #
89
+
58
90
# set config registers
59
91
config_reg = 0xF5 # Register address for config settings
60
92
t_sb = 0b000 # Standby time = 0.5ms (0b000)
61
- filter = 0b100 # filter coefficient = 16
93
+ filter = 0b000 # filter coefficient = OFF
62
94
spi3w_en = 0 # Disable SPI
63
95
config_val = ( t_sb << 5 ) | ( filter << 2 ) | spi3w_en
64
96
write ( config_reg , config_val )
65
97
66
98
# set ctrl_meas registers
67
99
tp_reg = 0xF4 # Register address for temperature/pressure settings
68
- osrs_t = 0b010 # Temperature oversampling = x2 (0b010 )
100
+ osrs_t = 0b101 # Temperature oversampling = x16 (0b101 )
69
101
osrs_p = 0b101 # Pressure oversampling = x16 (0b101)
70
102
mode = 0b11 # Normal mode (0b11)
71
103
tp_val = ( osrs_t << 5 ) | ( osrs_p << 2 ) | mode
72
104
write ( tp_reg , tp_val )
73
105
74
- # set ctrl_hum registers
75
- hum_reg = 0xF2 # Register address for humidity settings
76
- osrs_h = 0b001 # Humidity oversampling = x1 (0b001 )
106
+ # set ctrl_hum registers
107
+ hum_reg = 0xF2 # Register address for humidity settings
108
+ osrs_h = 0b101 # Humidity oversampling = x16 (0b101 )
77
109
hum_val = osrs_h
78
110
write ( hum_reg , hum_val )
79
111
end
@@ -92,7 +124,7 @@ def int8(n)
92
124
end
93
125
94
126
# Read compensation parameters of the BME280
95
- # refer to BST-BME280_DS001-12 .pdf (Page 22 )
127
+ # refer to bst-bme280-ds002 .pdf (Page 24 )
96
128
def read_trim_params
97
129
# compensation parameter register mapping
98
130
Calibration = Struct . new (
@@ -117,16 +149,16 @@ def read_trim_params
117
149
:dig_H6 , # 0xE7 dig_H6 signed char
118
150
:t_fine
119
151
)
120
- calib = [ ]
152
+ calib = [ ]
121
153
122
154
# data addresses
123
155
dig_t_reg = 0x88
124
156
dig_p_reg = 0x8E
125
157
dig_h_reg1 = 0xA1
126
158
dig_h_reg2 = 0xE1
127
-
159
+
128
160
data = read ( dig_t_reg , 6 )
129
- calib << ( ( data [ 1 ] << 8 ) | data [ 0 ] ) # uint16_t dig_T1 [1][0]
161
+ calib << ( ( data [ 1 ] << 8 ) | data [ 0 ] ) # uint16_t dig_T1 [1][0]
130
162
calib << int16 ( data [ 3 ] , data [ 2 ] ) # int16_t dig_T2 [3][2]
131
163
calib << int16 ( data [ 5 ] , data [ 4 ] ) # int16_t dig_T3 [5][4]
132
164
@@ -143,75 +175,76 @@ def read_trim_params
143
175
144
176
data = read ( dig_h_reg1 , 1 )
145
177
calib << data [ 0 ] # uint8_t dig_H1 [0]
146
-
178
+
147
179
data = read ( dig_h_reg2 , 7 )
148
180
calib << int16 ( data [ 1 ] , data [ 0 ] ) # int16_t dig_H2 [1],[0]
149
- calib << data [ 2 ] # uint8_t dig_H3 [2]
181
+ calib << data [ 2 ] # uint8_t dig_H3 [2]
150
182
151
183
# 109876543210 bit[11:0]
152
184
# xxxxxxxx.... dig_H4_msb [11:4] [3]
153
185
# ....xxxx dig_H4_lsb [3:0] [4]
154
- # xxxxxxxxxxxx dig_H4 [11:0]
186
+ # xxxxxxxxxxxx dig_H4 [11:0]
155
187
dig_H4_msb = ( data [ 3 ] >> 4 ) & 0x0F
156
- dig_H4_lsb = ( ( data [ 3 ] << 4 ) & 0xF0 ) | ( data [ 4 ] & 0x0F )
188
+ dig_H4_lsb = ( ( data [ 3 ] << 4 ) & 0xF0 ) | ( data [ 4 ] & 0x0F )
157
189
calib << int16 ( dig_H4_msb , dig_H4_lsb ) # int16_t dig_H4 [3][4]
158
-
190
+
159
191
# 109876543210 bit[11:0]
160
192
# xxxxxxxx.... dig_H5_msb [11:4] [5]
161
193
# xxxx.... dig_H5_lsb [7:4] [4]
162
194
# xxxxxxxxxxxx dig_H5 [11:0]
163
195
dig_H5_msb = ( data [ 5 ] >> 4 ) & 0x0F
164
- dig_H5_lsb = ( ( data [ 5 ] << 4 ) & 0xF0 ) | ( data [ 4 ] >> 4 )
196
+ dig_H5_lsb = ( ( data [ 5 ] << 4 ) & 0xF0 ) | ( data [ 4 ] >> 4 )
165
197
calib << int16 ( dig_H5_msb , dig_H5_lsb ) # int16_t dig_H5 [4][5]
166
-
198
+
167
199
calib << int8 ( data [ 6 ] ) # int8_t dig_H6 [6]
168
200
169
201
@calib = Calibration . new ( *calib )
170
202
end
171
203
172
- # compensate temperature
173
- # refer to BST-BME280_DS001-12 .pdf (page: 23 )
204
+ # compensate temperature
205
+ # refer to bst-bme280-ds002 .pdf (page: 49 )
174
206
def trim_t ( adc_T )
175
- var1 = ( ( ( ( adc_T >> 3 ) - ( @calib [ :dig_T1 ] << 1 ) ) ) * @calib [ :dig_T2 ] ) >> 11
176
- var2 = ( ( ( ( ( adc_T >> 4 ) - @calib [ :dig_T1 ] ) * ( ( adc_T >> 4 ) - @calib [ :dig_T1 ] ) ) >> 12 ) * @calib [ :dig_T3 ] ) >> 14
207
+ var1 = ( adc_T / 16384.0 - @calib [ :dig_T1 ] / 1024.0 ) * @calib [ :dig_T2 ]
208
+ var2 = ( ( adc_T / 131072.0 - @calib [ :dig_T1 ] / 8192.0 ) * ( adc_T / 131072.0 - @calib [ :dig_T1 ] / 8192.0 ) ) * @calib [ :dig_T3 ]
177
209
@calib [ :t_fine ] = var1 + var2
178
- t = ( ( @calib [ :t_fine ] * 5 + 128 ) >> 8 ) / 100
210
+ t = @calib [ :t_fine ] / 5120.0
179
211
end
180
212
181
213
# compensate pressure
182
- # refer to BST-BME280_DS001-12 .pdf (page: 50 )
214
+ # refer to bst-bme280-ds002 .pdf (page: 49 )
183
215
def trim_p ( adc_P )
184
- var1 = ( @calib [ :t_fine ] >> 1 ) - 64000
185
- var2 = ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 11 ) * @calib [ :dig_P6 ]
186
- var2 = var2 + ( ( var1 * @calib [ :dig_P5 ] ) << 1 )
187
- var2 = ( var2 >> 2 ) + ( @calib [ :dig_P4 ] << 16 )
188
- var1 = ( ( ( @calib [ :dig_P3 ] * ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 13 ) ) >> 3 ) + ( ( @calib [ :dig_P2 ] * var1 ) >> 1 ) ) >> 18
189
- var1 = ( ( 0x8000 + var1 ) * @calib [ :dig_P1 ] ) >> 15
216
+ var1 = ( @calib [ :t_fine ] / 2.0 ) - 64000.0
217
+ var2 = var1 * var1 / 32768.0 * @calib [ :dig_P6 ]
218
+ var2 = var2 + ( ( var1 * @calib [ :dig_P5 ] ) * 2.0 )
219
+ var2 = ( var2 / 4.0 ) + ( @calib [ :dig_P4 ] * 65536.0 )
220
+ var1 = ( @calib [ :dig_P3 ] * var1 * var1 / 524288.0 + @calib [ :dig_P2 ] * var1 ) / 524288.0
221
+ var1 = ( 1.0 + var1 / 32768.0 ) * @calib [ :dig_P1 ]
190
222
191
223
if var1 == 0
192
224
p = 0.0
193
225
else
194
- p = ( 0x100000 - adc_P - ( var2 >> 12 ) ) * 3125
195
- p = ( p << 1 ) / var1
196
- var1 = ( @calib [ :dig_P9 ] * ( ( p >> 3 ) * ( p >> 3 ) ) >> 13 ) >> 12
197
- var2 = ( ( p >> 2 ) * @calib [ :dig_P8 ] ) >> 13
198
- p = p + ( ( var1 + var2 + @calib [ :dig_P7 ] ) >> 4 )
199
- p /= 100
226
+ p = 1048576.0 - adc_P
227
+ p = ( p - ( var2 / 4096.0 ) ) * 6250.0 / var1
228
+ var1 = @calib [ :dig_P9 ] * p * p / 2147483648.0
229
+ var2 = p * @calib [ :dig_P8 ] / 32768.0
230
+ p = p + ( var1 + var2 + @calib [ :dig_P7 ] ) / 16.0
231
+ p /= 100.0
200
232
end
201
233
end
202
234
203
235
# compensate humidity
204
- # refer to BST-BME280_DS001-12 .pdf (page: 23)
236
+ # refer to bst-bme280-ds002 .pdf (page: 49)
205
237
def trim_h ( adc_H )
206
- h = @calib [ :t_fine ] - 76800
207
- h = ( ( ( ( adc_H << 14 ) - ( @calib [ :dig_H4 ] << 20 ) - ( @calib [ :dig_H5 ] * h ) ) + 0x4000 ) >> 15 ) *
208
- ( ( ( ( ( ( ( h * ( @calib [ :dig_H6 ] ) ) >> 10 ) * ( ( ( h * @calib [ :dig_H3 ] ) >> 11 ) + 0x8000 ) ) >> 10 ) + 0x200000 ) * @calib [ :dig_H2 ] + 0x2000 ) >> 14 )
209
- h = h - ( ( ( ( ( h >> 15 ) * ( h >> 15 ) ) >> 7 ) * @calib [ :dig_H1 ] ) >> 4 )
210
- h = h < 0 ? 0 : h
211
- h = h > 419430400 ? 419430400 : h
212
- h = ( h >> 12 ) / 1024
213
- end
214
-
238
+ h = @calib [ :t_fine ] - 76800.0
239
+ h1 = adc_H - ( @calib [ :dig_H4 ] * 64.0 + @calib [ :dig_H5 ] / 16384.0 * h )
240
+ h2 = @calib [ :dig_H2 ] / 65536.0 * ( 1.0 + @calib [ :dig_H6 ] / 67108864.0 * h * ( 1.0 + @calib [ :dig_H3 ] / 67108864.0 * h ) )
241
+ h = h1 * h2
242
+ h = h * ( 1.0 - @calib [ :dig_H1 ] * h / 524288.0 )
243
+ h = 100.0 if h > 100.0
244
+ h = 0.0 if h < 0.0
245
+ h
246
+ end
247
+
215
248
# Measurement of temperature, pressure and humidity
216
249
# return all compensated values
217
250
def data
@@ -225,8 +258,8 @@ def data
225
258
# Apply compensation to received ADC data and return as hash
226
259
{
227
260
t : trim_t ( adc_T ) ,
228
- p : trim_p ( adc_P ) . round ( 2 ) ,
229
- h : trim_h ( adc_H ) . round ( 2 )
261
+ p : trim_p ( adc_P ) ,
262
+ h : trim_h ( adc_H )
230
263
}
231
264
end
232
265
@@ -240,6 +273,6 @@ def write(reg_address, data)
240
273
def read ( reg_address , size = 1 )
241
274
receive ( reg_address , size , @addr )
242
275
end
243
-
276
+
244
277
end
245
278
end
0 commit comments