中国のお店が中国国外に売る通販モールAliExpressで、安いセンサーをいくつか購入しました。 今回はその中の1つ、二酸化炭素(CO2)濃度推測値と揮発性有機化合物(VOC)濃度が測れるSGP30が搭載されたセンサーモジュールをRaspberry Piにつないでみました。
Amazon.co.jpで売られているこちらのセンサーと同様のものと思われます。
AliExpressでの私が購入時の値段は、なんと$6.75でした!1000円近くするので高級なセンサーですね。
このセンサーはPythonから簡単にアクセスできるライブラリを公開されている方がいて、繋ぐだけで簡単にセンサーの値が読めます! とても便利ですね🥰早速Raspberry Piにつないでみましょう。
SGP30とは?
SGP30とは、スイスに本社のあるセンサーメーカーSensirionが出しているガスセンサーです。
水素とエタノールを検出でき、それをもとに演算して、総揮発性有機化合物(TVOC)と二酸化炭素(CO2)の推定値を測定できるみたいです。 演算はこのセンサー内部で行われて、マイコンからはTVOCやCO2の推定値が取得できます。
実際に二酸化炭素などを測定しているわけではなく、推定値なのでご注意ください👀
I2Cで通信することで、総揮発性有機化合物(TVOC)と二酸化炭素(CO2)の推定値のデータをマイコンで読み取れます。
Raspberry Piにつないでみよう
SGP30モジュールの準備
私が買ったSGP30モジュールはこちらです。
このモジュールはI2C通信専用のモジュールになっています。マイコンに簡単に繋げられるように、標準ピッチ(2.54mm)のピンヘッダが付属しています。 この写真はピンヘッダをはんだ付けした後のものです。
はんだごてがない方は、こちらのICテストクリップケーブルを使って、端子同士を引っかけてつかうこともできます。ピンヘッダにもスルーホールの穴にもクリップできるので便利です。ただし、ショート⚡️させないよう注意してくださいね。
I2C通信方法について
このモジュールはI2Cで通信するので、I2Cのピンに接続して…といいたいところですが、なぜかそれでは使えませんでした😥
ハッキリと理由はわかりませんでしたが、オシロスコープで見るとI2Cの信号線がLowの時でも1Vちょっと出ていたので、プルアップ抵抗の影響かもしれないと思いました🤔
※Raspberry PiのI2CバスはRaspberry Pi基板上に1.8kΩという強めのプルアップ抵抗が接続されているうえに、このSGP30モジュール基盤にも10kΩのプルアップ抵抗が実装されています。
試しにI2C bitbang機能を使ってGPIOピンを使ってI2C通信させたところ、動作させられました😊
GPIOピンでI2C通信をさせるI2C bitbangについては次の記事をご覧ください。
Raspberry Piへの接続
Raspberry Piのピンヘッダは上図のように機能が割り当てられています。 このうちI2CのピンGPIO2、GPIO3はRaspberry Pi基板上にプルアップ抵抗があります。今回はそれらのピンを使わず、ふつうのGPIOピンを使いました。
RasPiピン番号 | RasPi 機能 | BME280モジュール | 説明 |
---|---|---|---|
16 | GPIO 23 | SDA | I2Cデータ |
17 | 3V3 power | VIN | 電源(3.3V) |
18 | GPIO 24 | SCL | I2Cクロック |
20 | Ground | GND | グランド (0V基準電圧) |
これらをジャンプワイヤーで接続すると、次のようになりました。
I2C bitbangの設定
標準以外のピンでI2C通信を行うには、I2C bitbangドライバの設定をします。
Raspberry Pi上の /boot/config.txt
ファイルを開き、次の行を追加します。
dtoverlay=i2c-gpio,bus=11,i2c_gpio_sda=23,i2c_gpio_scl=2
Raspberry Piにログインして編集しても良いですし、/boot
パーティションはWindowsからも見えるので、マイクロSDカードをパソコンに挿してWindowsマシンから編集することもできます。例えば、次のようになります。
/boot/config.txt
ファイルを編集してRaspberry Piを再起動させると、I2C bitbangドライバが有効になります。
有効になっていると、/dev
以下にi2c-11
というデバイスファイルが見えます。
$ ls /dev/i2c* /dev/i2c-11
11というのは/boot/config.txt
で指定したI2Cバス番号です。これで、GPIOピンを使ってI2C通信ができるようになりました。
PythonからSGP30にアクセス
Pythonライブラリのインストール
イギリスの教育・趣味用電子機器ハードウェアメーカーの Pimoroni がSGP30のPythonライブラリを公開しているので、使わせていただきましょう😌
PyPIにも登録されているので、pipを使って簡単にインストールできます。まずはpipをインストールします。
$ sudo apt install python3-pip
続いて、先ほどのライブラリをインストールします。また、PythonからI2Cバスにアクセスするsmbus2
というライブラリもあわせてインストールします。
$ pip3 install pimoroni-sgp30 smbus2
これで準備が完了です。
サンプルプログラム
準備ができたら、次のようなプログラムを適当な名前で作成しましょう。
$ nano sgp30_test.py
中身は次のようになります。
from sgp30 import SGP30 from smbus2 import SMBus, i2c_msg import time bus = SMBus(11) sgp30 = SGP30(bus, i2c_msg) print("Sensor warming up, please wait...") sgp30.start_measurement() print("Done.") while True: result = sgp30.get_air_quality() print(result) time.sleep(1.0)
これを実行すると、センサーの値が読めます。
$ python3 sgp30_test.py Sensor warming up, please wait... Done. Air Quality: Equivalent CO2: 547 (ppm) Total VOC: 21 (ppb) Air Quality: Equivalent CO2: 400 (ppm) Total VOC: 44 (ppb) (...1秒ごとに表示が続く)
最初のウォーミングアップは20秒ほど時間がかかるようです。その後、1秒ごとにeCO2とVOCの値が出ます。 簡単に読めましたね。
この状態でも、例えばセンサーの近くでアルコール除菌ウェットティッシュを使うと一気にVOCの値が上がったりして、センサーが何かしら感知していることがうかがえます。
ただし、最初は絶対値は正確ではありません。正しく使うには準備が必要です。
正しい測定のために
私もデータシートをすべて理解しているわけではありませんが、SGP30で正確に測定するには準備が必要です。
SGP30で測定するには、ベースライン値というものを継続的にアップデートする必要があります。 最初はベースライン値が不明なため、最低12時間は電源を入れたままにしておき、ベースライン値を決定させます。 初回起動時は12時間待ってからセンサー出力値を利用するのがよいでしょう。
ベースライン値はSGP30センサーから読み出せます。12時間経過後は、1時間おきにベースライン値を読み出しておきます。 ベースライン値はセンサー電源OFFしてから1週間有効らしいので、最後に読み出した値を保存しておき、次回電源ON時にSGP30にベースライン値を書き込めば12時間の待ち時間が不要になり、直ちに有効な値を読み出せます。
また、センサー値は湿度によっても影響を受けるため、外部に温度湿度センサーを接続してSGP30に時々設定することで、 湿度の影響をキャンセルしたセンサー値が読み出せるようです。
使ってみた結果
数日間動かしてみましたが、特にアルコールウェットティッシュや洗剤などを使うとTVOCの値が跳ね上がるのがわかります。
一方でeCO2はTVOCの影響を受けて値が変わる感じもして、あまり正確に測れているような気はしませんでした。 使い方の問題かもしれませんが…。
CO2を測定するには、推定値でなくちゃんとCO2濃度を直接測定できるセンサーの方が簡単だと思いました。でもサイズが大きくなるのが悩みどころですね😅
いずれにしても、Raspberry Piから簡単に使えるセンサーですし、ぜひいろんな活用法を探してみてください!✊