久々に電子工作ネタ。
最近はずっとNode-REDでデータを取ってきたけど、今回はうまくいかなかったのでPythonを使いました。
参考にさせていただいた記事はこちら。
使ったもの
- BME680モジュール@秋月電子
- 16bitADコンバータ(MCP3425)
- RaspberryPi 2B
まずはMCP3425とBME680をラズパイに繋げて、それぞれ単独で動作確認。
これは無事成功。
通信はどちらもI2Cを使っています。
I2Cのアドレスの確認コマンドは下記。
sudo i2cdetect -y 1
これで2つ分のアドレスが表示されていることを確認します。
今回の場合は、68と77の2つが表示されました。
ちなみに、68がADコンバータ(MCP3425)、77がBME680のアドレスです。
次に、単独で動かしていたプログラムを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秒刻みでしばらく取ってみた結果がこちら。
密室でエアコンをつけていると風の影響で結構揺らぎますが、しっかりと値が取れていることが確認できました。
さて、これで実験ができるぞ!!