ObnizにCo2センサを接続 その1
とある事情からObnizにSCD30というCo2センサを接続することになり、簡単だと考えていたが、行ってみると想定外に苦労したので、参考になる様記録しておきます。
今、コロナ禍の中で密の指標としてCo2センサにて検出することが行われているようです。Amazon等で検索してみると安いものは2000円からありますが、あまり安いものは精度に少し難があるようです。
|Co2センサの種類
詳しいわけではないが、分類すると以下の種類となります。
1. NDIR方式 (Non Dispersive Infrared)
2. MOX方式 (Metal Oxide)
NDIR方式は閉空間に取り込んだ気体に赤外線を照射し、ガス分子が特定の波長の光を吸収することを利用して二酸化炭素を検出するもの。
MOX方式は温めた金属酸化物が揮発性有機化合物(TVOC)との反応により抵抗値が変わることを利用して検出するもの。後者は二酸化炭素を検出するものではなく、ガスの総量(種類の区別ない)を測定しているため、二酸化炭素相当を推定しているものとなります。
それぞれの特徴としては、
・NDIR方式
精度:高い (直接Co2の波長吸収を見るため)
応答:早い (検出ダクト内への気体の取り込みによる)
電流:多い (100-200mA 赤外LED照射するため)
価格:高い (構造的に複雑なため)
・MOX方式
精度:低い (TVOCからCo2相当を推定するため)
応答:遅い (金属皮膜の化学反応を見ているため)
電流:低い (10-20mA 抵抗値検出のため)
価格:安い (1chip構成のため)
あくまで想定ですが、Amazonなどで売っている表示が付いている安い二酸化炭素濃度計はMOX方式が使用されていると思います。ただ、正確な数値を取得する必要がなくガイドラインとして見る上では、十分なのかもしれません。
|Co2センサーモジュール
今回Obnizに接続してCo2濃度を見るセンサーの選択ですが、ざっと調べると趣味の工作的に使われているのは、以下のようです。
・NDIR方式
MH-Z19B (Amazonや秋月で販売。中国の会社の製品です。)
S-300L-3V (スイッチサイエンスで販売。 韓国の会社の製品です。)
SCD30 (Sensirion製でSeeed社がGrove化。Sensironはスイスの会社。)
・MOX方式
CCS811 (スイッチサイエンス等で販売。チップはams製。)
BME680 (Amazonやスイッチサイエンスで販売。チップはBosch製。)
・価格 (執筆現在)
MH-Z19B : 3,699円 @Amazon
S-300L-3V :10,725円 @スイッチサイエンス
SCD30 : 6,279円 @Seeed
CCS811 : 2,828円 @スイッチサイエンス
BME680 : 3,080円 @スイッチサイエンス
価格的にはMOX方式の方が割安で接続事例が多くお手軽な感じですが、今回は正確な数値を見てみたい事もあり、NDIR方式のものを選択しました。
MH-Z19Bは偽物も出回っているようなのと、手作り感いっぱいな外観で少し精度が心配な点があるので、Obnizに接続している人がいなさそうなSCD30を選択しました。Sensirion社はセンサーのものづくりに定評が高いのと、スペックシートからもそれがとても感じられました。
|Grove - CO2 & Temperature & Humidity Sensor for Arduino (SCD30) - 3-in-1 の購入
購入はスイッチサイエンスからもできますが、Seeed社のホームページからの方が少しお得なようです。ただ、出荷が中国からとなりそうで少し時間がかかる可能性がありそうです。
今の時期はどこも品薄のようで、スイッチサイエンスでは在庫切れとなっていました。(運良く在庫が切れる前に購入できました。)
青い基板の上にはSensirion社のSCD30がそのまま乗っているようで、その一部のパッドをGroveコネクタまで配線しているようです。Groveコネクタのシルク印刷を見るとGND/VCC/SDA/SCLが割り当てられており、SCD30のパッドの位置と照らし合わせると信号は一致しています。
|SCD30を動かす
製品タイトル名にもあるように、Arduino用のライブラリをSeeed社が公開しており、Wikiに詳しい使い方が掲載されています。使い方を掲載しているプラットフォームは現時点でArduinoのみのようで、今後Raspberry Piにも対応する方向のようです。ひとまずArduino系で動かします。
Getting Startedには、
1. Seeeduino V4.2 + Base Shield (Arduino IDEベース)
2. Wio Terminal (ArduPyベース)
の2通りの方法が掲載されており、手元にWio Terminalがあることからまずは2.で試そうと思いますが、「ArduPy」とは何?からスタートです。
ArduPyはMicroPythonからArduino APIを使用できる様にしたもので、既存のArduinoライブラリを変換して使用するようです。aipというArduPy用のCLIが準備されており、それを経由してライブラリの変換やパッケージマネージャ、FWの書込み等もを行う形になります。ひとまずArduPyのWikiを見ながらMacにインストールしてみました。
順序として、
1. homebrewからPython3が実行出来るようにインストール
2. pip3にて「ardupy-aip」パッケージをインストール
3. aipにて「seeed-ardupy-scd30」ライブラリをインストール
4. aipにてwio terminal用のsdc30ライブラリを含むFirmwareをビルド
5. aipにてwio terminalへ作ったFirmwareを書込み
6. SCD30を動かすpythonスクリプトファイルを作成
7. aipから作成したスクリプトの実行指示
理解しにくいのが、Pythonのパッケージとしてaipというardupy用のライブラリマネージャがあり、aipはファームウェアのビルドやwio terminalへの書込みも担っていてデバッグコンソールも兼ねるという内容となるが、文章での表現が難しいので、図に表すと以下のようになります。
流れとしては ArduPy Get Started に丁寧にかかれているのでそんなに迷わないと思いますが、補足点をいくつか。
3. aipにて「seeed-ardupy-scd30」ライブラリをインストール
ここは以下でSeeed社のGitHubから取って来るので問題ないと思います。
# aip install Seeed-Studio/seeed-ardupy-scd30
4. aipにてwio terminal用のsdc30ライブラリを含むFirmwareをビルド
以下のコマンドにてビルドを行います。
# aip build
この時にwio terminalを接続しておかないとエラーが発生します。
WARNING: please plug in a ArduPy Board or specify the board to build!
<usage> aip build [--board=<board>]
ERROR: Exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/pip/_internal/cli/base_command.py", line 181, in _main
assert isinstance(status, int)
AssertionError
ファームウェアのビルド時に接続されているボードのIDを読み込んで、該当のボードに合うファームをビルドするためと思います。現時点でArdypyの実行環境はWio TerminalとSeeeduino XIAOの2つがあるのでそれぞれのファームが違うんだと思います。
5. aipにてwio terminalへ作ったFirmwareを書込み
以下のコマンドにてファームの書込を行います。
# aip flash
この時にwio terminal側をファームのブートローダーモードにしておかないとエラーが発生します。(ここが一つ目のハマりどころです。)
・・・・・・・・・
writeBuffer(scr_addr=0x20004034, dst_addr=0x8000, size=0x1000)
[== ] 7% (40/516 pages)write(addr=0x20004034,size=0x1000)
SAM-BA operation failed
ブートローダーモードとは、wio terminalのFAQに乗っている通り、横のボタンを素早く2回スライドします。
これを行ったあとにflashコマンドを打つことでファームの書込が始まります。(マニュアルには特に書かれてなかったので、本来はコマンドの中でブートローダーモードに入るのかもしれませんが、そうはならなかったです。)
6. SCD30を動かすpythonスクリプトファイルを作成
SCD30を動かすためのpythonスクリプトは、Seeed wikiのGrove - CO2 & Temperature & Humidity Sensor (SCD30)の説明書の中にあり、この中のSoftwareの説明部分にコードが書かれています。このコードをコピーして「ArduPy-scd30.py」というファイル名でデスクトップあたり保存しておきます。
7. aipから作成したスクリプトの実行指示
GroveコネクタにSCD30を接続したwio terminalがPCに接続されている状態で、以下の実行コマンドを発行します。
# aip shell -n -c "runfile /Users/macbook/Desktop/ArduPy-scd30.py"
(※path名はご自分の環境に読み替えてください。)
通常はここでpythonコードが実行されて、温度/湿度/Co2が画面に表示されるはずですが、以下のようなエラーが出ました。(2つ目のハマりどころ)
Positional argument (/dev/cu.usbmodem141101) takes precedence over --open.
Connected to ardupy
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 36, in <module>
File "<string>", line 31, in main
NameError: local variable referenced before assignment
ここでかなり色々と調べたのですが、原因がわからず途方に暮れていた時にふとSeeed wikiの動作している写真を見ると、SCD30がwio terminalの左のGroveコネクタにつながっています・・右側につなげていました。(こんな単純な事ですが、気づかない時は気づかないです。)
|SCD30 無事に動く
紆余曲折がありながら、Ardupy上で無事にSCD30が動きました。
深くは追ってませんが、Ardupy Libraryの中のSCD30のコードは、一部変換されたコードとpython向けのwrapperのコードがあるので、実際の下回りの動きはArduino LibraryのSCD30のコードが該当するのだと思います。
さて、Obnizで動かす事を目的としている中で、なぜ苦労してまで他のプラットフォームで動かしたかと言うと、新たにコード実装する前に実際のI2Cの中の波形を見たかったからです。単にコードを移植して動かしてみれば動く可能性もありますが、確実に動いている波形を押さえて、周波数や電圧などを確認しておくことが、結果的に近道になると考えているからです。
ということで、今回はObnizに触りもしませんでしたが、次回は動いたSCD30の信号線の中を追っかけて行こうと思います。その2に続く。
この記事が気に入ったらサポートをしてみませんか?