diff --git a/README.rst b/README.rst index 134772a..6630553 100644 --- a/README.rst +++ b/README.rst @@ -61,20 +61,11 @@ Usage Example import board import time - import adafruit_bme280 + from adafruit_bme280 import basic # Create sensor object, using the board's default I2C bus. i2c = board.I2C() # uses board.SCL and board.SDA - bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) - #or with other sensor address - #bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, address=0x76) - - # OR create sensor object, using the board's default SPI bus. - # SPI setup - # from digitalio import DigitalInOut - #spi = board.SPI() - #bme_cs = digitalio.DigitalInOut(board.D10) - #bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs) + bme280 = basic.Adafruit_BME280_I2C(i2c) # change this to match the location's pressure (hPa) at sea level bme280.sea_level_pressure = 1013.25 diff --git a/adafruit_bme280/__init__.py b/adafruit_bme280/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adafruit_bme280/advanced.py b/adafruit_bme280/advanced.py new file mode 100644 index 0000000..f774c6e --- /dev/null +++ b/adafruit_bme280/advanced.py @@ -0,0 +1,398 @@ +# SPDX-FileCopyrightText: 2017 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +`adafruit_bme280.advanced` +========================================================================================= + +CircuitPython driver from BME280 Temperature, Humidity and Barometric +Pressure sensor + +* Author(s): ladyada, Jose David M. + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit BME280 Temperature, Humidity and Barometric Pressure sensor + `_ (Product ID: 2652) + + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + +* Adafruit's Bus Device library: + https://github.com/adafruit/Adafruit_CircuitPython_BusDevice + +""" +from micropython import const +from adafruit_bme280.basic import Adafruit_BME280 + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BME280.git" + +# I2C ADDRESS/BITS/SETTINGS +# ----------------------------------------------------------------------- +_BME280_ADDRESS = const(0x77) +_BME280_CHIPID = const(0x60) + +_BME280_REGISTER_CHIPID = const(0xD0) +_BME280_REGISTER_DIG_T1 = const(0x88) +_BME280_REGISTER_DIG_H1 = const(0xA1) +_BME280_REGISTER_DIG_H2 = const(0xE1) +_BME280_REGISTER_DIG_H3 = const(0xE3) +_BME280_REGISTER_DIG_H4 = const(0xE4) +_BME280_REGISTER_DIG_H5 = const(0xE5) +_BME280_REGISTER_DIG_H6 = const(0xE7) + +_BME280_REGISTER_SOFTRESET = const(0xE0) +_BME280_REGISTER_CTRL_HUM = const(0xF2) +_BME280_REGISTER_STATUS = const(0xF3) +_BME280_REGISTER_CTRL_MEAS = const(0xF4) +_BME280_REGISTER_CONFIG = const(0xF5) +_BME280_REGISTER_PRESSUREDATA = const(0xF7) +_BME280_REGISTER_TEMPDATA = const(0xFA) +_BME280_REGISTER_HUMIDDATA = const(0xFD) + +_BME280_HUMIDITY_MIN = const(0) +_BME280_HUMIDITY_MAX = const(100) + +"""iir_filter values""" +IIR_FILTER_DISABLE = const(0) +IIR_FILTER_X2 = const(0x01) +IIR_FILTER_X4 = const(0x02) +IIR_FILTER_X8 = const(0x03) +IIR_FILTER_X16 = const(0x04) + +_BME280_IIR_FILTERS = ( + IIR_FILTER_DISABLE, + IIR_FILTER_X2, + IIR_FILTER_X4, + IIR_FILTER_X8, + IIR_FILTER_X16, +) + +"""overscan values for temperature, pressure, and humidity""" +OVERSCAN_DISABLE = const(0x00) +OVERSCAN_X1 = const(0x01) +OVERSCAN_X2 = const(0x02) +OVERSCAN_X4 = const(0x03) +OVERSCAN_X8 = const(0x04) +OVERSCAN_X16 = const(0x05) + +_BME280_OVERSCANS = { + OVERSCAN_DISABLE: 0, + OVERSCAN_X1: 1, + OVERSCAN_X2: 2, + OVERSCAN_X4: 4, + OVERSCAN_X8: 8, + OVERSCAN_X16: 16, +} + +"""mode values""" +MODE_SLEEP = const(0x00) +MODE_FORCE = const(0x01) +MODE_NORMAL = const(0x03) + +_BME280_MODES = (MODE_SLEEP, MODE_FORCE, MODE_NORMAL) +""" +standby timeconstant values +TC_X[_Y] where X=milliseconds and Y=tenths of a millisecond +""" +STANDBY_TC_0_5 = const(0x00) # 0.5ms +STANDBY_TC_10 = const(0x06) # 10ms +STANDBY_TC_20 = const(0x07) # 20ms +STANDBY_TC_62_5 = const(0x01) # 62.5ms +STANDBY_TC_125 = const(0x02) # 125ms +STANDBY_TC_250 = const(0x03) # 250ms +STANDBY_TC_500 = const(0x04) # 500ms +STANDBY_TC_1000 = const(0x05) # 1000ms + +_BME280_STANDBY_TCS = ( + STANDBY_TC_0_5, + STANDBY_TC_10, + STANDBY_TC_20, + STANDBY_TC_62_5, + STANDBY_TC_125, + STANDBY_TC_250, + STANDBY_TC_500, + STANDBY_TC_1000, +) + +# pylint: disable=abstract-method +class Adafruit_BME280_Advanced(Adafruit_BME280): + """Driver from BME280 Temperature, Humidity and Barometric Pressure sensor + + .. note:: + The operational range of the BMP280 is 300-1100 hPa. + Pressure measurements outside this range may not be as accurate. + + """ + + # pylint: disable=too-many-instance-attributes + def __init__(self): + """Check the BME280 was found, read the coefficients and enable the sensor""" + self._overscan_humidity = OVERSCAN_X1 + self._overscan_temperature = OVERSCAN_X1 + self._overscan_pressure = OVERSCAN_X16 + self._mode = MODE_SLEEP + self._t_standby = STANDBY_TC_125 + super().__init__() + + @property + def standby_period(self): + """ + Control the inactive period when in Normal mode + Allowed standby periods are the constants STANDBY_TC_* + """ + return self._t_standby + + @standby_period.setter + def standby_period(self, value): + if not value in _BME280_STANDBY_TCS: + raise ValueError("Standby Period '%s' not supported" % (value)) + if self._t_standby == value: + return + self._t_standby = value + self._write_config() + + @property + def overscan_humidity(self): + """ + Humidity Oversampling + Allowed values are the constants OVERSCAN_* + """ + return self._overscan_humidity + + @overscan_humidity.setter + def overscan_humidity(self, value): + if not value in _BME280_OVERSCANS: + raise ValueError("Overscan value '%s' not supported" % (value)) + self._overscan_humidity = value + self._write_ctrl_meas() + + @property + def overscan_temperature(self): + """ + Temperature Oversampling + Allowed values are the constants OVERSCAN_* + """ + return self._overscan_temperature + + @overscan_temperature.setter + def overscan_temperature(self, value): + if not value in _BME280_OVERSCANS: + raise ValueError("Overscan value '%s' not supported" % (value)) + self._overscan_temperature = value + self._write_ctrl_meas() + + @property + def overscan_pressure(self): + """ + Pressure Oversampling + Allowed values are the constants OVERSCAN_* + """ + return self._overscan_pressure + + @overscan_pressure.setter + def overscan_pressure(self, value): + if not value in _BME280_OVERSCANS: + raise ValueError("Overscan value '%s' not supported" % (value)) + self._overscan_pressure = value + self._write_ctrl_meas() + + @property + def iir_filter(self): + """ + Controls the time constant of the IIR filter + Allowed values are the constants IIR_FILTER_* + """ + return self._iir_filter + + @iir_filter.setter + def iir_filter(self, value): + if not value in _BME280_IIR_FILTERS: + raise ValueError("IIR Filter '%s' not supported" % (value)) + self._iir_filter = value + self._write_config() + + @property + def _config(self): + """Value to be written to the device's config register """ + config = 0 + if self.mode == MODE_NORMAL: + config += self._t_standby << 5 + if self._iir_filter: + config += self._iir_filter << 2 + return config + + @property + def _ctrl_meas(self): + """Value to be written to the device's ctrl_meas register """ + ctrl_meas = self.overscan_temperature << 5 + ctrl_meas += self.overscan_pressure << 2 + ctrl_meas += self.mode + return ctrl_meas + + @property + def measurement_time_typical(self): + """Typical time in milliseconds required to complete a measurement in normal mode""" + meas_time_ms = 1.0 + if self.overscan_temperature != OVERSCAN_DISABLE: + meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_temperature) + if self.overscan_pressure != OVERSCAN_DISABLE: + meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.5 + if self.overscan_humidity != OVERSCAN_DISABLE: + meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.5 + return meas_time_ms + + @property + def measurement_time_max(self): + """Maximum time in milliseconds required to complete a measurement in normal mode""" + meas_time_ms = 1.25 + if self.overscan_temperature != OVERSCAN_DISABLE: + meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_temperature) + if self.overscan_pressure != OVERSCAN_DISABLE: + meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.575 + if self.overscan_humidity != OVERSCAN_DISABLE: + meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.575 + return meas_time_ms + + +class Adafruit_BME280_I2C(Adafruit_BME280_Advanced): + """Driver for BME280 connected over I2C + + :param ~busio.I2C i2c: The I2C bus the BME280 is connected to. + :param int address: I2C device address. Defaults to :const:`0x77`. + but another address can be passed in as an argument + + .. note:: + The operational range of the BMP280 is 300-1100 hPa. + Pressure measurements outside this range may not be as accurate. + + **Quickstart: Importing and using the BME280** + + Here is an example of using the :class:`Adafruit_BME280_I2C`. + First you will need to import the libraries to use the sensor + + .. code-block:: python + + import board + from adafruit_bme280 import advanced + + Once this is done you can define your `board.I2C` object and define your sensor object + + .. code-block:: python + + i2c = board.I2C() # uses board.SCL and board.SDA + bme280 = advanced.Adafruit_BME280_I2C(i2c) + + You need to setup the pressure at sea level + + .. code-block:: python + + bme280.sea_level_pressure = 1013.25 + + Now you have access to the :attr:`temperature`, :attr:`relative_humidity` + :attr:`pressure` and :attr:`altitude` attributes + + .. code-block:: python + + temperature = bme280.temperature + relative_humidity = bme280.relative_humidity + pressure = bme280.pressure + altitude = bme280.altitude + + """ + + def __init__(self, i2c, address=_BME280_ADDRESS): + import adafruit_bus_device.i2c_device as i2c_device # pylint: disable=import-outside-toplevel + + self._i2c = i2c_device.I2CDevice(i2c, address) + super().__init__() + + def _read_register(self, register, length): + with self._i2c as i2c: + i2c.write(bytes([register & 0xFF])) + result = bytearray(length) + i2c.readinto(result) + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + with self._i2c as i2c: + i2c.write(bytes([register & 0xFF, value & 0xFF])) + # print("$%02X <= 0x%02X" % (register, value)) + + +class Adafruit_BME280_SPI(Adafruit_BME280_Advanced): + """Driver for BME280 connected over SPI + + :param ~busio.SPI spi: SPI device + :param ~digitalio.DigitalInOut cs: Chip Select + :param int baudrate: Clock rate, default is 100000. Can be changed with :meth:`baudrate` + + .. note:: + The operational range of the BMP280 is 300-1100 hPa. + Pressure measurements outside this range may not be as accurate. + + **Quickstart: Importing and using the BME280** + + Here is an example of using the :class:`Adafruit_BME280_SPI` class. + First you will need to import the libraries to use the sensor + + .. code-block:: python + + import board + from digitalio import DigitalInOut + from adafruit_bme280 import advanced + + Once this is done you can define your `board.SPI` object and define your sensor object + + .. code-block:: python + + cs = digitalio.DigitalInOut(board.D10) + spi = board.SPI() + bme280 = advanced.Adafruit_BME280_SPI(spi, cs) + + You need to setup the pressure at sea level + + .. code-block:: python + + bme280.sea_level_pressure = 1013.25 + + Now you have access to the :attr:`temperature`, :attr:`relative_humidity` + :attr:`pressure` and :attr:`altitude` attributes + + .. code-block:: python + + temperature = bme280.temperature + relative_humidity = bme280.relative_humidity + pressure = bme280.pressure + altitude = bme280.altitude + + """ + + def __init__(self, spi, cs, baudrate=100000): + import adafruit_bus_device.spi_device as spi_device # pylint: disable=import-outside-toplevel + + self._spi = spi_device.SPIDevice(spi, cs, baudrate=baudrate) + super().__init__() + + def _read_register(self, register, length): + register = (register | 0x80) & 0xFF # Read single, bit 7 high. + with self._spi as spi: + spi.write(bytearray([register])) # pylint: disable=no-member + result = bytearray(length) + spi.readinto(result) # pylint: disable=no-member + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + register &= 0x7F # Write, bit 7 low. + with self._spi as spi: + spi.write(bytes([register, value & 0xFF])) # pylint: disable=no-member diff --git a/adafruit_bme280.py b/adafruit_bme280/basic.py similarity index 68% rename from adafruit_bme280.py rename to adafruit_bme280/basic.py index 7990d9e..5dd52d2 100644 --- a/adafruit_bme280.py +++ b/adafruit_bme280/basic.py @@ -3,13 +3,13 @@ # SPDX-License-Identifier: MIT """ -`adafruit_bme280` +`adafruit_bme280.basic` ========================================================================================= CircuitPython driver from BME280 Temperature, Humidity and Barometric Pressure sensor -* Author(s): ladyada +* Author(s): ladyada, Jose David M. Implementation Notes -------------------- @@ -39,103 +39,47 @@ import ustruct as struct -__version__ = "0.0.0-auto.0" +__version__ = "2.6.4" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BME280.git" # I2C ADDRESS/BITS/SETTINGS # ----------------------------------------------------------------------- + +"""General Information""" _BME280_ADDRESS = const(0x77) _BME280_CHIPID = const(0x60) - _BME280_REGISTER_CHIPID = const(0xD0) -_BME280_REGISTER_DIG_T1 = const(0x88) -_BME280_REGISTER_DIG_H1 = const(0xA1) -_BME280_REGISTER_DIG_H2 = const(0xE1) -_BME280_REGISTER_DIG_H3 = const(0xE3) -_BME280_REGISTER_DIG_H4 = const(0xE4) -_BME280_REGISTER_DIG_H5 = const(0xE5) -_BME280_REGISTER_DIG_H6 = const(0xE7) - -_BME280_REGISTER_SOFTRESET = const(0xE0) -_BME280_REGISTER_CTRL_HUM = const(0xF2) -_BME280_REGISTER_STATUS = const(0xF3) -_BME280_REGISTER_CTRL_MEAS = const(0xF4) -_BME280_REGISTER_CONFIG = const(0xF5) -_BME280_REGISTER_PRESSUREDATA = const(0xF7) -_BME280_REGISTER_TEMPDATA = const(0xFA) -_BME280_REGISTER_HUMIDDATA = const(0xFD) - -_BME280_HUMIDITY_MIN = const(0) -_BME280_HUMIDITY_MAX = const(100) - -"""iir_filter values""" -IIR_FILTER_DISABLE = const(0) -IIR_FILTER_X2 = const(0x01) -IIR_FILTER_X4 = const(0x02) -IIR_FILTER_X8 = const(0x03) -IIR_FILTER_X16 = const(0x04) - -_BME280_IIR_FILTERS = ( - IIR_FILTER_DISABLE, - IIR_FILTER_X2, - IIR_FILTER_X4, - IIR_FILTER_X8, - IIR_FILTER_X16, -) - """overscan values for temperature, pressure, and humidity""" -OVERSCAN_DISABLE = const(0x00) OVERSCAN_X1 = const(0x01) -OVERSCAN_X2 = const(0x02) -OVERSCAN_X4 = const(0x03) -OVERSCAN_X8 = const(0x04) OVERSCAN_X16 = const(0x05) - -_BME280_OVERSCANS = { - OVERSCAN_DISABLE: 0, - OVERSCAN_X1: 1, - OVERSCAN_X2: 2, - OVERSCAN_X4: 4, - OVERSCAN_X8: 8, - OVERSCAN_X16: 16, -} - """mode values""" -MODE_SLEEP = const(0x00) -MODE_FORCE = const(0x01) -MODE_NORMAL = const(0x03) - -_BME280_MODES = (MODE_SLEEP, MODE_FORCE, MODE_NORMAL) +_BME280_MODES = (0x00, 0x01, 0x03) +"""iir_filter values""" +IIR_FILTER_DISABLE = const(0) """ standby timeconstant values TC_X[_Y] where X=milliseconds and Y=tenths of a millisecond """ -STANDBY_TC_0_5 = const(0x00) # 0.5ms -STANDBY_TC_10 = const(0x06) # 10ms -STANDBY_TC_20 = const(0x07) # 20ms -STANDBY_TC_62_5 = const(0x01) # 62.5ms STANDBY_TC_125 = const(0x02) # 125ms -STANDBY_TC_250 = const(0x03) # 250ms -STANDBY_TC_500 = const(0x04) # 500ms -STANDBY_TC_1000 = const(0x05) # 1000ms - -_BME280_STANDBY_TCS = ( - STANDBY_TC_0_5, - STANDBY_TC_10, - STANDBY_TC_20, - STANDBY_TC_62_5, - STANDBY_TC_125, - STANDBY_TC_250, - STANDBY_TC_500, - STANDBY_TC_1000, -) +"""mode values""" +MODE_SLEEP = const(0x00) +MODE_FORCE = const(0x01) +MODE_NORMAL = const(0x03) +"""Other Registers""" +_BME280_REGISTER_SOFTRESET = const(0xE0) +_BME280_REGISTER_CTRL_HUM = const(0xF2) +_BME280_REGISTER_STATUS = const(0xF3) +_BME280_REGISTER_CTRL_MEAS = const(0xF4) +_BME280_REGISTER_CONFIG = const(0xF5) +_BME280_REGISTER_TEMPDATA = const(0xFA) +_BME280_REGISTER_HUMIDDATA = const(0xFD) class Adafruit_BME280: """Driver from BME280 Temperature, Humidity and Barometric Pressure sensor .. note:: - The operational range of the BMP280 is 300-1100 hPa. + The operational range of the BME280 is 300-1100 hPa. Pressure measurements outside this range may not be as accurate. """ @@ -149,9 +93,9 @@ def __init__(self): raise RuntimeError("Failed to find BME280! Chip ID 0x%x" % chip_id) # Set some reasonable defaults. self._iir_filter = IIR_FILTER_DISABLE - self._overscan_humidity = OVERSCAN_X1 - self._overscan_temperature = OVERSCAN_X1 - self._overscan_pressure = OVERSCAN_X16 + self.overscan_humidity = OVERSCAN_X1 + self.overscan_temperature = OVERSCAN_X1 + self.overscan_pressure = OVERSCAN_X16 self._t_standby = STANDBY_TC_125 self._mode = MODE_SLEEP self._reset() @@ -172,19 +116,17 @@ def _read_temperature(self): raw_temperature = ( self._read24(_BME280_REGISTER_TEMPDATA) / 16 ) # lowest 4 bits get dropped - # print("raw temp: ", UT) + var1 = ( raw_temperature / 16384.0 - self._temp_calib[0] / 1024.0 ) * self._temp_calib[1] - # print(var1) + var2 = ( (raw_temperature / 131072.0 - self._temp_calib[0] / 8192.0) * (raw_temperature / 131072.0 - self._temp_calib[0] / 8192.0) ) * self._temp_calib[2] - # print(var2) self._t_fine = int(var1 + var2) - # print("t_fine: ", self.t_fine) def _reset(self): """Soft reset the sensor""" @@ -234,88 +176,11 @@ def mode(self, value): self._mode = value self._write_ctrl_meas() - @property - def standby_period(self): - """ - Control the inactive period when in Normal mode - Allowed standby periods are the constants STANDBY_TC_* - """ - return self._t_standby - - @standby_period.setter - def standby_period(self, value): - if not value in _BME280_STANDBY_TCS: - raise ValueError("Standby Period '%s' not supported" % (value)) - if self._t_standby == value: - return - self._t_standby = value - self._write_config() - - @property - def overscan_humidity(self): - """ - Humidity Oversampling - Allowed values are the constants OVERSCAN_* - """ - return self._overscan_humidity - - @overscan_humidity.setter - def overscan_humidity(self, value): - if not value in _BME280_OVERSCANS: - raise ValueError("Overscan value '%s' not supported" % (value)) - self._overscan_humidity = value - self._write_ctrl_meas() - - @property - def overscan_temperature(self): - """ - Temperature Oversampling - Allowed values are the constants OVERSCAN_* - """ - return self._overscan_temperature - - @overscan_temperature.setter - def overscan_temperature(self, value): - if not value in _BME280_OVERSCANS: - raise ValueError("Overscan value '%s' not supported" % (value)) - self._overscan_temperature = value - self._write_ctrl_meas() - - @property - def overscan_pressure(self): - """ - Pressure Oversampling - Allowed values are the constants OVERSCAN_* - """ - return self._overscan_pressure - - @overscan_pressure.setter - def overscan_pressure(self, value): - if not value in _BME280_OVERSCANS: - raise ValueError("Overscan value '%s' not supported" % (value)) - self._overscan_pressure = value - self._write_ctrl_meas() - - @property - def iir_filter(self): - """ - Controls the time constant of the IIR filter - Allowed values are the constants IIR_FILTER_* - """ - return self._iir_filter - - @iir_filter.setter - def iir_filter(self, value): - if not value in _BME280_IIR_FILTERS: - raise ValueError("IIR Filter '%s' not supported" % (value)) - self._iir_filter = value - self._write_config() - @property def _config(self): """Value to be written to the device's config register """ config = 0 - if self.mode == MODE_NORMAL: + if self.mode == 0x03: # MODE_NORMAL config += self._t_standby << 5 if self._iir_filter: config += self._iir_filter << 2 @@ -329,30 +194,6 @@ def _ctrl_meas(self): ctrl_meas += self.mode return ctrl_meas - @property - def measurement_time_typical(self): - """Typical time in milliseconds required to complete a measurement in normal mode""" - meas_time_ms = 1.0 - if self.overscan_temperature != OVERSCAN_DISABLE: - meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_temperature) - if self.overscan_pressure != OVERSCAN_DISABLE: - meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.5 - if self.overscan_humidity != OVERSCAN_DISABLE: - meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.5 - return meas_time_ms - - @property - def measurement_time_max(self): - """Maximum time in milliseconds required to complete a measurement in normal mode""" - meas_time_ms = 1.25 - if self.overscan_temperature != OVERSCAN_DISABLE: - meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_temperature) - if self.overscan_pressure != OVERSCAN_DISABLE: - meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.575 - if self.overscan_humidity != OVERSCAN_DISABLE: - meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.575 - return meas_time_ms - @property def temperature(self): """The compensated temperature in degrees Celsius.""" @@ -370,7 +211,7 @@ def pressure(self): # Algorithm from the BME280 driver # https://github.com/BoschSensortec/BME280_driver/blob/master/bme280.c adc = ( - self._read24(_BME280_REGISTER_PRESSUREDATA) / 16 + self._read24(0xF7) / 16 # BME280_REGISTER_PRESSUREDATA ) # lowest 4 bits get dropped var1 = float(self._t_fine) / 2.0 - 64000.0 var2 = var1 * var1 * self._pressure_calib[5] / 32768.0 @@ -407,55 +248,47 @@ def humidity(self): returns None if humidity measurement is disabled """ self._read_temperature() - hum = self._read_register(_BME280_REGISTER_HUMIDDATA, 2) - # print("Humidity data: ", hum) + hum = self._read_register(0xFD, 2) # BME280_REGISTER_HUMIDDATA adc = float(hum[0] << 8 | hum[1]) - # print("adc:", adc) # Algorithm from the BME280 driver # https://github.com/BoschSensortec/BME280_driver/blob/master/bme280.c var1 = float(self._t_fine) - 76800.0 - # print("var1 ", var1) var2 = ( self._humidity_calib[3] * 64.0 + (self._humidity_calib[4] / 16384.0) * var1 ) - # print("var2 ",var2) var3 = adc - var2 - # print("var3 ",var3) var4 = self._humidity_calib[1] / 65536.0 - # print("var4 ",var4) var5 = 1.0 + (self._humidity_calib[2] / 67108864.0) * var1 - # print("var5 ",var5) var6 = 1.0 + (self._humidity_calib[5] / 67108864.0) * var1 * var5 - # print("var6 ",var6) var6 = var3 * var4 * (var5 * var6) humidity = var6 * (1.0 - self._humidity_calib[0] * var6 / 524288.0) - if humidity > _BME280_HUMIDITY_MAX: - return _BME280_HUMIDITY_MAX - if humidity < _BME280_HUMIDITY_MIN: - return _BME280_HUMIDITY_MIN + if humidity > 100: + return 100 + if humidity < 0: + return 0 # else... return humidity @property def altitude(self): - """The altitude based on current ``pressure`` versus the sea level pressure + """The altitude based on current :attr:`pressure` versus the sea level pressure (``sea_level_pressure``) - which you must enter ahead of time)""" pressure = self.pressure # in Si units for hPascal return 44330 * (1.0 - math.pow(pressure / self.sea_level_pressure, 0.1903)) def _read_coefficients(self): """Read & save the calibration coefficients""" - coeff = self._read_register(_BME280_REGISTER_DIG_T1, 24) + coeff = self._read_register(0x88, 24) # BME280_REGISTER_DIG_T1 coeff = list(struct.unpack(" %s" % (register, [hex(i) for i in result])) return result def _write_register_byte(self, register, value): @@ -549,6 +382,7 @@ def _write_register_byte(self, register, value): class Adafruit_BME280_SPI(Adafruit_BME280): + """Driver for BME280 connected over SPI :param ~busio.SPI spi: SPI device @@ -568,7 +402,7 @@ class Adafruit_BME280_SPI(Adafruit_BME280): import board from digitalio import DigitalInOut - import adafruit_bme280 + from adafruit_bme280 import basic Once this is done you can define your `board.SPI` object and define your sensor object @@ -576,7 +410,7 @@ class Adafruit_BME280_SPI(Adafruit_BME280): cs = digitalio.DigitalInOut(board.D10) spi = board.SPI() - bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, cs) + bme280 = basic.Adafruit_BME280_SPI(spi, cs) You need to setup the pressure at sea level @@ -608,7 +442,6 @@ def _read_register(self, register, length): spi.write(bytearray([register])) # pylint: disable=no-member result = bytearray(length) spi.readinto(result) # pylint: disable=no-member - # print("$%02X => %s" % (register, [hex(i) for i in result])) return result def _write_register_byte(self, register, value): diff --git a/docs/api.rst b/docs/api.rst index 0622224..8818b61 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -3,3 +3,9 @@ .. automodule:: adafruit_bme280 :members: + +.. automodule:: adafruit_bme280.basic + :members: + +.. automodule:: adafruit_bme280.advanced + :members: diff --git a/examples/bme280_normal_mode.py b/examples/bme280_normal_mode.py index c5f1dd2..85dd156 100644 --- a/examples/bme280_normal_mode.py +++ b/examples/bme280_normal_mode.py @@ -8,7 +8,7 @@ """ import time import board -import adafruit_bme280 +import adafruit_bme280.advanced as adafruit_bme280 # Create sensor object, using the board's default I2C bus. i2c = board.I2C() # uses board.SCL and board.SDA diff --git a/examples/bme280_simpletest.py b/examples/bme280_simpletest.py index d653584..2f1c39a 100644 --- a/examples/bme280_simpletest.py +++ b/examples/bme280_simpletest.py @@ -3,7 +3,7 @@ import time import board -import adafruit_bme280 +from adafruit_bme280 import basic as adafruit_bme280 # Create sensor object, using the board's default I2C bus. i2c = board.I2C() # uses board.SCL and board.SDA diff --git a/examples/bme280_simpletest_pico.py b/examples/bme280_simpletest_pico.py index d433b44..435e41a 100644 --- a/examples/bme280_simpletest_pico.py +++ b/examples/bme280_simpletest_pico.py @@ -4,7 +4,7 @@ import time import board import busio -import adafruit_bme280 +from adafruit_bme280 import basic as adafruit_bme280 # Create sensor object, using the board's default I2C bus. i2c = busio.I2C(board.GP1, board.GP0) # SCL, SDA