この記事は新歓ブログリレー 2020 の 55 日目の記事です。
こんにちは。@nari です。普段は競技プログラミングとかCTFとかTwitterとか睡眠とかカブとかしてます。
外出自粛のまま 4 月に入り、一ヶ月が経ち 5 月になってしまいました。私は M2 なのですが、このような状況でもゼミは普通にあり、zoom で資料を読むのにも慣れてきたところです。今月からは講義も始まるとのことで、ますます家でカメラを見つめる時間が長くなることでしょう。
さて、こういったリモートワークでは、自宅環境を見直すことで進捗効率の向上が図れることが知られています。 PC や机や椅子については目に見えて分かるため簡単に対策出来ますが、リモートワークが徐々に浸透するにつれ、 二酸化炭素濃度 を気にする人をよく見かけるようになりました。
言われてみるとたしかに、大学構内や社内では通学通勤の手間がかかるものの進捗は比較的よい効率で出来ていた気がします。一方で、家に帰ったりそもそも家から出なかったりすると、(おふとんがあるものの)すぐに眠くなったり注意が散漫になったりしていた気がします(個人の感想です)。
大学や会社といった環境では二酸化炭素濃度を1000ppm以下に保つための設備が存在しており、進捗に適した空気になっていた、ということらしいです。机や椅子が硬いしノートPCなのにプログラミングが捗っていたのは、周りの目線のような環境以外にも、目に見えない工夫がなされていたから、だったのかもしれないですね……
ということで、換気タイミングを通知するために二酸化炭素濃度計を手に入れようと思ったのですが、有名なものは売り切れていたり、ログを取れなかったりしたので、本記事では二酸化炭素濃度センサーである MH-Z14A を購入し、それを Arduino ライクな ESP-WROOM-02(ESPr Developer) と繋いで二酸化炭素濃度計を作ってみました。
注意書き
この記事では二酸化炭素濃度と人体の影響についての記述がいくつかありますが、私自身は医学的な勉学を積んでおらず、引用しているソースについてもあくまでネット検索で見かけたものでありそれらが全て正しいとは限りません。
この記事で扱っている内容はあくまで個人の感想であり、参考程度の判断材料としてご利用ください。
二酸化炭素濃度について
さて、そんな二酸化炭素濃度についてどれほどの値だと進捗に適しているのか、まずは調べてみます。
まず先程も出た ppm という単位について、これは parts per million のことで、よく使われるパーセント(%, percent) が ppc (parts per cent) であることから分かるように、全体の 100 万分の 1 を表す数値が 1ppm となります。気体の場合は体積比になるので、1000ppm なら空気全体の体積の 0.1% を占める体積を表すことになります。
次に具体的な二酸化炭素濃度の数値について、以下のページを参照すると次のような値がわかります。
- 400ppm : 外気の二酸化炭素濃度
- 1000ppm : ビル衛生管理法等で規定されている上限
- 1500ppm : 学校衛生基準で望ましいとされている基準
これらの値から、およそ 1000ppm あたりが基準となっていることがわかります。では実際に人体へ倦怠感等の影響を及ぼすのがどれほどかという話になるわけですが、これについては感覚的なところもあるからか明確なソースはわかりませんでした。
以下の pdf では「二酸化炭素そのものは 10,000ppm を超えてはじめて人体に何らかの影響」を及ぼすが「高いと換気不足が考えられ、その他の汚染物質などの濃度も高くなっている可能性が高い」としています。
https://www.niph.go.jp/soshiki/09seikatsu/arch/002.pdf
一方で以下の pdf では孫引きになってしまいますが「 1000ppm を超えると倦怠感、頭痛、耳鳴り、息苦しさ等の症 状を訴えるものが多くなり、フリッカー値(フリッカー値が小さいほ ど疲労度が高い)の低下も著しい」とされています。
またインターネットの記事でよく引用されている、ニューヨーク州立大学とローレンス・バークレー国立研究所による研究では、(英語読めないので図をさらっと追っただけですが) 600ppm / 1,000ppm / 2,500ppm の3つの環境での活動への影響について調べ、 より低い濃度がより高いパフォーマンスを出している ということを結論づけています。
二酸化炭素濃度というものが連続値であり、どういった影響を与えるかというところが感覚的なものである以上、厳密にどこからが良くてどこからが悪いという値を調べることは難しいと思いますが、より低いほど良い環境であり、その指標として 1,000ppm 以下という基準が存在する、ということのようです。元も子もありませんが、要は 「そんなことより換気だ!」 ということです。
以上を踏まえ、また CO2-mini という既存の二酸化炭素濃度計の基準を パクり 参考にし、以下の基準で二酸化炭素濃度計を作っていきます(というかこの基準を鵜呑みにして良いか確認するためにここまで調べました、一応理系学生ですからね)。
- 800ppm 以下 : 良い
- 800ppm 以上 1,200ppm 以下 : 注意
- 1,200ppm 以上 : 悪い (要換気)
参考にした二酸化炭素濃度計 : CO 2モニター CO2-mini | 自然環境測定器 - 製品情報 - 計測器のカスタム
作るもの
MH-Z14A で二酸化炭素濃度を計測し、その数値を UART で ESP-WROOM-02 に送信、数値に応じて LED の色を変えつつ、 PC へシリアル通信で数値を出力するデバイスを作ります。
ついでに Ruby でその数値を受け取って DB に記録したり、Ambient にデータを送信したり、Slack に通知したりします。
用意したもの
今回、二酸化炭素濃度計を作るにあたって用意したものは以下のとおりです。
- MH-Z14A : 二酸化炭素濃度センサー
- ESPr Developer(互換機) : ESP-WROOM-02 搭載の開発ボード
- コミケ93で頒布されていたものです
- 今回は Wi-Fi は使ってないので Arduino でも大丈夫だと思います
- PL9823-F5 : フルカラー LED
- 同上です
- ブレッドボード
- ジャンパワイヤ 7 本以上
- ピンヘッダ(4 ピン)
- Pro micro で余ってたやつをニッパで切断しました
- micro USB Type-B ケーブル : PC との接続用
- はんだごて・はんだ : MH-Z14A とピンヘッダのはんだ付け用
- PC
組み立て手順
まず MH-Z14A にピンヘッダをはんだ付けします。今回は UART (シリアル通信)を使うので T | R | V+ | V-
の箇所に付けます。
付けたら以下の写真のとおりにブレッドボードに刺します。簡単ですね。
図にするとこんな感じです。
fritzing 使ったの初めてで、MH-Z14A に対応するパーツを配布してる人がいなさそうだったので、代わりに MH-Z14 を使っています。4 本配線が伸びてるのは V- | V+ | R | T
だと思ってください。
フルカラー LED は今回は抵抗内蔵なので抵抗を使っていませんが、内臓じゃない場合は必要になるかと思います。あとどれに何繋ぐかは気をつけてください。
ジャンパワイヤの色は写真と合わせてるだけで、写真の方の色にも特に意味はありません。好きな色を使うと良いと思います(多分)。
図: fritzing を利用して作成
ライセンス: CC-BY-SA 3.0MH-Z14 CO2 sensor: http://fritzing.org/projects/mh-z14-co2-sensor
ライセンス: CC-BY-SA 3.0
著作権者: JurgenG
備考: MH-Z14 パーツのみを利用、MH-Z14A の代替ESPr Developer: https://github.com/houtbrion/fritzing-parts/tree/master/ESP-WROOM-02/ESPr Developer
ライセンス: CC0 1.0 Universal
著作権者: houtbrion
今回、MH-Z14A との通信では SoftwareSerial を使うため、12 を TX、13 を RX としています。また LED は 14 に繋ぎます。
後はお使いの OS で Arduino IDE をインストールして、ESP-WROOM-02 のための設定をします。時代の変化とか環境差とかあるので「ESP-WROOM-02 Arduino IDE」とか「ESPr Developer Arduino IDE」とかでググってください(丸投げ)。以下のプログラムを考慮した設定は次のとおりです。
- 環境設定の追加のボードマネージャとして
https://arduino.esp8266.com/stable/package_esp8266com_index.json
を指定する - ボードマネージャから esp8266 の最新版(執筆時点で 2.6.3)をインストール
- ツールを次の通り設定(書いてないのは多分デフォルト)
- ボード: "Generic ESP8266 Module"
- Upload Speed: "115200"
- CPU Frequency: "160 MHz"
- Crystal Frequency: "26 MHz"
- Flash Size: "2MB (FS: 1MB, OTA: ~512KB)"
- ものによっては4MBらしい
- Flash Mode: "QIO (fast)"
- Flash Frequency: "80 MHz"
- Reset Method: "dtr (aka nodemcu)"
- シリアルポート: (環境依存)
- 今回はフルカラー LED を使っているため、ライブラリとして
Adafruit NeoPixel
をインストールする
適切に設定をした後、以下のプログラムを書きます。
https://github.com/n-ari/co2-monitor/blob/master/sketch/co2.ino
後は PC とデバイスを micro USB ケーブルで繋いで書き込めば完成です。実際に Arduino IDE のシリアルモニタで見てみると以下の画像のように出力されていると思います。delay(60 * 1000);
の箇所で1回ごとに1分待つようにしているので、結果を早く見たい場合は delay(5 * 1000);
のように書き換えると良いと思います。
最初の一行は ESP-WROOM-02 起動時の出力で、これだけ遅い bps で出力されているため文字化けしています。ここは無視して大丈夫です。
プログラムの簡単な解説
今回はシリアル通信で MH-Z14A のデータを取るため、ESP-WROOM-02 側にもシリアル通信用の TX/RX を用意する必要があります。
ただ、ハードウェアシリアル通信は PC との通信用に使っているため、今回はソフトウェアシリアル通信を使います。SoftwareSerial co2Serial(12,13)
として、IO12 ピンを TX、IO13 ピンを RXとしてそれぞれ使うことにしています。基本的には通常の Serial
と同様に使えます。
CO2 濃度の読み取りコマンドは https://www.openhacks.com/uploadsproductos/mh-z14_co2.pdf を参考に実装します。書いてあるバイト列を投げれば良いだけです。たまに読み取り値がバグって 50000ppm になって窒息しちゃうので、読み取った 9 バイト目のチェックサムをちゃんと検証するようにしています。
ちなみにキャリブレーションコマンドも用意されていますが、今の所使う予定はありません。なので参考値程度ということになりますが、気になる人はキャリブレーションコマンドを投げることでキャリブレーション出来るのでやってみてください。
また、通電後 3 分程度は preheat といって値が安定しません(だいたい 410ppm を指す)。値を見るだけなら気にする必要はありませんが、ログを取りたい場合は邪魔なので適切に待ちます。上記のプログラムでは、起動直後で 410ppm 以下なら値を無視するという処理にしていますが、410ppm 以下がデフォルトな環境だと永遠に動かないと思います(上がったら動き出すので目的からすれば問題ない気はしますが)。
その他プログラム
その他、ESP-WROOM-02 からシリアル通信で流れてきたデータの取得から、ローカルの DB と Ambient へのデータの登録、換気を促す Slack への通知などをする Ruby プログラムを以下のリンクに示します。シリアル通信さえ受けられれば、任意の言語で実装できると思います。
https://github.com/n-ari/co2-monitor/blob/master/co2.rb
Ambient との通信については、公式の Python 用ライブラリのコードを見て Ruby で書き直しています。
参考: https://github.com/AmbientDataInc/ambient-python-lib
また、今回は ESP-WROOM-02 を使っているため、やろうと思えば PC にシリアル通信せずとも単体でインターネットにデータを送信できます。が、私の持っていたハードウェアは Wi-Fi 通信の感度があまり良くなく、Wi-Fi ルータに接近させないと通信が難しかったためこの形になっています。
お金と時間に余裕があれば、別のマイコンを買って試してみたいところです。
結果
実際に測定したデータについて、Ambient にログを送っています。そのうち非公開にしますが、現在そのチャートを公開しているので、以下の URL からリアルタイムで計測されている様子が見れます。
https://ambidata.io/ch/channel.html?id=20794
以下の図は私が実際に 1 日の二酸化炭素濃度を測ったものです。
また、Slack への通知もうまく行っています。起きている時間では一時間ごとに濃度をお知らせしてくれます。
まとめ
二酸化炭素濃度計をマイコンと組み合わせることで作ってみました。こういうことはどちらかというとロボット技術研究会の方があってる気がしますが
今回は二酸化炭素濃度を測るデバイスを作成しましたが、図らずも電子工作に興味が出てしまったので、また何かセンサーを買ってみたいなと思いました。プログラミングとはまた違って、手に取れる形で作った結果が見られるというのは面白いので、ぜひやってみてください。
明日の担当者は @Fourmsushi です。
参考文献
記事中で出したリンクをまとめてるだけです。
- https://www.tokyo-co2down.jp/2016/06/24/30472/index.html
- https://www.niph.go.jp/soshiki/09seikatsu/arch/002.pdf
- https://www.mhlw.go.jp/seisakunitsuite/bunya/kenkou_iryou/kenkou/seikatsu-eisei/gijutukensyuukai/dl/h23_3.pdf
- https://ehp.niehs.nih.gov/doi/10.1289/ehp.1104789
- それぞれ二酸化炭素濃度の基準について参考にしました。
- https://www.kk-custom.co.jp/emp/CO2-mini.html
- 売り切れた二酸化炭素濃度計であり、基準値の参考にしました。
- https://dgl.tokyo/publication
- C93で買って
積んでいた本とマイコンで、とても助かりました。今回の動機の一つです。
- C93で買って
- http://fritzing.org/projects/mh-z14-co2-sensor
- https://github.com/houtbrion/fritzing-parts/tree/master/ESP-WROOM-02/ESPr Developer
- それぞれ fritzing による作図で利用しました。
- https://www.openhacks.com/uploadsproductos/mh-z14_co2.pdf
- MH-Z14A のマニュアルです。シリアル通信する際のコマンドについて書かれています。
- https://github.com/AmbientDataInc/ambient-python-lib
- Ambient へのログ送信の実装の参考にしました。