見出し画像

Raspberry Piで子供用に時計サイネージを作ってみた(センサー接続編)

Raspberry Piに13インチのモニタを接続して、子供がいつでも見られる時計サイネージを作った話の続編第2弾である。これまでの話は、以下の記事を参照されたい。

これまでサイネージにさまざまな機能を追加してきたが、ほぼ全てウェブの技術を使ったものばかりであった。つまり、極端な話、Raspberry Piではない普通のパソコンでもある意味可能なことばかりだった。Raspberry Piを買ったからには、やはりRaspberry Piでしかできないことの一つであるGPIO端子による入出力を試してみたい。

そこで、サイネージの画面と組み合わせてできそうなものとして、温度や湿度などのセンサーの接続を試してみた。

今回紹介する機能のコードも一部を除きほぼ全てGitHubに載せているので、詳細はコードを参考にされたい。

センサーの選択と入手

何を測定するか

Raspberry Piに接続できるセンサーは多種多様なものがあるらしい。温度センサー、湿度センサーなどすぐ実用になりそうなものから、磁気センサー、明るさセンサー、紫外線センサー、アルコールセンサー、音センサー、ガスセンサーなどなどマニアックな物理量が計測できるものも多数あり、どれにチャレンジするか迷った。

今回は最初なので「ただ表示するだけでもとりあえず役に立ちそうなもの」として温度・湿度・気圧、そして室内の換気の目安になることを期待してCO2(二酸化炭素)センサーを試してみることにした。

接続できるか・データ取得できるか

センサーの選択にあたっては、初心者なので以下を考慮した。

  1. なるべく有名で入手しやすく文献も多いもの

  2. 追加の部品やハンダ付け無しにジャンパー線とブレッドボードだけで接続可能なもの

  3. Raspberry PiからNode.jsで(※)簡単にデータ取得可能なもの(データ取得のしくみが分かりやすいもの)
    ※Raspberry Piでのプログラミングと言えばPythonがよく使われるようだが、私はPythonは不得手なので、自分の得意言語であるNode.jsでコントロールできることを条件にした。ちなみに、これまでの機能も全てNode.jsとJavaScriptで実装してきている。

まず、温度・湿度・気圧については、BME280という温湿度・気圧センサーが名高いようだったので、これを探した。見つけたのは以下のスイッチサイエンスで販売している製品だ。

BME280というのは上記製品の中央に取り付けられた小さな銀色のチップのことであり、これは「BME280を搭載した基板モジュール」ということだそうだ。この製品はピンヘッダ実装済みだったので、ブレッドボードにそのまま差し込んでハンダ付け不要で接続できる。

また、データ取得のための通信方式としてはI2Cが使えると書いてあった。I2Cというのはシリアルバスの一種で、Raspberry PiのGPIO 2と3の端子に接続することで通信できる。また、Node.jsでI2C通信をするにはi2c-busというモジュールが使える。

次いで、CO2センサーは、秋月電子が販売しているMH-Z19Cという製品を選んだ。

こちらもピンヘッダがついているため、そのままブレッドボードに差し込める。また、通信方式もUARTによる一般的なシリアル通信であり、Raspberry PiではGPIO 14と15の端子に接続することで通信できる。なお、Node.jsでシリアル通信を行なうには、node-serialportモジュールが使える。

上記2つのセンサーがいずれも私の求める条件を満たしているようだったので、購入することにした。

センサーの接続とデータ取得

Raspberry Piと接続したところ

センサーが入手できたところで、まずはとにもかくにも物理的に接続しないことには何も始まらない。データシートや他の人のブログ記事なども参考にして、ミニブレッドボード×2枚の上に以下のように配線してみた。

GND(図1の黒色の線)だけは2つのセンサーで共有している。また、MH-Z19Cの方は、向きが分かりにくいことと、両側の端子がかなり離れているので5穴×2列のブレッドボード1枚では足りないという点が要注意である。

図1.配線図
写真1.実際に配線したところ
写真2.Raspberry Piと接続したところ

温湿度・気圧センサーBME280

BME280搭載モジュールの接続は以下の通りである。

  • 「3.3V」端子 → Raspberry Piの「3.3V」端子(1番ピンを使用)

  • 「GND」端子 → Raspberry Piの「GND」端子(6番ピンを使用)

  • 「SDA」端子 → Raspberry Piの「GPIO 2(I2C/SDA)」端子(3番ピン)

  • 「SCL」端子 → Raspberry Piの「GPIO 3(I2C/SCL)」端子(5番ピン)

I2C通信でセンサーにアクセスするには、まずRaspberry Pi側でI2C通信を有効にする必要がある。「raspi-config」の設定画面で「Interface Options」→「I2C」を選択し、有効に設定して再起動すると、デバイスファイル「/dev/i2c-1」が見えるようになる。

I2C通信ではバス上で通信するためのアドレスが必要であるが、このモジュールの場合は購入時のままだと0x77である。また、Node.jsからのコントロールはi2c-busモジュールを使う。

さて、ここまでで接続は完了し、I2Cによる通信も問題無くできる見通しとなったが、実はBME280から直接取得した生の値は温度や湿度の値そのものではなく、そこから非常に複雑な計算をしなければ人間が使える数値にならないのだ。

その計算処理は、スイッチサイエンスのサイトに掲載されていたデータシート内にサンプルコードとして書かれており、その処理を実装したbme280というNode.jsモジュールがすでに存在する。普通であればそれを使えばよいのだが、今回はデータシートの記載内容を少しでも理解してみようと思い、あえて車輪の再発明を承知で自作してみた

最終的に、bme280モジュールの出力と比較して自作モジュールの正しさを検証し、これでなんとか気温・湿度・気圧の数値は取れるようになった。

CO2センサーMH-Z19C

もう一方のMH-Z19Cの接続は以下の通りである。

  • 「Vin」端子 → Raspberry Piの「5V」端子(4番ピンを使用)

  • 「GND」端子 → Raspberry Piの「GND」端子(6番ピンを使用)

  • 「Rx」端子 → Raspberry Piの「GPIO 14(UART/TXD)」端子(8番ピン)

  • 「Tx」端子 → Raspberry Piの「GPIO 15(UART/RXD)」端子(10番ピン)

UARTによるシリアル通信を行なうには、同じく「raspi-config」の設定画面で「Interface Options」→「Serial Port」を選択し、有効に設定(Login shellの質問は「No」、有効化の質問に「Yes」と回答)して再起動しておく。すると、デバイスファイル「/dev/serial0」が見えるようになる。

Node.jsからシリアル通信を行なうには、node-serialportモジュールを使う。こちらは、先ほどのBME280と比べると通信方法もデータの取得も非常に簡単であった。計測値読み取りのコマンドを送信すると、CO2濃度の値(ppm)が16ビットの数値としてそのまま送られてくる。こちらの値を取得するモジュールもNode.jsで自作した

これで、CO2濃度も取得できるようになった。

グラフの表示

バッチ処理による自動記録

センサーから取得した値をサイネージに表示するにあたっては、現在の値だけでなく、直近の過去の値も合わせてグラフにして表示したいと思った。そのためには、グラフ表示のアプリが起動していない場合でも、定期的にセンサーにアクセスして数値を記録しておかなければならない。

そこで、Node.jsでセンサーからの値をファイルに記録するバッチスクリプトを作成し、cronで1分ごとに実行することにした。最大で直近5日分をJSON形式で記録し、古い記録は自動的に消去する。同じ名前のファイルを上書き更新していくので、ウェブページからは単純にそのJSONファイルをAjaxで取得するだけで常に最新のデータが取れるという寸法だ。

完成へ

ここまで準備できれば、あとはもうサイネージに表示するウェブページを作るだけだ。ここから先は知っている分野なので、もう自分の好きなように自由にやらせてもらう。笑

気温・湿度・気圧・CO2濃度と4つの計測値を表示するので、画面を十字に4分割してそれぞれグラフと現在の値を表示することにした。

折れ線グラフを表示するJSはこれまた自作した。これこそ車輪の再発明の最たるものであることは分かっているが、こういうのを何度でも一から自作するのが私は楽しいのである(材料を取り寄せて手料理を作りたくなる気持ちと似ている)。工数をかけてわざわざ再発明するという選択の自由があるのも個人開発の良さであろう。

そして完成したのがこちらだ。

写真3.完成した画面

ほぼ事前にイメージした通りのものができた。気温などは普段から目にする値であるが、時系列の変化が見られるようになったのは興味深い。CO2濃度に関しては、これまで全くなじみのない数値であったが、日中窓を開けて換気している間は濃度が大きく低下したりしている様子が分かって、こちらも面白かった。なお、ふりがなは娘が読めるようにするためのものである。

ちなみに、センサーを配置したブレッドボードは、そのままでは危ないと思い、厚紙で箱を自作してその中に格納した。箱は、サイネージのモニタの裏にRaspberry Piとともに貼り付けた。

写真4.厚紙で自作したセンサー格納用の箱
(CO2センサーが稼働して赤く光っているのが分かる)
写真5.箱を閉じたところ

おわりに

今回は、これまで製作してきた時計サイネージにセンサーの部品を接続するという「いかにもRaspberry Piらしいこと」を初めてやってみたが、手で触れる物理的な部品からの信号が画面上のプログラムで操れるデータに手軽に変換できるというのは非常に楽しかった。また、電子回路の知識がほとんど無くても、通信規格やセンサーの仕様に従ってプログラムを組むだけで計測値が取得できてしまうのは、大変便利なものだと実感した。

一方で、単なるプログラムと異なる点は、当たり前であるが部品は物理的なものなので、追加するとなると重さと体積の考慮が必要となってくることだ。モニターアーム1本の先端に全てがくっついている我が家の時計サイネージでは、この重さと体積の追加は大きな問題である。今回追加したセンサーの箱は、以下の写真のように他のケーブルに引っ掛ける形でなんとかモニターの裏に隠した形だ。

写真6.時計サイネージのモニターの裏側

この設置形態を取っている限りすぐに限界は来てしまいそうだが、また何か使えそうな部品とそれを使ったアイデアが思いついたら試してみたいと思う。

今後も引き続き、この時計サイネージへの機能追加にとどまらず、Raspberry Piでできることをいろいろ試していってみたいと思っている。

(最後までお読みいただきありがとうございました。)

この記事が参加している募集

私の作品紹介

つくってみた

この記事が気に入ったらサポートをしてみませんか?