4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでI2Cセンサ(CCS811/BME280)を読んで色々表示してみた(Matplotlib, Dash)

Last updated at Posted at 2020-11-26

CCS811/BME280 on Raspberry PI 4

CCS811とBME280をI2Cで接続して、値を読む。

  • CCS811: 等価CO2濃度と総揮発性ガス濃度を測定できる
  • BME280: 温度、湿度、気圧を測定できる

コードは以下にある。
https://github.com/nv-h/i2c_env_sensors

ついでにopenweathermapの予報データの表示と、気象庁のアメダスの観測データも同時に表示するようにしてみた。(2020/12/01更新)

newplot (3).png

Check I2C connection

i2c-toolsが必要。これで接続を確認する。
CCS811は0x5B(default)、BME280は0x77(default)にあるはず。うまく見えると以下のようになる。

$ sudo apt install i2c-tools
$ ls /dev/i2c*
/dev/i2c-1
$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- 5b -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77

接続を確認できたら、ハードウェアIDを確認してちゃんと動いているか確認。

#!/bin/bash

CCS811="0x5b"
BME280="0x77"
I2C_BUS="1"

# CCS811
# https://cdn.sparkfun.com/assets/learn_tutorials/1/4/3/CCS811_Datasheet-DS000459.pdf

ccs811_hw_id=$(i2cget -y ${I2C_BUS} ${CCS811} 0x20)
ccs811_hw_version=$(i2cget -y ${I2C_BUS} ${CCS811} 0x21)
# ccs811_fw_boot_version=$(i2cget -y ${I2C_BUS} ${CCS811} 0x23 w)
# ccs811_fw_app_version=$(i2cget -y ${I2C_BUS} ${CCS811} 0x24 w)

echo "CCS811 HW_ID: ${ccs811_hw_id} HW Version ${ccs811_hw_version}"
# echo "FW Boot Version ${ccs811_fw_boot_version}"
# echo "FW app  Version ${ccs811_fw_app_version}"

# BME280
# https://cdn.sparkfun.com/assets/learn_tutorials/4/1/9/BST-BME280_DS001-10.pdf

bme280_hw_id=$(i2cget -y ${I2C_BUS} ${BME280} 0xd0)
echo "BME280 HW_ID: ${bme280_hw_id}"

Read the sensor values

I2Cのデバイスは/dev/i2c-1みたいな感じの場所にいるが、アクセスするのに管理者権限が必要なので、自分をi2cというグループに登録しておく。
こうしておくと管理者権限無しでI2Cデバイスにアクセスできる。

sudo usermod -aG i2c $USER

こんかいはPythonを使いたいのでPythonからI2Cデバイスにアクセスできるsmbus2をインストールする。

pip install smbus2

このリポジトリのコードを使うと以下のようにセンサの値を取得できる。

from bme280 import BME280

bme280 = BME280()
p, t, h = bme280.get()
print(f"{p:7.2f} hPa, {t:6.2f} C, {h:5.2f} %")

from ccs811 import CCS811

ccs811 = CCS811()
ccs811.compensate(h, t) # if needed
voc, co2 = ccs811.get() # May need to exec several times to get correct values
print(f"TVOC:{voc:4d} ppb, eCO2:{co2:4d} ppm")

Example

Command Line

example.pyにコマンドラインの例を示す。
このコードは、標準出力に1秒毎にセンサで取得した値を吐く。
たまにOSErrorになるが、気にしていない。あと、CO2濃度はしばらく経たないとちゃんとした値にならない。
データシートによると20分位は安定しないのと、48時間のエージングが必要らしい。

#!/usr/bin/env python

from time import sleep
from bme280 import BME280
from ccs811 import CCS811

ccs811 = CCS811()
bme280 = BME280()
p, t, h = bme280.get()
ccs811.compensate(h, t)

while(True):
    try:
        p, t, h = bme280.get()
        voc, co2 = ccs811.get()
        print(f"{p:7.2f} hPa, {t:6.2f} C, {h:5.2f} %, TVOC:{voc:4d} ppb, eCO2:{co2:4d} ppm")
        sleep(1)
    except OSError:
        # i2c bus somtimes cannot access
        continue
    except KeyboardInterrupt:
        break

GUI (matplotlib)

example_gui.pyにmatplotlibでのGUI表示の例を示す。
このコードでは0.2秒毎にグラフを更新している。特に意味はないが高速に動かすと動いている感が得られる。
(PythonでGUI画面とリアルタイムグラフ表示するの成果を流用)

  • 必要なパッケージ: pip install matplotlib numpy

example_gui_matplotlib.jpg

GUI (dash)

save_csv.pyで1分ごとにデータ取得して、dash_from_csv.pyでそれをWeb UIで表示する。
表示にはdashを使用した。

  • 必要なパッケージ: pip install dash pandas numpy
  • 注意:
    • 温度: 基板の発熱があるのでセンサの値から-2℃しているが、環境によって変わると思う。
    • Time-zone: Asia/Tokyo (UTC -9 hours)に固定している。

example_gui_dash.jpg

無限にCSVファイルに追記することになるが、読み込みより表示のほうが大幅に負荷が大きいため表示データを1周間ごとに制限している。
さらにデータの個数は間引きして表示している。(1分間隔なんて高頻度に取得するなってことだけど、デモだとたくさん待たないといけないので...)

  • 知見
    • dashはコードを変更すると動的に表示が更新されて楽しい
    • Rasberry PIでdashは重すぎるかと思ったけど割とサクサク
    • pandas初めて触ったけどめっちゃ便利なので活用したい

もしOpenWeather MapのAPI keyを持っている場合、以下のようにAPI keyをセットすると予報データも同時に表示される。(このキャプチャ画像は古くて、今は最初に貼ったようにアメダスデータの表示と予報の表示にも対応している)

echo "API_key = {API key}" > ./openweathermap/api_key.py

newplot.png

4
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?