GroveはSeeedが開発したハードウェアのコネクターのシステムです。
最近は多くのセンサーがGroveに対応するようになってGroveで大抵のセンサー測定は事足ります。
その昔、秋葉原で初めてGroveのきっとを見たときは「こんなの買ってもやれること限られるだろ?」と思って買おうと思わなかったんです。(当時はRaspberry PiでGroveが使えることを知りませんでした)
しかし、とあるハッカソンでGroveの心拍センサーを使ったときに「なんか使いやすいなこれ」と思ったんです。
心拍センサーなんてあんまり他で見たことありませんし、なんか扱いが面倒くさそうでしたけどGroveで使えるように設計されていてよくできてるなと感心しました。
それ以来、いろんなGroveのモジュールを買い集めては試すようになり、すっかりGroveの虜になりました。
特にRaspberry Piで使うときにはピンの番号をいちいち調べるのが面倒なのでGrove Base Hat を使ってGroveと連携すればRaspberry PiでGroveモジュールを使うのが簡単になります。
前置きが長くなりましたが、今じゃ気になったGroveモジュールを見つけては買っているとあんまり使う機会がなくそのまま積みモジュールが増えていくわけですw。
で、今回はその積みモジュールの一つである「Grove VOC and eCO2 Gas Sensor」を触ってみたいと思います。
ドキュメント
Seeedから出している大抵のGroveモジュールにはドキュメントが存在します。
もちろん、このモジュールにもドキュメントがあります。
それがこちら↓
きほんはこれをベースにすすめていきます。
インストール
grove.py
今回は「Grove Base HAT for Raspberry Pi」を使うので、以下のコマンドでgrove.pyをインストールします。
curl -sL https://github.com/Seeed-Studio/grove.py/raw/master/install.sh | sudo bash -s -
ライブラリのインストール
このセンサーにはSGP-30が使われています。そしてこのセンサーを使うときには別途ライブラリーをインストールする必要があります。 ライブラリは以下のコマンドでライブラリをクローンします。
git clone https://github.com/Seeed-Studio/Seeed_Python_SGP30.git cd Seeed_Python_SGP30 sudo python3 setup.py install
サンプルコードの実行
サンプルコードは公式ドキュメントにある以下のコードを動かしてします。
import seeed_sgp30 from grove.i2c import Bus sgp30 = seeed_sgp30.grove_sgp30(Bus()) while True: data = sgp30.read_measurements() co2_eq_ppm, tvoc_ppb = data.data print("\r tVOC = {} ppb CO2eq = {} ".format( tvoc_ppb, co2_eq_ppm))
実行すると以下のエラーが出ました。
ImportError: cannot import name 'SMBusWrapper' from 'smbus2' (/usr/local/lib/python3.7/dist-packages/smbus2/__init__.py)
ドキュメント通りに実行してこんなことになることあるのか?と思うのですが、オープンソースってたまにそういうことありますねw。
で、さすがにこのまま終わるわけにはいかないので、なんとかすることにしました。
なんとかしてみた
このセンサーにはI2Cが使われており、seeed_sgp30の大元のライブラリであるsgp30にはsmbus2が使用されています。
そのときにSMBusWrapper
を呼び出そうとしているようです。
とりあえずsmbus2でSMBusWrapperがメソッドとしてあるのか調べてみましたが、それらしき記述は見当たりませんでした。 (それはエラーになるな…)
そして、sgp30のライブラリのソースを確認してSMBusWrapperがどこで使われるのか確認したら以下のmain関数で使われていました。
def main(): with SMBusWrapper(1) as bus: sgp=Sgp30(bus,baseline_filename=BASELINE_FILENAME+".TESTING") print("resetting all i2c devices") sgp.i2c_geral_call() print(sgp.read_features()) print(sgp.read_serial()) sgp.init_sgp() print(sgp.read_measurements()) bus.close()
1箇所だけしか使われていなかったのでこれは修正はそこまで大変ではありませんね。 でもどう修正すればいいのか悩みつつもう一回smbus2のレポジトリのREADMEにあるサンプルコードを眺めてたら以下の記述を見つけました。
from smbus2 import SMBus with SMBus(1) as bus: bus.pec = 1 # Enable PEC b = bus.read_byte_data(80, 0) print(b)
さっきのmain関数によく似ています。
なんだ、簡単に修正できるじゃないかw。
ライブラリの修正
というわけでRaspberry Piにインストールしたライブラリのソースを直に修正しちゃいます!
修正するのは、/usr/local/lib/python3.7/dist-packages/sgp30/sgp30.py
です。
まずは2行目のライブラリのインポートの記述を以下のように修正します。
from smbus2 import SMBus, i2c_msg
そして、118行目からのmain関数にあるwith構文を以下のように修正します。
修正点としては、SMBusWrapper(1)
をSMBus(1)
にしました。
ついでにwith構文を使っているので関数の一番下にあるbus.close()
を削除します。
def main(): with SMBus(1) as bus: sgp=Sgp30(bus,baseline_filename=BASELINE_FILENAME+".TESTING") print("resetting all i2c devices") sgp.i2c_geral_call() print(sgp.read_features()) print(sgp.read_serial()) sgp.init_sgp() print(sgp.read_measurements())
もう一回動かしてみた
ライブラリを修正できたところでもう一回サンプルコードを動かしてみます。
するとセンサーの値がスムーズに取れました。
いい感じですね👍
tVOC = 13 ppb CO2eq = 400 tVOC = 8 ppb CO2eq = 401 tVOC = 18 ppb CO2eq = 413 tVOC = 11 ppb CO2eq = 408 tVOC = 14 ppb CO2eq = 409 tVOC = 8 ppb CO2eq = 413 tVOC = 14 ppb CO2eq = 407 tVOC = 9 ppb CO2eq = 407 tVOC = 8 ppb CO2eq = 401 tVOC = 6 ppb CO2eq = 403
センサーの値が変わらないときにはセンサーに軽く息を吹きかけるとセンサーの値が変化すると思います。
まとめ
今回はGrove VOC and eCO2 Gas SensorをRaspberry Piで動かしてみました。
ライブラリの問題でうまく動きませんでしたが、原因が単純で修正も簡単で拍子抜けしました。
ただ動かしてみたネタを書きたかったのに、図らずもエラー対処記録になってしまいましたがネタとしては程よい感じでしたw。
さて、修正をPRしないと…