How to connect a BME680?

I would suggest putting everything in the home directory and running from there. You can get permission and or conflicting file names/libraries from running within an example directory.

cd ~
mkdir bme680_test
cd bme680_test
cp ~/Cayenne-MQTT-Python/examples/new_bme680.py new_bme680.py
python new_bme680.py

Or copy w/e file you are currently working with. I see you are trying a bunch of them.

1 Like

I copy code from read-all.py to Example-01-SendData.py and it works:

pi@raspberrypi:~/Cayenne-MQTT-Python/examples $ python SendData.py 
read-all.py - Displays temperature, pressure, humidity, and gas.

Press Ctrl+C to exit!


Calibration data:
par_gh1: -51
par_gh2: -12741
par_gh3: 18
par_h1: 880
par_h2: 990
par_h3: 0
par_h4: 45
par_h5: 20
par_h6: 120
par_h7: -100
par_p1: 37570
par_p10: 30
par_p2: -10627
par_p3: 88
par_p4: 6075
par_p5: -104
par_p6: 30
par_p7: 68
par_p8: -5847
par_p9: -1284
par_t1: 26188
par_t2: 26263
par_t3: 3
range_sw_err: 0
res_heat_range: 1
res_heat_val: 42
t_fine: 116517


Initial reading:
gas_index: 0
gas_resistance: 3014623
heat_stable: False
humidity: 37.628
meas_index: 0
pressure: 1007.65
status: 32
temperature: 22.76


Polling:
22.76 C,1007.64 hPa,37.62 %RH
22.77 C,1007.64 hPa,37.62 %RH,12613 Ohms
22.80 C,1007.62 hPa,37.60 %RH,15227 Ohms
22.82 C,1007.60 hPa,37.55 %RH,17988 Ohms
22.85 C,1007.61 hPa,37.53 %RH,20854 Ohms
22.88 C,1007.60 hPa,37.47 %RH,23695 Ohms
22.89 C,1007.62 hPa,37.42 %RH,26614 Ohms
22.91 C,1007.63 hPa,37.37 %RH,29561 Ohms
22.93 C,1007.63 hPa,37.34 %RH,32368 Ohms
22.94 C,1007.61 hPa,37.29 %RH,35048 Ohms
22.96 C,1007.62 hPa,37.25 %RH,37526 Ohms
22.97 C,1007.63 hPa,37.22 %RH,40150 Ohms
22.98 C,1007.62 hPa,37.18 %RH,42642 Ohms
22.99 C,1007.64 hPa,37.15 %RH,45169 Ohms
23.00 C,1007.63 hPa,37.13 %RH,47149 Ohms
23.01 C,1007.64 hPa,37.11 %RH,49519 Ohms
23.01 C,1007.63 hPa,37.07 %RH,51625 Ohms
23.02 C,1007.67 hPa,37.05 %RH,53883 Ohms
23.03 C,1007.66 hPa,37.02 %RH,56122 Ohms
23.03 C,1007.65 hPa,36.99 %RH,58148 Ohms
23.04 C,1007.67 hPa,36.98 %RH,60196 Ohms
23.05 C,1007.65 hPa,36.95 %RH,62162 Ohms
23.05 C,1007.64 hPa,36.92 %RH,64064 Ohms
23.06 C,1007.63 hPa,36.90 %RH,66296 Ohms
23.06 C,1007.65 hPa,36.89 %RH,68240 Ohms
23.07 C,1007.64 hPa,36.89 %RH,69892 Ohms
23.07 C,1007.63 hPa,36.86 %RH,72305 Ohms
23.08 C,1007.65 hPa,36.84 %RH,73901 Ohms
23.09 C,1007.64 hPa,36.83 %RH,76048 Ohms
23.09 C,1007.64 hPa,36.81 %RH,77311 Ohms
23.09 C,1007.63 hPa,36.81 %RH,78989 Ohms
23.10 C,1007.65 hPa,36.79 %RH,81447 Ohms
23.10 C,1007.65 hPa,36.77 %RH,82816 Ohms
23.11 C,1007.63 hPa,36.77 %RH,84402 Ohms
23.11 C,1007.63 hPa,36.75 %RH,86049 Ohms
23.12 C,1007.65 hPa,36.75 %RH,87763 Ohms
23.12 C,1007.65 hPa,36.74 %RH,89641 Ohms
23.13 C,1007.64 hPa,36.72 %RH,91005 Ohms
23.13 C,1007.63 hPa,36.72 %RH,92615 Ohms
23.13 C,1007.62 hPa,36.69 %RH,94390 Ohms
23.14 C,1007.64 hPa,36.69 %RH,95466 Ohms
23.14 C,1007.65 hPa,36.69 %RH,95824 Ohms
23.15 C,1007.63 hPa,36.67 %RH,97554 Ohms
23.15 C,1007.62 hPa,36.67 %RH,98471 Ohms
23.16 C,1007.67 hPa,36.65 %RH,99940 Ohms
23.16 C,1007.66 hPa,36.63 %RH,101948 Ohms
23.16 C,1007.66 hPa,36.63 %RH,103523 Ohms
23.17 C,1007.65 hPa,36.62 %RH,104296 Ohms
23.17 C,1007.65 hPa,36.60 %RH,105946 Ohms
23.17 C,1007.65 hPa,36.60 %RH,107579 Ohms
23.18 C,1007.67 hPa,36.59 %RH,108979 Ohms
23.18 C,1007.66 hPa,36.59 %RH,110197 Ohms
23.18 C,1007.65 hPa,36.56 %RH,112040 Ohms
23.19 C,1007.65 hPa,36.58 %RH,112567 Ohms
23.19 C,1007.65 hPa,36.56 %RH,114805 Ohms
23.19 C,1007.67 hPa,36.53 %RH,116158 Ohms
23.20 C,1007.66 hPa,36.55 %RH,116888 Ohms
23.20 C,1007.65 hPa,36.52 %RH,118207 Ohms
23.20 C,1007.64 hPa,36.53 %RH,119986 Ohms
^CConnecting to mqtt.mydevices.com:8883
Connected with result code 0
SUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/cmd/+
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/sys/model Python
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/sys/version 1.1.0
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=1
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=10
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=801
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=2
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=20
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=802
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=3
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=30
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=803
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=4
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=40
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=804
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=5
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=50
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=805
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=6
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=60
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=806
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=7
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=70
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=807
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=8
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=80
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/3 bp,hpa=808
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/1 temp,c=9
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602-11ea-8221-599f77add412/data/2 lum,lux=90
PUB v1/06487d60-1537-11ea-84bb-8f71124cfdfb/things/f9f06b50-1602

and It show data in example dashboard:


but there’s something wrong with data. It start to send when I click ctrl+c

excellent work. Click on the green + on the widget to make it permanent.

it is to kill the process.

That is my new code, it works but I think it need some chlittle changes:

pi@raspberrypi:~/Cayenne-MQTT-Python/examples $ cat SendData.py 
#!/usr/bin/env python
import cayenne.client
import time
import bme680
import logging

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


# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = "06487d60-1537-11ea-84bb-8f71124cfdfb"
MQTT_PASSWORD  = "23309cdee31964b2ae4caed9417b689c9bebece2"
MQTT_CLIENT_ID = "f9f06b50-1602-11ea-8221-599f77add412"


client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO, port=8883)
# 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)

i=0
timestamp = 0

while True:
    client.loop()
    
    if (time.time() > timestamp + 10):
        client.celsiusWrite(1, i)
        client.luxWrite(2, i*10)
        client.hectoPascalWrite(3, i+800)
        timestamp = time.time()
        i = i+1

ohh no, :man_facepalming:

I have edited your code.
Untitled.txt (3.1 KB)

Your code don’t work:

pi@raspberrypi:~/bme680_test $ python bme680.py 
read-all.py - Displays temperature, pressure, humidity, and gas.

Press Ctrl+C to exit!


Traceback (most recent call last):
  File "bme680.py", line 4, in <module>
    import bme680
  File "/home/pi/bme680_test/bme680.py", line 14, in <module>
    sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
AttributeError: 'module' object has no attribute 'BME680'

YEEEES :smiley:
now it works. I rename it and remove bme680.py file:

@adam any thoughts on this issue?

But it shows data on example device `Device 24c6’ - that is device what was generated when I try Example_01_senddata.py and not on my device BME680.

Now I rename device and everything is OK. Thank You very much for help and Your time. Can You tell me is it posiible to also add my pm2.5 sensor [SDS011] to my dashboard in Cayenne? :smiley:
I make it work with that tutorial and it autostart when reboot. Can I do it with my code to autostart:
$ crontab -e
@reboot cd /home/pi/bme680_test && ./python Example_bme680.py

1 Like

yes, just add the pm2.5 code to your existing code and send it with client.virtualWrite(6, x) where x is the pm2.5 data

Can I do it with my code to autostart:
$ crontab -e
@reboot cd /home/pi/bme680_test && ./python Example_bme680.py?

no, use @reboot python /home/pi/bme680_test/Example_bme680.py & as your crontab entry

Thanks. Can You help me where to paste that pm2.5 [sds011] code in my code from bme680?
aqi.py

#!/usr/bin/python -u
# coding=utf-8
# "DATASHEET": http://cl.ly/ekot
# https://gist.github.com/kadamski/92653913a53baf9dd1a8
from __future__ import print_function
import serial, struct, sys, time, json, subprocess

DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5
CMD_SLEEP = 6
CMD_FIRMWARE = 7
CMD_WORKING_PERIOD = 8
MODE_ACTIVE = 0
MODE_QUERY = 1
PERIOD_CONTINUOUS = 0

JSON_FILE = '/var/www/html/aqi.json'

MQTT_HOST = ''
MQTT_TOPIC = '/weather/particulatematter'

ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600

ser.open()
ser.flushInput()

byte, data = 0, ""

def dump(d, prefix=''):
    print(prefix + ' '.join(x.encode('hex') for x in d))

def construct_command(cmd, data=[]):
    assert len(data) <= 12
    data += [0,]*(12-len(data))
    checksum = (sum(data)+cmd-2)%256
    ret = "\xaa\xb4" + chr(cmd)
    ret += ''.join(chr(x) for x in data)
    ret += "\xff\xff" + chr(checksum) + "\xab"

    if DEBUG:
        dump(ret, '> ')
    return ret

def process_data(d):
    r = struct.unpack('<HHxxBB', d[2:])
    pm25 = r[0]/10.0
    pm10 = r[1]/10.0
    checksum = sum(ord(v) for v in d[2:8])%256
    return [pm25, pm10]
    #print("PM 2.5: {} μg/m^3  PM 10: {} μg/m^3 CRC={}".format(pm25, pm10, "OK" if (checksum==r[2] and r[3]==0xab) else "NOK"))

def process_version(d):
    r = struct.unpack('<BBBHBB', d[3:])
    checksum = sum(ord(v) for v in d[2:8])%256
    print("Y: {}, M: {}, D: {}, ID: {}, CRC={}".format(r[0], r[1], r[2], hex(r[3]), "OK" if (checksum==r[4] and r[5]==0xab) else "NOK"))

def read_response():
    byte = 0
    while byte != "\xaa":
        byte = ser.read(size=1)

    d = ser.read(size=9)

    if DEBUG:
        dump(d, '< ')
    return byte + d

def cmd_set_mode(mode=MODE_QUERY):
    ser.write(construct_command(CMD_MODE, [0x1, mode]))
    read_response()

def cmd_query_data():
    ser.write(construct_command(CMD_QUERY_DATA))
    d = read_response()
    values = []
    if d[1] == "\xc0":
        values = process_data(d)
    return values

def cmd_set_sleep(sleep):
    mode = 0 if sleep else 1
    ser.write(construct_command(CMD_SLEEP, [0x1, mode]))
    read_response()

def cmd_set_working_period(period):
    ser.write(construct_command(CMD_WORKING_PERIOD, [0x1, period]))
    read_response()

def cmd_firmware_ver():
    ser.write(construct_command(CMD_FIRMWARE))
    d = read_response()
    process_version(d)

def cmd_set_id(id):
    id_h = (id>>8) % 256
    id_l = id % 256
    ser.write(construct_command(CMD_DEVICE_ID, [0]*10+[id_l, id_h]))
    read_response()

def pub_mqtt(jsonrow):
    cmd = ['mosquitto_pub', '-h', MQTT_HOST, '-t', MQTT_TOPIC, '-s']
    print('Publishing using:', cmd)
    with subprocess.Popen(cmd, shell=False, bufsize=0, stdin=subprocess.PIPE).stdin as f:
        json.dump(jsonrow, f)


if __name__ == "__main__":
    cmd_set_sleep(0)
    cmd_firmware_ver()
    cmd_set_working_period(PERIOD_CONTINUOUS)
    cmd_set_mode(MODE_QUERY);
    while True:
        cmd_set_sleep(0)
        for t in range(15):
            values = cmd_query_data();
            if values is not None and len(values) == 2:
              print("PM2.5: ", values[0], ", PM10: ", values[1])
              time.sleep(2)

        # open stored data
        try:
            with open(JSON_FILE) as json_data:
                data = json.load(json_data)
        except IOError as e:
            data = []

        # check if length is more than 100 and delete first element
        if len(data) > 100:
            data.pop(0)

        # append new values
        jsonrow = {'pm25': values[0], 'pm10': values[1], 'time': time.strftime("%d.%m.%Y %H:%M:%S")}
        data.append(jsonrow)

        # save it
        with open(JSON_FILE, 'w') as outfile:
            json.dump(data, outfile)

        if MQTT_HOST != '':
            pub_mqtt(jsonrow)
            
        print("Going to sleep for 1 min...")
        cmd_set_sleep(1)
        time.sleep(60)

I try Your way and my in cronetab and it’s offline when I reboot :confused:

After the line import serial, struct, sys, time, json, subprocess put time.sleep(30) #Sleep to allow wireless to connect before starting MQTT Even if you don’t use wireless it’s a good idea to sleep for a little to allow the Pi to get an IP address. If you don’t want to wait 30 secs you can try something lower. Even 10 seconds should be plenty if you have a pi 3 or newer.

try this simple code:

import time
def hexShow(argv):  
    result = ''  
    hLen = len(argv)  
    for i in range(hLen):  
        hvol = argv[i]
        hhex = '%02x'%hvol  
        result += hhex+' '  
    print ('hexShow:',result)
  
t = serial.Serial('/dev/ttyAMA0',9600)  
t.setTimeout(1.5)
while True:
    t.flushInput()
    time.sleep(0.5)
    retstr = t.read(10)
    hexShow(retstr)
    if len(retstr)==10:
        if(retstr[0]==0xaa and retstr[1]==0xc0):
            checksum=0
            for i in range(6):
                checksum=checksum+int(retstr[2+i])
            if checksum%256 == retstr[8]:
                pm25=int(retstr[2])+int(retstr[3])*256
                pm10=int(retstr[4])+int(retstr[5])*256
                print ("pm2.5:%.1f pm10 %.1f"%(pm25/10.0,pm10/10.0))

@shramik_salgaonkar What is this code for?

@adam Sorry I’m not a programmer and I don’t know what do You mean :confused:

Replace the code at the top with this:

#!/usr/bin/python -u
# coding=utf-8
# "DATASHEET": http://cl.ly/ekot
# https://gist.github.com/kadamski/92653913a53baf9dd1a8
from __future__ import print_function
import serial, struct, sys, time, json, subprocess

time.sleep(30) #Sleep to allow wireless to connect before starting MQTT

DEBUG = 0
CMD_MODE = 2
CMD_QUERY_DATA = 4
CMD_DEVICE_ID = 5

Basically you just want to add the time.sleep part.