How to connect a BME680?


How do I connect my BME680 sensor via Cayenne? It does not appear to be supported by default, will this change in a future update?


which device (pi / arduino) have you connected your BME680?


Hi shramiksalgaonkar,

I am using a Raspberry Pi and have successfully connected the module to my Pi and ran the test script supplied with the module.

Hooking the data being captured into Cayenne is the goal I wish to achieve.


you can the sensor data from the test script to cayenne using



So something like this project?:

This Github project seems to have solved connecting bme680 using MQTT but to another service.


you have do something similar but using and


Following on from the Pimoroni topic of your (I’m guessing)

I suggest doing this on the Pi desktop or on a Mac/Windows Desktop and copying it across as it’s horrible to do on Android.
On your dashboard,
Use Add New… - Device/Widget (green bit top left)
Select ‘Bring Your Own Thing’ (from the list, it’s at the bottom).
then stop there.

Use this (it should work, but it’s an untested cut down version of my program with more sensors and I cannot test it, edit as needed and check nothing is included that is also not needed.)
Fill it in with the MQTT info from that page

import sys
import time
import cayenne.client
import bme680

# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = "mqqt_user_from_page"
MQTT_PASSWORD  = "mqqt_pass_from_page"
MQTT_CLIENT_ID = "mqqt_id_from_page"

timestamp = 0
loop_delay = 15 #seconds
reading_delay = 60

def on_message(message):
        print("message received: " + str(message))

def bme_start():
    print("""Estimate indoor air quality

    Runs the sensor for a burn-in period, then uses a
    combination of relative humidity and gas resistance
    to estimate indoor air quality as a percentage.

    Press Ctrl+C to exit


    sensor = bme680.BME680()

    # These oversampling settings can be tweaked to
    # change the balance between accuracy and noise in
    # the data.



    # start_time and curr_time ensure that the
    # burn_in_time (in seconds) is kept track of.

    start_time = time.time()
    curr_time = time.time()
    burn_in_time = 300

    burn_in_data = []

        # Collect gas resistance burn-in values, then use the average
        # of the last 50 values to set the upper limit for calculating
        # gas_baseline.
        print("Collecting gas resistance burn-in data for 5 mins\n")
        while curr_time - start_time < burn_in_time:
            curr_time = time.time()
            if sensor.get_sensor_data() and
                gas =
                print("Gas: {0} Ohms".format(gas))

        gas_baseline = sum(burn_in_data[-50:]) / 50.0

        # Set the humidity baseline to 40%, an optimal indoor humidity.
        hum_baseline = 40.0

        # This sets the balance between humidity and gas reading in the
        # calculation of air_quality_score (25:75, humidity:gas)
        hum_weighting = 0.25

        print("Gas baseline: {0} Ohms, humidity baseline: {1:.2f} %RH\n".format(gas_baseline, hum_baseline))

    except KeyboardInterrupt:

    return gas_baseline, hum_baseline, hum_weighting

#cayenne mqqt setup
client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message

print("BME680 Starting")
bme_sensor = bme680.BME680()
gas_baseline, hum_baseline, hum_weighting = bme_start()

    while True:

        if (time.time() > timestamp + reading_delay):

            if bme_sensor.get_sensor_data():
                #send data direct to Cayenne
                client.celsiusWrite(    1,
                client.virtualWrite(    3,,"rel_hum","p")

            time.sleep(5)   #needs a delay otherwise gas sensor doesn't (i.e. doesn't trigger true), alter as needed.

            if bme_sensor.get_sensor_data() and
                gas =
                gas_offset = gas_baseline - gas

                hum =
                hum_offset = hum - hum_baseline

                # Calculate hum_score as the distance from the hum_baseline.
                if hum_offset > 0:
                    hum_score = (100 - hum_baseline - hum_offset) / (100 - hum_baseline) * (hum_weighting * 100)

                    hum_score = (hum_baseline + hum_offset) / hum_baseline * (hum_weighting * 100)

                # Calculate gas_score as the distance from the gas_baseline.
                if gas_offset > 0:
                    gas_score = (gas / gas_baseline) * (100 - (hum_weighting * 100))

                    gas_score = 100 - (hum_weighting * 100)

                # Calculate air_quality_score.
                air_quality_score = hum_score + gas_score

                #Send to calculated Pimoroni formula IAQ to Cayenne, this isn't the true Bosch IAQ
                client.virtualWrite(4, gas, "co","ohms")
                client.virtualWrite(5, air_quality_score, "IAQ","null")
                #print("Gas: {0:.2f} Ohms,humidity: {1:.2f} %RH,air quality: {2:.2f}".format(gas, hum, air_quality_score))

            timestamp = time.time()

except KeyboardInterrupt:

then run it on the Pi with that page still open and wait till it works, which shouldn’t be long


Superb @bensimmo. Thanks for sharing this. It will be helpful to many users.


Thank you @bensimmo.

Excitedly working my way through the steps you shared now :slight_smile:

This will be a good resource to point other people to @shramiksalgaonkar - thanks to you too.


I now use Bosch BSEC blob (their bit of C software code you must use as though it says IAQ readings are direct from the device, they are not. They are indirect and go via a bit of C software (BSEC) that does the calculations.

But that’s just switching out all the BME680 code for some code on GitHub.
I’m still testing it though ASI have nothing to compare the actual IAQ too.