Device-Chip-BME280
view release on metacpan or search on metacpan
lib/Device/Chip/BME280.pm view on Meta::CPAN
my $bytes = pack_config( %$config, %changes );
# Don't write REG_STATUS
await $self->cached_write_reg( REG_CTRL_HUM, substr( $bytes, 0, 1 ) );
await $self->cached_write_reg( REG_CTRL_MEAS, substr( $bytes, 2, 2 ) );
}
async method initialize_sensors ()
{
await $self->change_config(
MODE => "NORMAL",
OSRS_H => 4,
OSRS_P => 4,
OSRS_T => 4,
FILTER => 4,
);
# First read after startup contains junk values
await $self->read_sensor;
}
=head2 read_status
$status = await $chip->read_status;
=cut
async method read_status ()
{
my $byte = await $self->read_reg( REG_STATUS, 1 );
return {
MEASURING => !!( $byte & (1<<3) ),
IM_UPDATE => !!( $byte & (1<<0) ),
};
}
=head2 read_raw
( $adc_P, $adc_T, $adc_H ) = await $chip->read_raw;
Returns three integers containing the raw ADC reading values from the sensor.
This method is mostly for testing or internal purposes only. For converted
sensor readings in real-world units you want to use L</read_sensor>.
=cut
async method read_raw ()
{
my ( $bytesP, $bytesT, $bytesH ) = unpack "a3 a3 a2",
await $self->read_reg( REG_PRESS, 8 );
return (
unpack( "L>", "\x00" . $bytesP ) >> 4,
unpack( "L>", "\x00" . $bytesT ) >> 4,
unpack( "S>", $bytesH ),
);
}
# Compensation formulae directly from BME280 datasheet section 8.1
field $_t_fine;
field @_dig_T;
async method _compensate_temperature ( $adc_T )
{
@_dig_T or
@_dig_T = ( undef, unpack "S< s< s<", await $self->read_reg( REG_DIG_T1, 6 ) );
my $var1 = ($adc_T / 16384 - $_dig_T[1] / 1024) * $_dig_T[2];
my $var2 = ($adc_T / 131072 - $_dig_T[1] / 8192) ** 2 * $_dig_T[3];
$_t_fine = int( $var1 + $var2 );
my $T = ( $var1 + $var2 ) / 5120.0;
return $T;
}
field @_dig_P;
async method _compensate_pressure ( $adc_P )
{
@_dig_P or
@_dig_P = ( undef, unpack "S< s< s< s< s< s< s< s< s<", await $self->read_reg( REG_DIG_P1, 18 ) );
my $var1 = ($_t_fine / 2) - 64000;
my $var2 = $var1 * $var1 * $_dig_P[6] / 32768;
$var2 = $var2 + $var1 * $_dig_P[5] * 2;
$var2 = ($var2 / 4) + ($_dig_P[4] * 65536);
$var1 = ($_dig_P[3] * $var1 * $var1 / 524288 + $_dig_P[2] * $var1) / 524288;
$var1 = (1 + $var1 / 32768) * $_dig_P[1];
return 0 if $var1 == 0; # avoid exception caused by divide-by-zero
my $P = 1048576 - $adc_P;
$P = ($P - ($var2 / 4096)) * 6250 / $var1;
$var1 = $_dig_P[9] * $P * $P / 2147483648;
$var2 = $P * $_dig_P[8] / 32768;
$P = $P + ($var1 + $var2 + $_dig_P[7]) / 16;
return $P;
}
field @_dig_H;
async method _compensate_humidity ( $adc_H )
{
unless( @_dig_H ) {
@_dig_H = (
undef,
unpack( "C", await $self->read_reg( REG_DIG_H1, 1 ) ),
unpack( "s< C ccc c", await $self->read_reg( REG_DIG_H2, 7 ) ),
);
# Reshape the two 12bit values
my ( $b0, $b1, $b2 ) = splice @_dig_H, 4, 3;
splice @_dig_H, 4, 0,
( $b0 << 4 | $b1 & 0x0F ), # H4
( $b1 >> 4 | $b2 << 4 ); # H5
}
my $var_H = $_t_fine - 76800;
$var_H = ($adc_H - ($_dig_H[4] * 64.0 + $_dig_H[5] / 16384.0 * $var_H)) *
($_dig_H[2] / 65536.0 * (1.0 + $_dig_H[6] / 67108864.0 * $var_H * (1.0 + $_dig_H[3] / 67108864.0 * $var_H)));
( run in 0.610 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )