|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +import bme680 |
| 4 | +import time |
| 5 | + |
| 6 | +print("""Estimate indoor air quality |
| 7 | +
|
| 8 | +Runs the sensor for a burn-in period, then uses a |
| 9 | +combination of relative humidity and gas resistance |
| 10 | +to estimate indoor air quality as a percentage. |
| 11 | +
|
| 12 | +Press Ctrl+C to exit |
| 13 | +
|
| 14 | +""") |
| 15 | + |
| 16 | +sensor = bme680.BME680() |
| 17 | + |
| 18 | +# These oversampling settings can be tweaked to |
| 19 | +# change the balance between accuracy and noise in |
| 20 | +# the data. |
| 21 | + |
| 22 | +sensor.set_humidity_oversample(bme680.OS_2X) |
| 23 | +sensor.set_pressure_oversample(bme680.OS_4X) |
| 24 | +sensor.set_temperature_oversample(bme680.OS_8X) |
| 25 | +sensor.set_filter(bme680.FILTER_SIZE_3) |
| 26 | +sensor.set_gas_status(bme680.ENABLE_GAS_MEAS) |
| 27 | + |
| 28 | +sensor.set_gas_heater_temperature(320) |
| 29 | +sensor.set_gas_heater_duration(150) |
| 30 | +sensor.select_gas_heater_profile(0) |
| 31 | + |
| 32 | +# start_time and curr_time ensure that the |
| 33 | +# burn_in_time (in seconds) is kept track of. |
| 34 | + |
| 35 | +start_time = time.time() |
| 36 | +curr_time = time.time() |
| 37 | +burn_in_time = 300 |
| 38 | + |
| 39 | +burn_in_data = [] |
| 40 | + |
| 41 | +try: |
| 42 | + # Collect gas resistance burn-in values, then use the average |
| 43 | + # of the last 50 values to set the upper limit for calculating |
| 44 | + # gas_baseline. |
| 45 | + print("Collecting gas resistance burn-in data for 5 mins\n") |
| 46 | + while curr_time - start_time < burn_in_time: |
| 47 | + curr_time = time.time() |
| 48 | + if sensor.get_sensor_data() and sensor.data.heat_stable: |
| 49 | + gas = sensor.data.gas_resistance |
| 50 | + burn_in_data.append(gas) |
| 51 | + print("Gas: {0} Ohms".format(gas)) |
| 52 | + time.sleep(1) |
| 53 | + |
| 54 | + gas_baseline = sum(burn_in_data[-50:]) / 50.0 |
| 55 | + |
| 56 | + # Set the humidity baseline to 40%, an optimal indoor humidity. |
| 57 | + hum_baseline = 40.0 |
| 58 | + |
| 59 | + # This sets the balance between humidity and gas reading in the |
| 60 | + # calculation of air_quality_score (25:75, humidity:gas) |
| 61 | + hum_weighting = 0.25 |
| 62 | + |
| 63 | + print("Gas baseline: {0} Ohms, humidity baseline: {1:.2f} %RH\n".format(gas_baseline, hum_baseline)) |
| 64 | + |
| 65 | + while True: |
| 66 | + if sensor.get_sensor_data() and sensor.data.heat_stable: |
| 67 | + gas = sensor.data.gas_resistance |
| 68 | + gas_offset = gas_baseline - gas |
| 69 | + |
| 70 | + hum = sensor.data.humidity |
| 71 | + hum_offset = hum - hum_baseline |
| 72 | + |
| 73 | + # Calculate hum_score as the distance from the hum_baseline. |
| 74 | + if hum_offset > 0: |
| 75 | + hum_score = (100 - hum_baseline - hum_offset) / (100 - hum_baseline) * (hum_weighting * 100) |
| 76 | + |
| 77 | + else: |
| 78 | + hum_score = (hum_baseline + hum_offset) / hum_baseline * (hum_weighting * 100) |
| 79 | + |
| 80 | + # Calculate gas_score as the distance from the gas_baseline. |
| 81 | + if gas_offset > 0: |
| 82 | + gas_score = (gas / gas_baseline) * (100 - (hum_weighting * 100)) |
| 83 | + |
| 84 | + else: |
| 85 | + gas_score = 100 - (hum_weighting * 100) |
| 86 | + |
| 87 | + # Calculate air_quality_score. |
| 88 | + air_quality_score = hum_score + gas_score |
| 89 | + |
| 90 | + print("Gas: {0:.2f} Ohms,humidity: {1:.2f} %RH,air quality: {2:.2f}".format(gas, hum, air_quality_score)) |
| 91 | + time.sleep(1) |
| 92 | + |
| 93 | +except KeyboardInterrupt: |
| 94 | + pass |
0 commit comments