久々に電子工作ネタ。

 

最近はずっとNode-REDでデータを取ってきたけど、今回はうまくいかなかったのでPythonを使いました。

参考にさせていただいた記事はこちら。

 

 

 

 

 

 

使ったもの

  • BME680モジュール@秋月電子
  • 16bitADコンバータ(MCP3425)
  • RaspberryPi 2B

 

まずはMCP3425とBME680をラズパイに繋げて、それぞれ単独で動作確認。

これは無事成功。

通信はどちらもI2Cを使っています。

 

I2Cのアドレスの確認コマンドは下記。

sudo i2cdetect -y 1

これで2つ分のアドレスが表示されていることを確認します。

今回の場合は、68と77の2つが表示されました。

ちなみに、68ADコンバータ(MCP3425)77BME680のアドレスです。

 

次に、単独で動かしていたプログラムを1つにまとめます。

それができたらcsvに保存するプログラムを追記。

データ取得時刻も保存するようにしました。

 

 

そうやって出来たのが下記のプログラム。

ツギハギだらけだけど、動いたので良し!

 

#!/usr/bin/env python

import bme680
import time
import datetime
import smbus
i2c = smbus.SMBus(1)
addr=0x68
config = 0b10011000
Vref=2.048

i2c.write_byte(addr, config) #16bit
time.sleep(0.2)

def swap16(x):
    return (((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF))

def sign16(x):
    return ( -(x & 0b1000000000000000) | (x & 0b0111111111111111) )
  
def write_csv(t,p,h,g,m):
    dt_now = datetime.datetime.now()
    with open('MSS_BME680.csv', 'a') as f:
        f.write(dt_now.strftime('%Y/%m/%d %H:%M:%S')+ "," + str(t) + "," + str(p) + "," + str(h) + "," + str(g) + "," + str(m) + "\n")


print("""read-all.py - Displays temperature, pressure, humidity, and gas.
Press Ctrl+C to exit!
""")

try:
    sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except (RuntimeError, 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)
            t = sensor.data.temperature
            p = sensor.data.pressure
            h = sensor.data.humidity

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

                data = i2c.read_word_data(addr, config)
                raw = swap16(int(hex(data), 16))
                raw_s = sign16(raw)
                volts = round((Vref * raw_s / 32767), 4)
                print(volts)
                
                m = volts
                write_csv(t,p,h,g,m)
    
            else:
                print(output)

        time.sleep(1)

except KeyboardInterrupt:
    pass
 


1秒刻みでしばらく取ってみた結果がこちら。

 

 

密室でエアコンをつけていると風の影響で結構揺らぎますが、しっかりと値が取れていることが確認できました。

 

さて、これで実験ができるぞ!!