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 )