diff --git a/adafruit_bmp5xx.py b/adafruit_bmp5xx.py index 0cfb20e..32a1424 100644 --- a/adafruit_bmp5xx.py +++ b/adafruit_bmp5xx.py @@ -1,4 +1,3 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries # # SPDX-License-Identifier: MIT @@ -34,15 +33,17 @@ import time from adafruit_bus_device.i2c_device import I2CDevice -from adafruit_register.i2c_bit import ROBit, RWBit -from adafruit_register.i2c_bits import ROBits, RWBits -from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct +from adafruit_bus_device.spi_device import SPIDevice # noqa: PLC0415 +from adafruit_register.register_accessor import I2CRegisterAccessor, SPIRegisterAccessor +from adafruit_register.register_bit import ROBit, RWBit +from adafruit_register.register_bits import ROBits, RWBits from micropython import const try: from typing import Optional - from busio import I2C + from busio import I2C, SPI + from digitalio import DigitalInOut except ImportError: pass @@ -138,12 +139,12 @@ BMP585_CHIP_ID = const(0x51) -class BMP5XX_I2C: +class BMP5XX: """ Bosche BMP5xx temperature and pressure sensor breakout CircuitPython driver. """ - chip_id: int = ROUnaryStruct(BMP5_REG_ID, "B") + chip_id: int = ROBits(8, BMP5_REG_ID, 0) # Status register bits status_nvm_ready: bool = ROBit(BMP5_REG_STATUS, 1) # NVM ready @@ -219,14 +220,29 @@ class BMP5XX_I2C: output_data_rate = RWBits(5, BMP5XX_REG_ODR_CONFIG, 2) """Output data rate. Must be one of the ODR constants.""" - command = UnaryStruct(BMP5_REG_CMD, "B") # command register + command = RWBits(8, BMP5_REG_CMD, 0) # command register """Command register""" - def __init__(self, i2c: I2C, address: int = DEFAULT_ADAFRUIT_ADDR) -> None: - try: - self.i2c_device = I2CDevice(i2c, address) - except ValueError: - raise ValueError(f"No I2C device found at address 0x{address:02X}") + def __init__( + self, + i2c: I2C = None, + address: Optional[int] = DEFAULT_ADAFRUIT_ADDR, + spi: SPI = None, + cs: DigitalInOut = None, + ) -> None: + if spi is not None and cs is not None: + try: + self.spi_device = SPIDevice(spi, cs, baudrate=1000000) + self.register_accessor = SPIRegisterAccessor(self.spi_device) + except ValueError: + raise ValueError(f"No SPI device found.") + + elif i2c is not None: + try: + i2c_device = I2CDevice(i2c, address) + self.register_accessor = I2CRegisterAccessor(i2c_device) + except ValueError: + raise ValueError(f"No I2C device found.") self.sea_level_pressure = 1013.25 self.reset() @@ -271,10 +287,11 @@ def altitude(self) -> float: def reset(self) -> None: """Reset the BMP5xx device.""" self.command = BMP5_SOFT_RESET_CMD - time.sleep(0.006) + time.sleep(0.012) + _throwaway = self.chip_id if self.chip_id not in {BMP581_CHIP_ID, BMP585_CHIP_ID}: - raise ValueError(f"CHIP_ID was zero") + raise ValueError(f"CHIP_ID was incorrect") if not self.status_nvm_ready: raise ValueError("NVM not ready") if self.status_nvm_err: diff --git a/docs/examples.rst b/docs/examples.rst index b68bc01..0acb2cf 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -6,3 +6,11 @@ Ensure your device works with this simple test. .. literalinclude:: ../examples/bmp5xx_simpletest.py :caption: examples/bmp5xx_simpletest.py :linenos: + +.. literalinclude:: ../examples/bmp5xx_spi_simpletest.py + :caption: examples/bmp5xx_spi_simpletest.py + :linenos: + +.. literalinclude:: ../examples/bmp5xx_spi_multi_device.py + :caption: examples/bmp5xx_spi_multi_device.py + :linenos: diff --git a/examples/bmp5xx_simpletest.py b/examples/bmp5xx_simpletest.py index 96a3fc5..8dfc44e 100644 --- a/examples/bmp5xx_simpletest.py +++ b/examples/bmp5xx_simpletest.py @@ -5,7 +5,7 @@ import board -from adafruit_bmp5xx import BMP5XX_I2C +from adafruit_bmp5xx import BMP5XX SEALEVELPRESSURE_HPA = 1013.25 @@ -13,7 +13,7 @@ i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller -bmp = BMP5XX_I2C(i2c) +bmp = BMP5XX(i2c) bmp.sea_level_pressure = SEALEVELPRESSURE_HPA diff --git a/examples/bmp5xx_spi_multi_device.py b/examples/bmp5xx_spi_multi_device.py new file mode 100644 index 0000000..a66094c --- /dev/null +++ b/examples/bmp5xx_spi_multi_device.py @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import time + +import board +from digitalio import DigitalInOut, Direction + +from adafruit_bmp5xx import BMP5XX + +SEALEVELPRESSURE_HPA = 1013.25 + +# SPI setup +spi = board.SPI() + +# first sensor setup +cs1 = DigitalInOut(board.D10) +cs1.direction = Direction.OUTPUT +bmp1 = BMP5XX(spi=spi, cs=cs1) + +# second sensor setup, different CS pin, same SPI bus +cs2 = DigitalInOut(board.D11) +cs2.direction = Direction.OUTPUT +bmp2 = BMP5XX(spi=spi, cs=cs2) + +bmp1.sea_level_pressure = SEALEVELPRESSURE_HPA +bmp2.sea_level_pressure = SEALEVELPRESSURE_HPA + +while True: + if bmp1.data_ready: + print( + f"BMP1 temp F: {bmp1.temperature * (9 / 5) + 32} " + f"pressure: {bmp1.pressure} hPa " + f"Approx altitude: {bmp1.altitude} m" + ) + + if bmp2.data_ready: + print( + f"BMP2 temp F: {bmp2.temperature * (9 / 5) + 32} " + f"pressure: {bmp2.pressure} hPa " + f"Approx altitude: {bmp2.altitude} m" + ) + print("-----") + time.sleep(1) diff --git a/examples/bmp5xx_spi_simpletest.py b/examples/bmp5xx_spi_simpletest.py new file mode 100644 index 0000000..97e168b --- /dev/null +++ b/examples/bmp5xx_spi_simpletest.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense +import time + +import board +from digitalio import DigitalInOut, Direction + +from adafruit_bmp5xx import BMP5XX + +SEALEVELPRESSURE_HPA = 1013.25 + +# SPI setup +spi = board.SPI() # uses board.SCL and board.SDA +spi = board.SPI() +cs = DigitalInOut(board.D10) +cs.direction = Direction.OUTPUT +bmp = BMP5XX(spi=spi, cs=cs) + + +bmp.sea_level_pressure = SEALEVELPRESSURE_HPA + +while True: + if bmp.data_ready: + print( + f"temp F: {bmp.temperature * (9 / 5) + 32} " + f"pressure: {bmp.pressure} hPa " + f"Approx altitude: {bmp.altitude} m" + ) + time.sleep(1)