Skip to content

Add SPI Interface for BME680 #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 14, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 57 additions & 4 deletions adafruit_bme680.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
_BME680_REG_SOFTRESET = const(0xE0)
_BME680_REG_CTRL_GAS = const(0x71)
_BME680_REG_CTRL_HUM = const(0x72)
_BME280_REG_STATUS = const(0xF3)
_BME680_REG_STATUS = const(0x73)
_BME680_REG_CTRL_MEAS = const(0x74)
_BME680_REG_CONFIG = const(0x75)

_BME680_REG_STATUS = const(0x1D)
_BME680_REG_MEAS_STATUS = const(0x1D)
_BME680_REG_PDATA = const(0x1F)
_BME680_REG_TDATA = const(0x22)
_BME680_REG_HDATA = const(0x25)
Expand Down Expand Up @@ -266,7 +266,7 @@ def _perform_reading(self):
self._write(_BME680_REG_CTRL_MEAS, [ctrl])
new_data = False
while not new_data:
data = self._read(_BME680_REG_STATUS, 15)
data = self._read(_BME680_REG_MEAS_STATUS, 15)
new_data = data[0] & 0x80 != 0
time.sleep(0.005)
self._last_reading = time.monotonic()
Expand Down Expand Up @@ -324,7 +324,7 @@ class Adafruit_BME680_I2C(Adafruit_BME680):
will be from the previous reading."""
def __init__(self, i2c, address=0x77, debug=False, *, refresh_rate=10):
"""Initialize the I2C device at the 'address' given"""
import adafruit_bus_device.i2c_device as i2c_device
from adafruit_bus_device import i2c_device
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you changing the I2C import here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its kinda the style we use in other drivers - so im not oppsoed to this change :D

Copy link
Contributor Author

@jraber jraber Mar 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @brentru. I changed it mostly to make pylint happy.

When I added the SPI code, pylint complained about the SPI import, so I "fixed" it. Not wanting the library to have two different import styles, the choice was to either change the i2c import to match the new SPI import, which would make pylint happy, or to change the SPI import to match the i2c import. Also, I feel like the imports are a bit cleaner this way.

I put it in it's own commit to make it obvious that it has nothing to do with the SPI code.

self._i2c = i2c_device.I2CDevice(i2c, address)
self._debug = debug
super().__init__(refresh_rate=refresh_rate)
Expand All @@ -349,3 +349,56 @@ def _write(self, register, values):
i2c.write(buffer)
if self._debug:
print("\t$%02X <= %s" % (values[0], [hex(i) for i in values[1:]]))

class Adafruit_BME680_SPI(Adafruit_BME680):
"""Driver for SPI connected BME680.

:param busio.SPI spi: SPI device
:param digitalio.DigitalInOut cs: Chip Select
:param bool debug: Print debug statements when True.
:param int baudrate: Clock rate, default is 100000
:param int refresh_rate: Maximum number of readings per second. Faster property reads
will be from the previous reading.
"""

def __init__(self, spi, cs, baudrate=100000, debug=False, *, refresh_rate=10):
from adafruit_bus_device import spi_device
self._spi = spi_device.SPIDevice(spi, cs, baudrate=baudrate)
self._debug = debug
super().__init__(refresh_rate=refresh_rate)

def _read(self, register, length):
if register != _BME680_REG_STATUS:
#_BME680_REG_STATUS exists in both SPI memory pages
#For all other registers, we must set the correct memory page
self._set_spi_mem_page(register)

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
if self._debug:
print("\t$%02X => %s" % (register, [hex(i) for i in result]))
return result

def _write(self, register, values):
if register != _BME680_REG_STATUS:
#_BME680_REG_STATUS exists in both SPI memory pages
#For all other registers, we must set the correct memory page
self._set_spi_mem_page(register)
register &= 0x7F # Write, bit 7 low.
with self._spi as spi:
buffer = bytearray(2 * len(values))
for i, value in enumerate(values):
buffer[2 * i] = register + i
buffer[2 * i + 1] = value & 0xFF
spi.write(buffer) #pylint: disable=no-member
if self._debug:
print("\t$%02X <= %s" % (values[0], [hex(i) for i in values[1:]]))

def _set_spi_mem_page(self, register):
spi_mem_page = 0x00
if register < 0x80:
spi_mem_page = 0x10
self._write(_BME680_REG_STATUS, [spi_mem_page])