編集履歴一覧に戻る
kouのアイコン画像

kou が 2022年09月26日06時06分00秒 に編集

初版

タイトルの変更

+

Eltressを使ったCO2濃度監視システム

タグの変更

+

ELTRES

+

IOT

+

SPRESENSE

+

CO2

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

ライセンスの変更

+

(MIT) The MIT License

本文の変更

+

# 概要 部室の喚起状態が悪かったので、Eltresを活用してCO2濃度を可視化して警告することで換気を促すシステムを作成しました。 # きっかけ 大学で所属しているサークルの部室でCO2濃度を測定してみたところ、人が多い時には5000ppmを超えている異常な状況で最悪の場合は健康被害が出るような非常にまずい状態だったため、しっかりと換気をするためにCO2濃度が一定以上だと換気を促すようなシステムを作成しました。 # システム構成 今回作成したシステムの構成図は次のような感じです。 今回はシステム全体でクラウドを活用しており、なるべく既存のフレームワークやシステムをフル活用していくことで少し実装を手軽にしました。 ![システム構成図](https://camo.elchika.com/ca7ab36f28042fc55d3c5db5c4cef6e32e47d5c4/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f35666235366438622d353239622d343033372d386631612d373763323030343132313539/) システムが少し複雑になっているのでハードウェア部分とソフトウェア部分に分けてそれぞれ説明していきます。 ## ハードウェア構成 ### CO2センサ部分 CO2センサ部分に関してはクレスコさんのCO2センサーを用いたサンプルプログラムと同じ構成です。使用した部品は以下の通りです。 | 部品名 | 値段 | |:---:|:---:| | SONY SPRESENSE メインボード | ¥6,050 | | SPRESENSE用ELTRESアドオンボード | ¥10,978 | | Passive GPS Antenna uFL - 15mmx15mm 1dBi giain | ¥580 | | LPWA用アンテナ | ¥770 | | Sony Spresense 用 CO2センサー(SCD41) Addon ボード|¥7,920| これで合計は驚愕の26,298円です。普段だったら高級であまり触る機会がない部品ですが、今回はコンテストのモニターや、勉強会の方など提供していただきました。 CO2センサを除く部品は[秋月電子](https://akizukidenshi.com/catalog/top.aspx)にて、CO2センサに関しては[NextStep](https://nextstep.official.ec/items/57108630)から購入できます。 ### アラート部分 #### 部品構成 | 部品名 | 値段 | |:---:|:---:| | 赤色灯(赤色回転灯)DC12V ASS-12|¥1,640| |スイッチングACアダプター12V4.17A|¥1,650| |大電流大型リレーモジュールキット 12V版|¥520| | ESP32-DevKitC ESP-WROOM-32開発ボード|¥1,480| 合計で5,290円ぐらいです。 こちらのアラート部分は視覚的にわかりやすくということで用意しました。個人的に秋月にある赤色灯が気になっていてIoTと組み合わせたら面白そうだなーということで使ってみました。 回転灯の電圧が12Vで突入電流が4Aぐらいなのでどうしてもそれに対応するACアダプターとなるとお高めになってしまいます。今回はシンプルに途中にリレーモジュールを挟んであげることでESP32から制御できるようにしました。 ### 配線図 モジュールに関してはハンダ付けした上で図のように配線していきます。今回使用したリレーモジュールは制御信号電圧が2V〜10VなのでESP32のIO電圧3.3Vで十分に制御することが可能です。注意ポイントとして、VCCはリレーの駆動電圧であるため12Vを供給してあげる必要があるのでACアダプからの12V電源をそのまま流用させてもらいました。 また、今回使用した回転灯の端子部分が4mm丸型のオスメスのコネクタ(詳しい名前は不明)なので必要な端子を購入して圧着しました。 なお電流に関しても最大で4A程度流れる可能性があるので、パトランプと接続する部分の配線に関しては適切な太さのものを使用した上で、基板に関してもショートしないように適切に絶縁処理などを施してください。発火など事故があっても責任は負えませんので自己責任で悪しからず... ![配線図](https://camo.elchika.com/8c6a846207b645d96e7f1d1ee2636810a61e25fd/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f33386363636639612d393461392d343761332d613735622d363530383936663966383434/) # ソフトウェア構成 ## CO2センサからのデータ取得 今回使用したSPRESENSE用のELTRESボードは株式会社クレスコ・デジタルテクノロジーズ(以下クレスコ)が作っているもので、秋月電子の方から購入するとELTRES回線の使用料とオンラインのデータ解析ツールであるCLIP Viewer Liteが最大4ヶ月無料で付属してきます。 こちらに関してはクレスコ様から提供して頂いたので無料で使うことができていますが、普通に購入した場合は無料期間の4ヶ月を過ぎると送信間隔によって値段は変わりますが1年間当たり約4,000円程度の利用料が必要となるので注意が必要です。ただ、1ヶ月当たりで考えれば約330円程度で利用できるので解析ツールも付いてくると考えるとコスパは良さそうです。 ## CLIP Viewer Lite さて、CO2センサから取得した値はELTRES回線を通してクレスコのサーバーへと届けられます。CLIP Viewer Liteを使うと、図のように送信時間やペイロード、受信強度などを確認することができます。また、ペイロードタイプとして温度、湿度、CO2濃度、加速度などが用意されているので指定されたフォーマットでデータを送信してあげると下の図のように自動的にグラフ化して表示してくれます。 ![CLIP Viewer Liteでのデータ](https://camo.elchika.com/0472267a19a92a6a80a6ac5939a065806cdbec78/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f64613665646661312d373130662d346635652d613132352d616465383633383064393235/) ![CLIP Viewer Liteでのグラフ](https://camo.elchika.com/cd678fbc0154585ceb00839ad3a50b30575b3996/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f39373064396463352d623131352d343763312d626263622d373635623264363930363335/) データを確認するだけならこれで良いのですが、今回は一定濃度のCO2が検出された時に通知を出したり回転灯を回したりしたいので、このデータを取得して何処かしらの別のサーバーへ送る必要があります。CLIP Viewer LiteではAPI連携機能が用意されており、発行されたAPIを叩いてあげると ``` { "payload": [ { "deviceId": "********", "sendDateTime": "2022-08-07 18:46:37", "payloadType": "温湿度CO2情報", "payload": "8241eed4004230a2c04412c0~", "communicationLine": "ELTRES", "rssi": 2, "firmVersion": null, "radioQuality": null, "gps": null, "generationTime": null, "temperature": 29.853515625, "humidity": 44.158935546875, "carbonDioxide": 587, "xAcceleration": null, "yAcceleration": null, "zAcceleration": null, "pitchGyro": null, "rollGyro": null, "yawGyro": null, "airPressure": null, "pressure": null, "illuminance": null, "distance": null, "chNumber": null, "trigger1": null, "trigger2": null, "voltageInfo": null, "error": null } ], "count": 1, "result": "success" } ``` といったような感じで最新のPayloadデータを取得してあげることが可能です。なんとなくレスポンスからシステム内部でAWSを使ってそうだなぁという雰囲気がありますね。 CO2センサーからは1分ごとにデータが送られてくるので、このAPIを1分おきに叩いてあげれば最新のデータを取得することが可能になります。また、APIを叩き過ぎるとレート制限に引っかかってしまうのでデバッグの時に同時にプログラムを動かさないように注意が必要です。 このデータから今回はCO2濃度や湿度、気温などのデータを抽出してあげて管理するサーバーへと送ってあげます。 ## AWS IoT さてここまででCO2センサーから最新のデータを取得することはできますが、そのデータを視覚化したり、一定以上のCO2を検知したときにトリガーイベントを発生させたりという処理を行う必要があります。そこで今回はAWS IoTというサービスを使ってみました。前々から気になっていたのですが、触る機会がなかったので触ってみようということで試しに利用してみました。 ### AWS IoTへのデータ送信 AWS IoTではAWS IoT CoreというサービスでIoTデバイスを管理します。ここらへんの使い方はAWSのチュートリアルやクラスメソッドの記事が充実していたのでそちらを参考にしました。 AWS IoTではIoTクライアントデバイスからのデータ送受信にあたって、MQTTというPub/Sub型のプロトコルを使用しています。このプロトコルは非常にシンプルな上に軽量で特にIoT機器での通信などによく使用されています。AWSではこれにSSL/TLSによる暗号化が施されたMQTTSプロトコルを使用します。ダッシュボードでのデバイス作成時に通信に使用するデバイス証明書が発行されるのでそれを利用します。 実際にCO2センサーからデータを送るコードは[Github上に公開](https://github.com/csenet/iot)したのでそちらを参照してください。 `.env`ファイルには ``` apiKey=<Clip Viewer LiteのAPI Key> username=<Clip Viewer Liteのusername> password=<Clip Viewer Liteのpassword> awsClientId=<AWS IoTデバイスのclient id> ClipdeviceId=<Clip Viewer LiteのセンサーのデバイスID> thingName=<AWS IoTデバイスのモノの名前> awsHost=<AWS IoTデバイスのエンドポイント> ``` を記入してあげた上で、appディレクトリ以下にcertsディレクトリを作成してAWS IoTの公開鍵、秘密鍵、証明書、RootCAを保存します。詳しいコードの動かし方についてはReadmeに記載しておきますのでそちらを参照してください。 このコードを動かして、テストクライアントで確認してみると1分おきにデータがAWS IoT Coreへ送信されていることが分かります。また、このコードはサーバー上で常時動かしておく必要があるので、私はAWS Lightsail上で起動させています。 ### データの保存と可視化 AWS IoT CoreへとCO2データを送信する部分まではできますが、あくまでIoT CoreはデバイスとMQTTで通信をするためのGate Wayに過ぎません。そのため、MQTTで送られてきたデータを保管して表示するためにAWS IoT Analysisという仕組みを利用します。MQTTで取得したデータはIoT CoreでIoT ruleを指定すると別のサービスへ送ることができるため、AWS IoT Analysisへ送信します。AWS IoT Analysisでは受信したデータがChannelに届けられAWS S3(Simple Storage Service)へ生のデータが保存されます。そのデータは、Pipelineを通して無駄なデータを省いた形へ成形された上でData Storeに届きS3で保存されます。 Data Storeに保存されたデータから、一定時間ごとの平均や統計を算出したり分析することができるのもIoT Analysisの機能です。IoT Analysis上でSQLライクな形でデータセットを作成することができ、そのデータがDatasetとして保存されます。そして、Amazon QuickSightを利用することによってデータセットを可視化することができます。Amazon QuickSightはIoT Analysis以外にもさまざまなデータを可視化できるサービスですが、無料枠だと利用できる機能が少し限られてくるのは少し残念なポイントです。実際に可視化したデータは図\ref{fig:quick}のような形で、データセットを元にしてグラフを作成したり、平均値を表示したりなどダッシュボードを自由にカスタマイズして表示させることができます。また、期間を絞ったりフィルターをかけたりすることも簡単にできるので、データ分析をするには便利なツールですね(料金が高いのを除けば)。 ![Amazon QuickSight](https://camo.elchika.com/55c2c7126ba434f3c3f79d7ccb0c78de1eedfe77/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f38356234306165322d373633302d343633332d616636642d346433383337373732383333/) ### IoT回転灯とAWS IoTの接続 1500ppmを超えた時に回転灯を光らせるためにESP32とAWS IoTを接続します。MQTTのライブラリはあるのでそれを使えば実装はできるのですが、今回はMongoose OSというIoTシステムを作るときにとても便利なESP32用のOSがあるのでそちらを利用していきます。似たようなものでAmazon FreeRTOSもあるのですが、Mongooseの方が手軽そうなのでそちらを利用していきます。 Mongoose OSのセットアップはとてもシンプルです。[公式サイト](https://mongoose-os.com/docs/mongoose-os/quickstart/setup.md)のガイドに従って進めていき、ESP32をUSBで接続すると簡単にOSをインストールするとができます。また、公式でAWS IoT Coreと連携させるサンプルが用意してあるのでこの[チュートリアル](https://mongoose-os.com/docs/mongoose-os/cloud/aws.md)に従ってセットアップするだけで簡単に実装ができました。なお、サンプルのコードのledのピン番号の部分をリレーのSIGと接続されている13番ピンに変更してください。 セットアップが完了してWi-Fiに接続した後は、回転灯を固定してあげてACアダプターの電源やESP32の電源を確保してあげます。回転灯は目がつきやすい部室の棚に図のように設置しました。ESP32などの制御部分は写真では見えませんが、棚の上の部分にボックスにまとめて置いてあります。 ![設置された様子](https://camo.elchika.com/4df43ca08677d26b5145db421cc513197667d752/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f36363064383938612d356337622d346339662d383932342d313538353561326466663839/) なお、このチュートリアルではAWS IoT CoreのDevice Shadowという機能を利用しています。これはデバイスの状態を管理できる機能で、LEDがonなのかoffなのかという状態を用意すると、ESP32は自動的にその状態を取得してLEDをONにしたりOFFにしたりしてくれるのでデバイスを再起動しても問題ありません。また、deltaというTopicが用意されていて変更したい状態を指定してあげるとその差分をESP32に通知してくれる機能があります。例えば、LEDが既にONの時にONにしたいと送っても何も送信されませんが、OFFの時にONにしたいと送るとESP32に通知されるというような感じです。これにより、ESP32もその差分だけをsubscribeすれば良いので無駄な通信も減らすことができます。 ちなみにMongoose OSの良いところは、プログラムをJavaScriptやPythonなどの言語で書けるという点や、IoT向けのOSなのでAWSやAzureなどクラウドサービスとの連携がとても手軽にできるという点です。さらに、OTA(Over-The-Air)によるファームウェア更新機能もあるので一度コードを書き込んでネットに接続してしまえば、その後はパソコンにESP32を接続しなくてもネット上からファームウェアの書き換えが可能です。 実際にAWS IoTからパトランプを操作するとこんな感じです(音声なし)。 @[youtube](https://youtu.be/n4IgmXTjouU) ## 基準値を超えたときのトリガー ここでは送られてきたデータが基準値を上回った場合に警告をするために、IoT Eventというサービスを利用します。IoT Eventでは検知器モデルを作成することができ、送られてきたデータに応じてその状態を変化させることで異常な状態など色々なイベントを発行することができるサービスです。Analysisの場合と同様にIoT ruleを指定してあげてあげるとデータが受け取れるようになるので、入力値に応じて基準値を超えているかどうかを判定するために検知器モデルを作成します。今回は図のようにSafeとDangerの2つの状態を定義してあげて、1500ppmを基準として状態遷移を定義してあげました。初めはこの基準値を2000ppmぐらいに設定したのですが、CO2の可視化システムも開発しているクレスコの方に伺ったところ換気の目安としては1500ppm程度が適切だと伺い、最終的にこの値を基準としました。 ![AWS IoT Event](https://camo.elchika.com/3a2003f309c1612c6359662a02639afaa2c18e0f/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f61366665396632662d656639622d343739322d616335302d323832346363303364636637/) IoT Eventでは状態遷移をトリガーとしてAWSのサービスを呼び出すことができます。そこで今回は1500ppmを超えた際にKokenのDiscordへ通知を飛ばすために、Lambda関数を用意しました。以下に示すようなシンプルな実装で、DiscordにWebhook経由で図のような感じに通知を飛ばします。 ```javascript const axios = require('axios') const URL = process.env.webhookURL exports.handler = async (event) => { const config = { 'Accept':'applitation/json', 'Content-type':'applitation/json' } // console.log(event); const co2 = event.payload.state.variables.co2; const messageType = event.payload.state.variables.type; const postData = { username: 'CO2 Monitor BOT', content: `CO2濃度が${co2} ppmに下がりました。ご協力ありがとうございます!` } const res = await axios.post(URL, postData, config); console.log(res); }; ``` ![Discordへの通知](https://camo.elchika.com/ab2e3d71e01b7be93e1a429bb791bc5d866cbffa/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f61623332343163342d333737322d343865322d386136392d6630383164353966393564612f37363037656363312d373135642d343139392d383032372d643962396138356230366635/) Discord通知とは別にIoT EventからはDevice ShadowのStateを更新することによって、1500ppmを超えた時に回転灯を光らせるということを実装しています。 # まとめと課題 実際に部室で動いている様子を動画に収めることができなかったのですが、2か月ほど運用してみて問題なく動作しています。 今回のシステムではAWS IoTをフル活用したシステムだったのですが、実際に運用してみて分かった点としては意外とランニングコストが高いという点です。このシステムでは1分おきにデータが処理され、その度にS3にデータが書き込まれるのでかなりの頻度で書き込みが発生します。これによりS3の料金が無料枠を超えてしまい意外とかかってしまいました。また、IoT Coreなども無料ではなく、合計すると月に1,000円ぐらいのランニングコストがかかってしまいます。さすがにそれは厳しいので、今後はAWS IoTの代わりとなるシステムを開発して置き換えようかなと思ってます。システムを動かすインフラ環境は部室に用意されているので、Mongoose OSのmDashという無料のプラットフォームなどと連携させれば意外と簡単に開発できそうかもしれません。 またこのシステムを動かしてから2週間ぐらい経ちますが、アラームが点灯すると定期的に換気するようになったので部室内のCO2濃度も5,000ppmに行くこともなくかなり良い状況へと改善されました。Discordの方も部員の方からの提案で"換気"をすると"歓喜"するBotになり、換気でCO2濃度が下回ったことを確認できるようになったのでより分かりやすくなりました。今後も部室状況をネットで見れるようにするなど色々と改善をしていく予定です。