hogehoge, world.

米国カリフォルニアのソフトウェアエンジニアがIT・自転車・音楽・天体写真・語学などについて書く予定。

HM3301で山火事ベイエリアのPM2.5濃度を測る

現在カリフォルニアは史上最大規模と言われる山火事の最中である。うちの近所はこんな様子↓で、二週間程燃え続けてやっと70%鎮火と、だいぶ収まってきた感じではある。

f:id:tomoto335:20200902074349p:plainhttps://www.fire.ca.gov/

ところがその結果大気汚染がひどいこと↓になっている。これでも先週よりは少しはましになりつつあるのだが、健康に影響が出る(Unhealthy)と呼ばれるレベルである。 

f:id:tomoto335:20200902075059p:plainhttps://www.purpleair.com/

このような状況だと、コロナ対策で外気を吸う機会は少ないにしても、窓を開けて換気をすべきかどうか(ちなみに私はエアコンのない家に住んでいる)とか、室内でもマスクをすべきかどうかとか、いろいろ判断に困る。そもそも窓を閉めた状態で汚染はどの程度室内に入り込むのかも、まったく知らないのである。

また、この汚染度の数字は日や時刻によって大きく変わる。あるとき真っ赤だったのが夜になると急に緑になることもある。適切な判断をするにはリアルタイムにデータを知りたいという気もする。

というわけで、センサーを入手してポータブル大気汚染度測定器を仕立て、これらの疑問に答えられるようになってみよう、というのが今回のお題である。下の写真はM5StickCとM5Atomを使って作った完成品と、そのデモビデオである。

f:id:tomoto335:20200902162127j:plain

https://youtu.be/89IInh19yVU

PM2.5センサーの入手

大気汚染度を知るには、いわゆるPM2.5という種類の粒子が空気中にどれだけいるかを測ればよいと思われる。調べてみると、その手のセンサーでホビー向けに使えるのはPMS5003とHM3301の二択のようだ。

まずPMS5003は例によってAdafruitで取り扱われている。

www.adafruit.com

そしてHM3301の方はSeeedがGroveモジュールとして販売している。

www.seeedstudio.com

データシートを見ると能力的な仕様はそっくりなので、計測ハードはたぶん同じものだろう。HM3301の方が新しい・安い・I2C対応・Mouserに在庫がある・Groveコネクタ変換基盤が付いていてお得(もし邪魔なら外すこともできそう)ということで、こちらを2個買うことにした。

M5StickC/M5Atomへの接続 ― 電圧に注意!

ポータブルにしたいので、コントローラーはM5AtomとM5StickCを使ってみることにした。ブレッドボードでは持ち歩きにくかろう。

M5Atom/M5StickCにはGroveコネクタが付いているのでHM3301とは簡単に接続できる…はずが、実は電圧に注意が必要である。というのは、M5Atom/M5StickCのGroveコネクタはVCC=5V/信号線=3.3Vだが、HM3301のGroveコネクタは3.3V統一/5V統一のどちらかなのである。つまり、HM3301のVCCに5Vを入れると信号線も5Vになってしまい、M5Atom/M5StickCの方が耐えられない可能性がある。

この電圧問題については以下の記事↓でよく整理されている。簡単な話題ではあるが、人に説明するときなど、こうやって整理されているのはありがたい。 

The 5 Volt Danger with the M5StickC | Tinkerfarm.net

今回の場合、オプションは以下のいずれかだろう。

  1. 気にせずそのまま接続する(上の記事のオプション3-2)。ESP32の信号線は公式には3.3Vだが、現実には5Vかけてもある程度大丈夫だったりするようで、先の記事でもI2C程度で壊れるリスクは低いだろうと言っている。実は上のビデオではこの手を使っており、幸い壊れずに動いている。

  2.  GroveコネクタのVCC端子を引き出して、M5Atom/M5StickCの3.3V出力につなぐ(上の記事のオプション2)。HM3301のVCCに3.3Vを供給すれば、信号線も合わせて3.3Vになるのだ。シンプルで優等生な解だが、Groveコネクタのうまみが半減する。

  3. HM3301のセンサーモジュールをGroveコネクタ変換基盤から取り外して、直接M5Atom/M5StickCにつなぐ。工作が必要だが、結果的にはストレート且つ小型化にもなる。

オプション3は説明が必要だろう。SeeedのHM3301解説サイトにあるデータシートや基盤の回路図をよく見るとわかるのだが、実はHM3301のセンサーモジュール(青い箱)本体はVCC=5V/信号線=3.3Vであり、M5Atom/M5StickCと一致しているのだ。これをGroveコネクタへの変換基盤がわざわざ電圧変換し、VCCと信号線が同一の電圧になるよう調整しているのである。これはコントローラーが3.3Vでも5Vでも使えるようにという親切な配慮なのだが、コントローラーがM5Atom/M5StickCの場合には「たまたま合ってるのに余計な事してくれるなヽ(`Д´)ノ」という不幸な話になる。

そこで、青い箱を基盤から引っぺがして(2本のプッシュピンを抜いて粘着テープから無理矢理引きはがす)、基盤と接続している8Pコネクタを抜き、同じ形のコネクタを自作すればM5Atom/M5StickCと直接接続することができる。これで電圧は適正になるし、基盤もなくなりコンパクトにもなる。

基盤から取り外したところ:

f:id:tomoto335:20200902092511j:plain

コネクタの配線:

f:id:tomoto335:20200902092852j:plain

最低限、赤(VCC)/黒(GND)/緑(SDA)/青(SCL)の4本だけつなげば動く。追加の2本、白(RESET)/黄(SET, スリープモード=ファンを止めて電気を節約するのに使う)はオプショナルで、使わなければ浮かせておいて構わない。ケーブルの反対側はGroveコネクタでもHAT用のピンでも自分の目的に応じてお好きなように。なお上の図のように4ピンコネクタを作ると、M5StickCのHATにさした場合にG26/G36がSDA/SCLになるが、どうやらG36はI2Cには使えないという制限があるらしくハマってしまった。M5StickCで使いたければG36ではなくG0にささるようにコネクタを作る必要がある。

センサーデータの取得

Arduino用ライブラリがSeeedから出ているが、まぁいろんな意味でしょぼい。しょぼいものを使わされるのは嫌いだし、もともかなり簡単なものだったので、自分で書き直してここに公開した。

GitHub - tomoto/Arduino_Tomoto_HM330X: Arduino library for HM330X dust sensor

2020/9/14追記: Arduinoライブラリマネージャに登録され、Arduino開発環境から直接ダウンロードできるようになった。

f:id:tomoto335:20200915021107p:plain

I2Cから取れる情報は、以下の3種類である。

  1. PM1.0/2.5/10濃度(μg/m3) "standard particulate matter"
  2. PM1.0/2.5/10濃度(μg/m3) "atmospheric environment"
  3. 直径0.3/0.5/1.0/2.5/5.0/10μm以上の粒子の大気0.1Lあたりの数(個/0.1L)

1.と2.の違いはわかりにくいのだが、このセクションのNoteにある説明を何度も読んでようやく解釈できた。おそらく、光学的に計測した値から粒子の重量を出すのに粒子の種類を仮定する必要があって、そのため測定環境はどんな性質のものか選ぶ必要があるのだ。金属粒子が飛ぶような工場の中なら1.を、公害物質が飛ぶような外気なら2.を使いなさい、ということである。(ちなみに別のフォーラムには気圧補正の違いじゃないかと言っている人がいて、最初はわかりやすいそちらの説を信じたのだが、結局違うという結論に達した。)

また3.にも謎があって、2個のセンサーのうち1個はそれらしい値が取れるのだが、もう1個は常にゼロである。データシートからはHM3301はそもそも3.は取れないモデルのようにも見えるし、Seeedのページの出力例もゼロになっているので、取れない方がハズレなのか、取れる方がアタリ(何故か上位モデルのHM3602が入ってるとか?)なのか、どうもよくわからない。今のところ使う予定はないので、少なくとも一台取れるのならよしとしておく。 

Air Quality Indexの計算と表示

アメリカで大気汚染の指標としてよく用いられるのは、Air Quality Index (AQI)とかNowCastとか呼ばれている値である。本来は過去の値を加重平均したりするらしいが、今回はリアルタイムに目安を知りたいだけなので、下記Wikipediaの説明を参考に、現時点のPM2.5の濃度から変換表でちゃちゃっと求めることにする。

en.wikipedia.org

カラーコードも概ね決まっているようなので、そのまま使わせてもらう。上限はVery unhealthyくらいまでまともに表示出来ればいいことにする。例えばM5AtomならLEDが5x5なので250まで25段階、色は5段階で表示すればよかろう。

AQIメーターのコード

ライブラリの中にexamples/M5Stack/AirQualityMeterとして入れてある。サンプルと呼ぶには少々大袈裟かもしれないが、まあいいだろう。

コードは読んでもらえばいいので細かい解説はせず、大まかな方針の話だけ。

  • アプリケーションロジック本体は共通にし、M5StickCとM5Atomそれぞれ用にビルドできるようにする。
  • M5Atomライブラリはここで書いた通り害しかないので使わない。
  • M5StickCは小さな内蔵電池で駆動するユースケースを考えて、電力節約の工夫を入れる。ボタン一発で電源をON/OFFできる、LCDの輝度を下げて必要なときだけ明るくできる、通信エラーから回復できなければ自力で電源を切るなど。M5Atomはあまり努力しなくてよい。余裕のある外部バッテリーで使うし、そもそもペリフェラルに流れる電流をカットできないのであまり報われない。

測定結果とまとめ

デモ動画を見てもらうと感じがわかると思うが、以下のような評価である。

  • 一番気になるセンサーの信頼性だが、これは「信頼できる」と言ってよさそうである。レスポンスはよく(場所を変えれば値が敏感に変わる)、再現性は高い(同じ場所に戻れば同じ値に戻る)。
  • 外気をあちこち測定すると、各種情報サイトで発表されている値とよく整合する。これらのサイトが情報源にしている low cost IoT sensor は実は同じブツであることも多いのかもしれない。
  • 窓を閉めただけの屋内は、外気が150程度(Unhealthy)の場合、60~70程度(Moderate)にとどまる。また少しくらい窓を開けてもそんなに上がらない。外気では宙を舞っている粒子が屋内だと床に落ちるからだろうか。隙間の多い古いアメリカの家屋なので心配だったが、PM2.5粒子がそんなにがばがば入ってくるわけではないようだ。
  • 閉めた部屋の中で空気清浄機を回すと、同じく外気が150程度の場合、10~20(Good)と全く問題のない状態まで持っていくことができる。
  • このように、外が150程度の場合には屋内環境にあまり問題は生じないが、時折外気の状態が一時的に悪くなることがあり(>200程度, Very Unhealthy)、そうなると屋内も100を超える。こうなると室内でもN95マスクをした方がよい、といった判断をすることができる。

山火事は鎮火しつつあり、大気も正常化の兆しを見せているが、それでももうしばらくAQI 100越えの状態は続くだろうし、突発的に上がることも十分にあるだろう。このように状態を数値化できると安心だし、効率的な行動・管理につながるので大いに意義があると言えよう。

最後に富豪刑事風に今回の支出を挙げてみよう。

M5StickC Dev Kit $11.95
M5Atom Matrix $8.95
HM3301 x2 $29.90 x2
コネクタ作成キット $23.99
M5Stack & Mouserの送料 $15.22
合計 $119.91

コネクタ作成キットというのはこんな↓パッケージだが、この "Here's what you've got, you know what you've got to do" と言わんばかりのド直球でわかりやすい中華エレクトロニクスのノリは嫌いではない。

f:id:tomoto335:20200903024826j:plain