line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2020-2023 -- leonerd@leonerd.org.uk |
5
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
1024578
|
use v5.26; |
|
5
|
|
|
|
|
47
|
|
7
|
5
|
|
|
5
|
|
29
|
use warnings; |
|
5
|
|
|
|
|
7
|
|
|
5
|
|
|
|
|
136
|
|
8
|
5
|
|
|
5
|
|
560
|
use Object::Pad 0.800; |
|
5
|
|
|
|
|
8993
|
|
|
5
|
|
|
|
|
222
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package Device::Chip::BME280 0.06; |
11
|
|
|
|
|
|
|
class Device::Chip::BME280 |
12
|
5
|
|
|
5
|
|
2597
|
:isa(Device::Chip::Base::RegisteredI2C); |
|
5
|
|
|
|
|
28626
|
|
|
5
|
|
|
|
|
158
|
|
13
|
|
|
|
|
|
|
|
14
|
5
|
|
|
5
|
|
2601
|
use Device::Chip::Sensor 0.23 -declare; |
|
5
|
|
|
|
|
12312
|
|
|
5
|
|
|
|
|
21
|
|
15
|
|
|
|
|
|
|
|
16
|
5
|
|
|
5
|
|
2476
|
use Data::Bitfield qw( bitfield enumfield boolfield ); |
|
5
|
|
|
|
|
9087
|
|
|
5
|
|
|
|
|
319
|
|
17
|
5
|
|
|
5
|
|
33
|
use Future::AsyncAwait; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
24
|
|
18
|
|
|
|
|
|
|
|
19
|
5
|
|
|
5
|
|
242
|
use utf8; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
22
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=encoding UTF-8 |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 NAME |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
C - chip driver for F |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 SYNOPSIS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use Device::Chip::BME280; |
30
|
|
|
|
|
|
|
use Future::AsyncAwait; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $chip = Device::Chip::BME280->new; |
33
|
|
|
|
|
|
|
await $chip->mount( Device::Chip::Adapter::...->new ); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
await $chip->change_config( |
36
|
|
|
|
|
|
|
OSRS_H => 4, |
37
|
|
|
|
|
|
|
OSRS_P => 4, |
38
|
|
|
|
|
|
|
OSRS_T => 4, |
39
|
|
|
|
|
|
|
MODE => "NORMAL", |
40
|
|
|
|
|
|
|
); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
my ( $pressure, $temperature, $humidity ) = await $chip->read_sensor; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
printf "Temperature=%.2fC ", $temperature; |
45
|
|
|
|
|
|
|
printf "Pressure=%dPa ", $pressure; |
46
|
|
|
|
|
|
|
printf "Humidity=%.2f%%\n", $humidity; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 DESCRIPTION |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
This L subclass provides specific communication to a F |
51
|
|
|
|
|
|
|
F attached to a computer via an I²C adapter. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
The reader is presumed to be familiar with the general operation of this chip; |
54
|
|
|
|
|
|
|
the documentation here will not attempt to explain or define chip-specific |
55
|
|
|
|
|
|
|
concepts or features, only the use of this module to access them. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=cut |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
method I2C_options |
60
|
4
|
|
|
4
|
0
|
1495
|
{ |
61
|
|
|
|
|
|
|
return ( |
62
|
4
|
|
|
|
|
22
|
addr => 0x76, |
63
|
|
|
|
|
|
|
max_bitrate => 400E3, |
64
|
|
|
|
|
|
|
); |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
use constant { |
68
|
5
|
|
|
|
|
15776
|
REG_DIG_T1 => 0x88, |
69
|
|
|
|
|
|
|
REG_DIG_P1 => 0x8E, |
70
|
|
|
|
|
|
|
REG_DIG_H1 => 0xA1, |
71
|
|
|
|
|
|
|
REG_ID => 0xD0, |
72
|
|
|
|
|
|
|
REG_RESET => 0xE0, |
73
|
|
|
|
|
|
|
REG_DIG_H2 => 0xE1, |
74
|
|
|
|
|
|
|
REG_CTRL_HUM => 0xF2, |
75
|
|
|
|
|
|
|
REG_STATUS => 0xF3, |
76
|
|
|
|
|
|
|
REG_CTRL_MEAS => 0xF4, |
77
|
|
|
|
|
|
|
REG_CONFIG => 0xF5, |
78
|
|
|
|
|
|
|
REG_PRESS => 0xF7, # 24bit |
79
|
|
|
|
|
|
|
REG_TEMP => 0xFA, # 24bit |
80
|
|
|
|
|
|
|
REG_HUM => 0xFD, |
81
|
5
|
|
|
5
|
|
733
|
}; |
|
5
|
|
|
|
|
10
|
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
bitfield { format => "bytes-LE" }, config => |
84
|
|
|
|
|
|
|
# REG_CTRL_HUM |
85
|
|
|
|
|
|
|
OSRS_H => enumfield( 0, qw( SKIP 1 2 4 8 16 16 16 ) ), |
86
|
|
|
|
|
|
|
# REG_CTRL_MEAS |
87
|
|
|
|
|
|
|
MODE => enumfield( 2*8+0, qw( SLEEP FORCED FORCED NORMAL ) ), |
88
|
|
|
|
|
|
|
OSRS_P => enumfield( 2*8+2, qw( SKIP 1 2 4 8 16 16 16 ) ), |
89
|
|
|
|
|
|
|
OSRS_T => enumfield( 2*8+5, qw( SKIP 1 2 4 8 16 16 16 ) ), |
90
|
|
|
|
|
|
|
# REG_CONFIG |
91
|
|
|
|
|
|
|
SPI3W_EN => boolfield( 3*8+0 ), |
92
|
|
|
|
|
|
|
FILTER => enumfield( 3*8+2, qw( OFF 2 4 8 16 16 16 16 ) ), |
93
|
|
|
|
|
|
|
T_SB => enumfield( 3*8+5, qw( 0.5 62.5 125 250 500 1000 10 20 ) ); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 METHODS |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
The following methods documented in an C expression return L |
98
|
|
|
|
|
|
|
instances. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=cut |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head2 read_id |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$id = await $chip->read_id |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Returns the chip ID. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
async method read_id |
111
|
1
|
|
|
|
|
3
|
{ |
112
|
1
|
|
|
|
|
7
|
return unpack "C", await $self->read_reg( REG_ID, 1 ); |
113
|
1
|
|
|
1
|
1
|
267
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head2 read_config |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
$config = await $chip->read_config |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Returns a C reference containing the chip config, using fields named |
120
|
|
|
|
|
|
|
from the data sheet. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
FILTER => OFF | 2 | 4 | 8 | 16 |
123
|
|
|
|
|
|
|
MODE => SLEEP | FORCED | NORMAL |
124
|
|
|
|
|
|
|
OSRS_H => SKIP | 1 | 2 | 4 | 8 | 16 |
125
|
|
|
|
|
|
|
OSRS_P => SKIP | 1 | 2 | 4 | 8 | 16 |
126
|
|
|
|
|
|
|
OSRS_T => SKIP | 1 | 2 | 4 | 8 | 16 |
127
|
|
|
|
|
|
|
SPI3W_EN => 0 | 1 |
128
|
|
|
|
|
|
|
T_SB => 0.5 | 10 | 20 | 62.5 | 125 | 250 | 500 | 1000 |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=cut |
131
|
|
|
|
|
|
|
|
132
|
5
|
|
|
|
|
8
|
async method read_config () |
|
5
|
|
|
|
|
6
|
|
133
|
5
|
|
|
|
|
13
|
{ |
134
|
5
|
|
|
|
|
22
|
my $bytes = await $self->cached_read_reg( REG_CTRL_HUM, 4 ); |
135
|
|
|
|
|
|
|
|
136
|
5
|
|
|
|
|
18508
|
return { unpack_config( $bytes ) }; |
137
|
5
|
|
|
5
|
1
|
3787
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=head2 change_config |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
await $chip->change_config( %changes ) |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Writes updates to the configuration registers. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Note that these two methods use a cache of configuration bytes to make |
146
|
|
|
|
|
|
|
subsequent modifications more efficient. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=cut |
149
|
|
|
|
|
|
|
|
150
|
1
|
|
|
|
|
2
|
async method change_config ( %changes ) |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
2
|
|
151
|
1
|
|
|
|
|
3
|
{ |
152
|
1
|
|
|
|
|
2
|
my $config = await $self->read_config; |
153
|
|
|
|
|
|
|
|
154
|
1
|
|
|
|
|
102
|
my $bytes = pack_config( %$config, %changes ); |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Don't write REG_STATUS |
157
|
1
|
|
|
|
|
164
|
await $self->cached_write_reg( REG_CTRL_HUM, substr( $bytes, 0, 1 ) ); |
158
|
1
|
|
|
|
|
1733
|
await $self->cached_write_reg( REG_CTRL_MEAS, substr( $bytes, 2, 2 ) ); |
159
|
1
|
|
|
1
|
1
|
3378
|
} |
160
|
|
|
|
|
|
|
|
161
|
0
|
|
|
|
|
0
|
async method initialize_sensors () |
|
0
|
|
|
|
|
0
|
|
162
|
0
|
|
|
|
|
0
|
{ |
163
|
0
|
|
|
|
|
0
|
await $self->change_config( |
164
|
|
|
|
|
|
|
MODE => "NORMAL", |
165
|
|
|
|
|
|
|
OSRS_H => 4, |
166
|
|
|
|
|
|
|
OSRS_P => 4, |
167
|
|
|
|
|
|
|
OSRS_T => 4, |
168
|
|
|
|
|
|
|
FILTER => 4, |
169
|
|
|
|
|
|
|
); |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# First read after startup contains junk values |
172
|
0
|
|
|
|
|
0
|
await $self->read_sensor; |
173
|
0
|
|
|
0
|
0
|
0
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=head2 read_status |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
$status = await $chip->read_status; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=cut |
180
|
|
|
|
|
|
|
|
181
|
0
|
|
|
|
|
0
|
async method read_status () |
|
0
|
|
|
|
|
0
|
|
182
|
0
|
|
|
|
|
0
|
{ |
183
|
0
|
|
|
|
|
0
|
my $byte = await $self->read_reg( REG_STATUS, 1 ); |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
return { |
186
|
0
|
|
|
|
|
0
|
MEASURING => !!( $byte & (1<<3) ), |
187
|
|
|
|
|
|
|
IM_UPDATE => !!( $byte & (1<<0) ), |
188
|
|
|
|
|
|
|
}; |
189
|
0
|
|
|
0
|
1
|
0
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 read_raw |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
( $adc_P, $adc_T, $adc_H ) = await $chip->read_raw |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
Returns three integers containing the raw ADC reading values from the sensor. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
This method is mostly for testing or internal purposes only. For converted |
198
|
|
|
|
|
|
|
sensor readings in real-world units you want to use L. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=cut |
201
|
|
|
|
|
|
|
|
202
|
8
|
|
|
|
|
19
|
async method read_raw () |
|
8
|
|
|
|
|
10
|
|
203
|
8
|
|
|
|
|
14
|
{ |
204
|
8
|
|
|
|
|
31
|
my ( $bytesP, $bytesT, $bytesH ) = unpack "a3 a3 a2", |
205
|
|
|
|
|
|
|
await $self->read_reg( REG_PRESS, 8 ); |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
return ( |
208
|
7
|
|
|
|
|
14093
|
unpack( "L>", "\x00" . $bytesP ) >> 4, |
209
|
|
|
|
|
|
|
unpack( "L>", "\x00" . $bytesT ) >> 4, |
210
|
|
|
|
|
|
|
unpack( "S>", $bytesH ), |
211
|
|
|
|
|
|
|
); |
212
|
8
|
|
|
8
|
1
|
299
|
} |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# Compensation formulae directly from BME280 datasheet section 8.1 |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
field $_t_fine; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
field @_dig_T; |
219
|
|
|
|
|
|
|
|
220
|
10
|
|
|
|
|
15
|
async method _compensate_temperature ( $adc_T ) |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
11
|
|
221
|
10
|
|
|
|
|
30
|
{ |
222
|
10
|
100
|
|
|
|
27
|
@_dig_T or |
223
|
|
|
|
|
|
|
@_dig_T = ( undef, unpack "S< s< s<", await $self->read_reg( REG_DIG_T1, 6 ) ); |
224
|
|
|
|
|
|
|
|
225
|
10
|
|
|
|
|
2631
|
my $var1 = ($adc_T / 16384 - $_dig_T[1] / 1024) * $_dig_T[2]; |
226
|
10
|
|
|
|
|
36
|
my $var2 = ($adc_T / 131072 - $_dig_T[1] / 8192) ** 2 * $_dig_T[3]; |
227
|
|
|
|
|
|
|
|
228
|
10
|
|
|
|
|
21
|
$_t_fine = int( $var1 + $var2 ); |
229
|
10
|
|
|
|
|
18
|
my $T = ( $var1 + $var2 ) / 5120.0; |
230
|
10
|
|
|
|
|
58
|
return $T; |
231
|
10
|
|
|
10
|
|
18
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
field @_dig_P; |
234
|
|
|
|
|
|
|
|
235
|
4
|
|
|
|
|
7
|
async method _compensate_pressure ( $adc_P ) |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
5
|
|
236
|
4
|
|
|
|
|
13
|
{ |
237
|
4
|
100
|
|
|
|
20
|
@_dig_P or |
238
|
|
|
|
|
|
|
@_dig_P = ( undef, unpack "S< s< s< s< s< s< s< s< s<", await $self->read_reg( REG_DIG_P1, 18 ) ); |
239
|
|
|
|
|
|
|
|
240
|
4
|
|
|
|
|
2526
|
my $var1 = ($_t_fine / 2) - 64000; |
241
|
4
|
|
|
|
|
11
|
my $var2 = $var1 * $var1 * $_dig_P[6] / 32768; |
242
|
4
|
|
|
|
|
11
|
$var2 = $var2 + $var1 * $_dig_P[5] * 2; |
243
|
4
|
|
|
|
|
9
|
$var2 = ($var2 / 4) + ($_dig_P[4] * 65536); |
244
|
4
|
|
|
|
|
11
|
$var1 = ($_dig_P[3] * $var1 * $var1 / 524288 + $_dig_P[2] * $var1) / 524288; |
245
|
4
|
|
|
|
|
8
|
$var1 = (1 + $var1 / 32768) * $_dig_P[1]; |
246
|
4
|
50
|
|
|
|
14
|
return 0 if $var1 == 0; # avoid exception caused by divide-by-zero |
247
|
4
|
|
|
|
|
9
|
my $P = 1048576 - $adc_P; |
248
|
4
|
|
|
|
|
10
|
$P = ($P - ($var2 / 4096)) * 6250 / $var1; |
249
|
4
|
|
|
|
|
9
|
$var1 = $_dig_P[9] * $P * $P / 2147483648; |
250
|
4
|
|
|
|
|
8
|
$var2 = $P * $_dig_P[8] / 32768; |
251
|
4
|
|
|
|
|
19
|
$P = $P + ($var1 + $var2 + $_dig_P[7]) / 16; |
252
|
4
|
|
|
|
|
20
|
return $P; |
253
|
4
|
|
|
4
|
|
7
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
field @_dig_H; |
256
|
|
|
|
|
|
|
|
257
|
4
|
|
|
|
|
6
|
async method _compensate_humidity ( $adc_H ) |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
6
|
|
258
|
4
|
|
|
|
|
10
|
{ |
259
|
4
|
100
|
|
|
|
38
|
unless( @_dig_H ) { |
260
|
2
|
|
|
|
|
9
|
@_dig_H = ( |
261
|
|
|
|
|
|
|
undef, |
262
|
|
|
|
|
|
|
unpack( "C", await $self->read_reg( REG_DIG_H1, 1 ) ), |
263
|
|
|
|
|
|
|
unpack( "s< C ccc c", await $self->read_reg( REG_DIG_H2, 7 ) ), |
264
|
|
|
|
|
|
|
); |
265
|
|
|
|
|
|
|
# Reshape the two 12bit values |
266
|
2
|
|
|
|
|
4899
|
my ( $b0, $b1, $b2 ) = splice @_dig_H, 4, 3; |
267
|
2
|
|
|
|
|
10
|
splice @_dig_H, 4, 0, |
268
|
|
|
|
|
|
|
( $b0 << 4 | $b1 & 0x0F ), # H4 |
269
|
|
|
|
|
|
|
( $b1 >> 4 | $b2 << 4 ); # H5 |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
4
|
|
|
|
|
8
|
my $var_H = $_t_fine - 76800; |
273
|
4
|
|
|
|
|
23
|
$var_H = ($adc_H - ($_dig_H[4] * 64.0 + $_dig_H[5] / 16384.0 * $var_H)) * |
274
|
|
|
|
|
|
|
($_dig_H[2] / 65536.0 * (1.0 + $_dig_H[6] / 67108864.0 * $var_H * (1.0 + $_dig_H[3] / 67108864.0 * $var_H))); |
275
|
4
|
|
|
|
|
10
|
$var_H = $var_H * (1.0 - $_dig_H[1] * $var_H / 524288.0); |
276
|
|
|
|
|
|
|
|
277
|
4
|
50
|
|
|
|
12
|
return 0 if $var_H < 0; |
278
|
4
|
50
|
|
|
|
12
|
return 100 if $var_H > 100; |
279
|
4
|
|
|
|
|
15
|
return $var_H; |
280
|
4
|
|
|
4
|
|
68
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 read_sensor |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
( $pressure, $temperature, $humidity ) = await $chip->read_sensor |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Returns the sensor readings appropriately converted into units of Pascals for |
287
|
|
|
|
|
|
|
pressure, degrees Celcius for temperature, and percentage relative for |
288
|
|
|
|
|
|
|
humidity. |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=cut |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
async method read_sensor |
293
|
1
|
|
|
|
|
3
|
{ |
294
|
1
|
|
|
|
|
3
|
my ( $adc_P, $adc_T, $adc_H ) = await $self->read_raw; |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# Must do temperature first |
297
|
1
|
|
|
|
|
64
|
my $T = await $self->_compensate_temperature( $adc_T ); |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
return ( |
300
|
1
|
|
|
|
|
84
|
await $self->_compensate_pressure( $adc_P ), |
301
|
|
|
|
|
|
|
$T, |
302
|
|
|
|
|
|
|
await $self->_compensate_humidity( $adc_H ), |
303
|
|
|
|
|
|
|
); |
304
|
1
|
|
|
1
|
1
|
4423
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
field $_pending_read_f; |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
method _next_read |
309
|
12
|
|
|
12
|
|
18
|
{ |
310
|
|
|
|
|
|
|
return $_pending_read_f //= |
311
|
12
|
|
66
|
6
|
|
45
|
$self->read_raw->on_ready(sub { undef $_pending_read_f }); |
|
6
|
|
|
|
|
533
|
|
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
declare_sensor pressure => |
315
|
|
|
|
|
|
|
method => async method { |
316
|
|
|
|
|
|
|
my ( $rawP, $rawT, undef ) = await $self->_next_read; |
317
|
|
|
|
|
|
|
$self->_compensate_temperature( $rawT ); |
318
|
|
|
|
|
|
|
return await $self->_compensate_pressure( $rawP ); |
319
|
|
|
|
|
|
|
}, |
320
|
|
|
|
|
|
|
units => "pascals", |
321
|
|
|
|
|
|
|
sanity_bounds => [ 80_000, 120_000 ], |
322
|
|
|
|
|
|
|
precision => 0; |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
declare_sensor temperature => |
325
|
|
|
|
|
|
|
method => async method { |
326
|
|
|
|
|
|
|
my ( undef, $rawT, undef ) = await $self->_next_read; |
327
|
|
|
|
|
|
|
return await $self->_compensate_temperature( $rawT ); |
328
|
|
|
|
|
|
|
}, |
329
|
|
|
|
|
|
|
units => "°C", |
330
|
|
|
|
|
|
|
sanity_bounds => [ -50, 80 ], |
331
|
|
|
|
|
|
|
precision => 2; |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
declare_sensor humidity => |
334
|
|
|
|
|
|
|
method => async method { |
335
|
|
|
|
|
|
|
my ( undef, $rawT, $rawH ) = await $self->_next_read; |
336
|
|
|
|
|
|
|
$self->_compensate_temperature( $rawT ); |
337
|
|
|
|
|
|
|
return await $self->_compensate_humidity( $rawH ); |
338
|
|
|
|
|
|
|
}, |
339
|
|
|
|
|
|
|
units => "%RH", |
340
|
|
|
|
|
|
|
sanity_bounds => [ -1, 101 ], # give it slight headroom beyond the 0-100 range for rounding errors/etc |
341
|
|
|
|
|
|
|
precision => 2; |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=head1 AUTHOR |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
Paul Evans |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=cut |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
0x55AA; |