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 https://github.com/myDevicesIoT/Cayenne-MQTT-Python

Thanks!

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 https://github.com/pimoroni/bme680-python and https://github.com/myDevicesIoT/Cayenne-MQTT-Python

1 Like

Following on from the Pimoroni topic of your (I’m guessing) https://forums.pimoroni.com/t/bme680-to-web-service/8407

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, https://cayenne.mydevices.com/cayenne/dashboard/add
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

#!/usr/bin/python3
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"

#general
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.

    sensor.set_humidity_oversample(bme680.OS_2X)
    sensor.set_pressure_oversample(bme680.OS_4X)
    sensor.set_temperature_oversample(bme680.OS_8X)
    sensor.set_filter(bme680.FILTER_SIZE_3)
    sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)

    sensor.set_gas_heater_temperature(320)
    sensor.set_gas_heater_duration(150)
    sensor.select_gas_heater_profile(0)

    # 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 = []

    try:
        # 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 sensor.data.heat_stable:
                gas = sensor.data.gas_resistance
                burn_in_data.append(gas)
                print("Gas: {0} Ohms".format(gas))
                time.sleep(1)

        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:
        pass

    return gas_baseline, hum_baseline, hum_weighting

#-----Main
#cayenne mqqt setup
client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

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


try:
    while True:
        client.loop()

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

            if bme_sensor.get_sensor_data():
                #send data direct to Cayenne
                client.celsiusWrite(    1, bme_sensor.data.temperature)
                client.hectoPascalWrite(2, bme_sensor.data.pressure)
                client.virtualWrite(    3, bme_sensor.data.humidity,"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 bme_sensor.data.heat_stable:
                gas = bme_sensor.data.gas_resistance
                gas_offset = gas_baseline - gas

                hum = bme_sensor.data.humidity
                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)

                else:
                    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))

                else:
                    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()
        time.sleep(loop_delay-5)

except KeyboardInterrupt:
    pass

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

2 Likes

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

1 Like

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 @shramik_salgaonkar - thanks to you too.

1 Like

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.

1 Like

@bensimmo Hi. I try to add my bme680 sensor from Rpi zero to Cayenne with Your tutorial but I don’t know where to save that file You gave and how to name it. Also it will be great od You tell me how to make my sensor start when I turn on Raspberry Pi.
Regards.
Przemek

First follow this link and see if you are able to get reading from the sensor https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-bme680-breakout

@shramik_salgaonkar Hi, thanks for answer. I have make my bme680 is working when I run:
python read-all.py file. But when I make new file read-cayenne.py it don’t send data to my dashboard. I copy that:

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"

to my read-all.py file and type credentials from cayenne dashboard. I also try to make new file with data from @bensimmo post but it only show me data from air sensor in Ohms in ssh terminal but I don’t see any measurements in cayenne dashboard.

I see in terminal that is connecting to mqtt.mydevices.com:1883.
Regards

to send data to cayenne you need to use:

 client.loop()

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

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

`

@shramik_salgaonkar Can You tell where I have to paste this?

can you share your entire code.

@shramik_salgaonkar
That is my modified file:

#!/usr/bin/env python

import cayenne.client
import bme680
import time
import logging

# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = "06487d60-1537-11ea-84bb-8f71124cfdfb"
MQTT_PASSWORD  = "23309cdee31964b2ae4caed9417b689c9bebece2"
MQTT_CLIENT_ID = "79503770-153d-11ea-a38a-d57172a4b4d4"

client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO)
# For a secure connection use port 8883 when calling client.begin:
# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)

#general
timestamp = 0
loop_delay = 15 #seconds
reading_delay = 60

print("""read-all.py - Displays temperature, pressure, humidity, and gas.

Press Ctrl+C to exit!

""")

try:
    sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except IOError:
    sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)

# These calibration data can safely be commented
# out, if desired.

print('Calibration data:')
for name in dir(sensor.calibration_data):

    if not name.startswith('_'):
value = getattr(sensor.calibration_data, name)

        if isinstance(value, int):
            print('{}: {}'.format(name, value))

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

sensor.set_humidity_oversample(bme680.OS_2X)
sensor.set_pressure_oversample(bme680.OS_4X)
sensor.set_temperature_oversample(bme680.OS_8X)
sensor.set_filter(bme680.FILTER_SIZE_3)
sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)

print('\n\nInitial reading:')
for name in dir(sensor.data):
    value = getattr(sensor.data, name)
if not name.startswith('_'):
        print('{}: {}'.format(name, value))

sensor.set_gas_heater_temperature(320)
sensor.set_gas_heater_duration(150)
sensor.select_gas_heater_profile(0)

# Up to 10 heater profiles can be configured, each
# with their own temperature and duration.
# sensor.set_gas_heater_profile(200, 150, nb_profile=1)
# sensor.select_gas_heater_profile(1)

print('\n\nPolling:')
try:
    while True:

        client.loop()

         if (time.time() > timestamp + reading_delay):
if bme_sensor.get_sensor_data():
            #send data direct to Cayenne
            client.celsiusWrite(    1, bme_sensor.data.temperature)
            client.hectoPascalWrite(2, bme_sensor.data.pressure)
            client.virtualWrite(    3, bme_sensor.data.humidity,"rel_hum","p")


        if sensor.get_sensor_data():
            output = '{0:.2f} C,{1:.2f} hPa,{2:.2f} %RH'.format(
                sensor.data.temperature,
                sensor.data.pressure,
                sensor.data.humidity)

            if sensor.data.heat_stable:
                print('{0},{1} Ohms'.format(
                    output,
                    sensor.data.gas_resistance))

            else:
            print(output)

        time.sleep(1)

except KeyboardInterrupt:
    pass

this file contains the lines i mentioned. This is the code given by Bensimmo, and it should work fine.

@shramik_salgaonkar It work in terminal but don’t send data to dashboard but when I add Your lines:

client.loop()

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

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

it don’t work at all:

File "read-cayenne.py", line 78
    if (time.time() > timestamp + reading_delay):
    ^
IndentationError: unexpected indent

thats is an indent error https://www.w3schools.in/python-tutorial/concept-of-indentation-in-python/

You are confusing me, are you using bensimmo code or are a different code?