この記事は techtekt アドベントカレンダー2021 の 最終日の記事 です。 24日目は吉次さんの "なぜDone is better than perfectなのか考えてみた" という記事でした🎉
こんにちは! エンジニアリング統括部でフロントエンドエンジニアをしております21卒の竪山(たてやま)です。 今日はRaspberry Piというマイクロコンピューターを使って水槽を手軽にモニタリングしよう!というお話をいたします。
ただ…先輩方の記事を拝見していると少し俺テイスト間違えてね…?と不安になっております笑 (ナイトプールに競泳水着🏊♀️)で来てしまったような気持ちですが頑張ってラスト、泳ぎ切っていきます。
※竪山は退職していますが、本人の同意を得て、掲載を継続しています。
はじめに
自宅には60cmの水槽があります。水槽では水草と魚を育てているのですが、彼らのためにはCO2添加器とヒーターが欠かせません。 十分な光合成を行うためのCO2がなければ水草は綺麗に育ちませんし、熱帯魚は冬場水温が下がりすぎると死んでしまいます。
CO2はスマートコンセントによりライトと共にタイマー動作をしており、ヒーターは設定水温を自動的に一定に保ってくれるため、基本的には任せきりです。 しかしこの二つの機械にはある不安がつきまといます。壊れた時……どうする?🤔
実際CO2添加器は弁の設定を誤って大量のCO2が放出され、炭酸水のようになり大絶滅を招いていしまった過去があります…😇 ヒーターも寿命になり暴走してしまった場合、(エビ🦐もいますので)水槽がダシの効いたスープになってしまうことでしょう。 これをなんとしても防がなくてはいけません。
変化を見守りたい!
- そこで常に水槽の状態をチェックできるようなシステムをつくり、事故を防ぐ体制を作っていけたらなぁ…というのが今回のテーマです💪🏻
初めにCO2とpHについて👩🔬
CO2の添加量については水のpH(現在の読み方はピーエイチです)を計測して知ることができます。 pHは1〜14で表され、小さくなるほど酸性、大きくなるほどアルカリが強いことを示します。 水草水槽にとって最適なpHは5.5~7あたりが良いとされており、CO2の添加量が増えるとpHが下がって**いきます。
要するにpH下がりすぎるとまずいから見ようね!水温上がりすぎもダメよ!
ということです
今回つくる仕組み
今回は次の2点の仕組みをお手軽に作っちゃおうかな?と思っております。
- pHと水温を計測しLINEに通知する📟
- 計測した値をCSVに入れる
調べたらほぼ同じようなことをされている方が複数いらっしゃったのでこちらを参考にしながら作っていけばよさそうですね!
詳細な手法についてはこちらのブログをご参照ください
Raspberry Pi で 金魚水槽管理システム を構築 - Advent Calendar - HomeMadeGarbage
homemadegarbage.com
Raspberry Pi + Node-RED + DS18B20 防水型温度センサー でメダカ水槽の温度を管理する (1) | THE POOH FILES
使うものの説明
RaspberryPi zeroW
ちいさなコンピューター(マイコン)で、とても安価に手に入ります。
今回の主役です。GPIOピンと呼ばれる端子がついており、センサーと繋ぐことでセンサーの値を取ることができるようになります。
ザ・電子工作といった見た目ですね🤖
Raspberry Pi Zero W - スイッチサイエンス
ピンにジャンパワイヤーを繋ぎ、センサーと接続させます。
*なおラズパイは品薄&高騰が続いておりぶっ壊したら後がありません news.mynavi.jp
ラズパイについてはこちらのサイトが28回にわたって⁉️ 丁寧に説明してくださっています。興味ある方にはおすすめです。
アナログ出力pHセンサー
https://www.amazon.co.jp/gp/product/B07VWFNBL8/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1www.amazon.co.jp
ブログ参考にさせていただきました。セッティングがやや面倒そうです。
防水水温計
同じく参考にして購入しました。3本入り。そんなにいらないですね……ケーブルがぐにゃぐにゃしていて取り回ししやすそうですマイコンボード (pro Micro)
pHメーターとラズパイの仲立ちをしてくれます。 彼自身はOSを持たず、書き込まれたプログラムを実行するだけです。 自作キーボード作りに使われたりします。
詳しく
購入したpHセンサーはアナログ出力により電圧を返しますが、ラズパイにはアナログピンがないためこのArduino Leonard互換マイコンを使いアナログ出力をとり、microUSBを介してラズパイにデジタル値として返します。
ジャンパワイヤ.ブレッドボード.抵抗
自宅にあったものを使いました。ブレッドボードとジャンパワイヤーを使うと簡単にセンサーなどのパーツを繋げられます
はんだごて
自宅にあったものを使いました。Amazonで一番安かったものです
pH校正液
水に溶かすだけで使えます。
つくりかた
今回、センサーの値をラズパイで取得し、LINEに送ったりするフローはNode-REDというサービスを使うこととしました
Node-REDについて
さまざまな機能をもつノードを繋いでシステムを構築するビジュアルプログラミングのようなサービスです。 自宅にあるラズパイの中でNode-REDを動かし、値を計測します。少しのJavaScriptの知識があれば使えます。 非エンジニアの方や、電子工作シタコトナイヨ〜〜な方でも気軽に使えます💪🏻。
詳しく
- インストールして起動するとlocalhost:1880で立ち上がります。ノードを繋いでデプロイを押せば直ちに変更が反映される優れものです。ノードはmsgというJSONをやりとりし、標準入出力はmsg.payloadを利用します。
- functionパレットにはJSで記述ができ、自由にkey-valueを追加できるので柔軟な設計が可能です。
- 条件による分岐やcatchなど様々なノードが用意されているほか、今回利用するラズパイGPIO I/Oや各種センサー専用のノードも用意されており、気軽に電子工作が楽しめます。
- 各種APIを叩けるほか、APIエンドポイントを設定することで外部からのrequestにも応答できます
ちょっと使ってみる
ラズパイはピンに1の信号を送ると電気を流し、0を送ると電気を止めます。
- 専用のパレッドnode-red-node-pi-gpioをつかいます。
- node-pi-gpioを使うと簡単にラズパイのGPIOピンにアクセスできます。
今回はこのようにしてみます。
こんな感じでノードを繋いで、 これ↑を押すと16番のピンに信号が送られます。
ラズパイの16番のピンとマイナス極(GND)をLEDにつなぎ、Node_REDで1を押すとライトがつきます。
0を押すと消えます。
問題なく使えそうですのでセンサーたちを繋いでいきましょう!
測定機器のセッティング
温度センサーをつなぐ🌡
- 温度センサーをつなぎます。 (写真を撮り忘れました……)
- 温度センサーは専用のノードnode-red-contrib-ds18b20-sensorが用意されているので本当に簡単に値を取れます。
センサーをラズパイに繋いだ状態で左のボタンを押します
緑色のログ出力ノードから値が出力されました
いい感じに取れていますね!
pHメータの設定
- まずラズパイ仲立ちであるこいつ(proMicro)を設定します
動作するコードをUSBでMacとつなぎArduino IDEを使って書き込みます。
- こちらを参考にしました:Arduino IDEのインストールと設定 (Windows, Mac, Linux対応) – Indoor Corgi
- コードについてはこちらを参考にしつつ、ひとまず生の電圧を返すようにしました。(0リセットのため)
はんだづけをしてpHメータの基盤部分とつなぎます。
pHメーターのセンサー部分はこんな感じ。この先端を水中に入れpHを測定します
上述のサイトを参考に0リセットとpH計算式の決定をしました
……が初めうまく0リセットができず、はんだづけをやり直しました。
はんだづけと0リセットを行い、pHBuffer液で校正をしました。
- センサーは直接のpHではなく電圧を返します
- pH4.00 6.86 9.18の3種の校正液を使い、そのとき得られた電圧をもとに関係式を作りました。
- その結果
pH = -5.3958*電圧 + 21.429
の関係式が求められましたので、こちらをマイコンボードのコードに記入します - 最終的なproMicroのコードはこちら
// .ino拡張子のファイルです byte input; const int analogInPin = A3; int sensorValue = 0; unsigned long int avgValue; float b; int buf[10],temp; void setup() { Serial.begin(115200); } void loop() { input = Serial.read(); if (input == '1') { for(int i=0;i<10;i++) { buf[i]=analogRead(analogInPin); delay(10); } for(int i=0;i<9;i++){ for(int j=i+1;j<10;j++){ if(buf[i]>buf[j]){ temp=buf[i]; buf[i]=buf[j]; buf[j]=temp; } } } avgValue=0; for(int i=2;i<8;i++) avgValue+=buf[i]; float analogValue = avgValue/6; float pHVol=(float)avgValue*5.0/1024/6; float phValue = -5.3958*pHVol + 21.429; // 計算式はpH校正液をもとに算出 Serial.println(phValue); } }
Node-REDの設定
- シリアル通信と呼ばれるものでマイコンボードとラズパイはやりとりしています。
このやりとりを簡単に制御できるノードもNode-REDには用意されています
ラズパイとマイコンボードをmicroUSBで接続し、シリアル通信を有効にします
ノード設定画面で利用するシリアルポートを指定するとリクエストを送り、マイコンボードが動作し、値を返してくれます。便利すぎか?
requestで1を送ると先ほど書いたコードが実行され、センサーからの値が返ってきます
LINEに値を送る
取られた値をスマホで見れるよう、 LINEbotを作成し、messagingAPIを使って計測結果をLINEで送ります。 developers.line.biz
今回はLINEbotの友達全員にメッセージを送るブロードキャストノードを使いました。
ノードを作る
これらのノードを繋ぎ、定期的に水温とpHが送られるようにします。フローを実行するinjectノードを定期実行するように設定しました。
さらに一回の測定ではばらつきが大きいので10回平均を結果として返すようにします。
- 完成したノードがこちら
詳しく
- getphとgetTemplatureでそれぞれの値を取得し、ph格納と数値を配列に格納ノードで整形しています。(outputは全てmsg.payloadに格納されて上書きされるので移動させています。)
- switchで計測回数を確認し、10回計測したら上のノードに、違えば下のサーキットループに戻します。
- CalcAvgpH、CalcAvgTempはcalcノードを利用しました。こいつは配列に対しての統計処理をお手軽にしてくれるノードです
完成がこちら
ただこのままだと設置ができないのでブレッドボードをどかして直接配線します
水槽横に仮設置し、センサーを水中に入れて測定しました。
動作間隔を2分にしたのでやべー人からのLINEみたいになっていますが、ちゃんと測定できているようです
動作中はこのようにライトがピカピカします
異変に気づく
設置したのは火曜夜でしたが、水曜朝にあることに気が付きます
………………pHが低すぎるpH3~4だと炭酸水〜レモン水レベルであり、魚にいい状況とは言えません
正しく校正してあるのでそこまでずれはないはずです。水流があるため不安定になるはずですが……
しかもこの時間帯はCO2スイッチはオフになっているはずです。
原因判明
CO2添加器のスイッチが切れているのにCO2がちょぼちょぼ出ていました……
スマートコンセントによってタイマー制御しており、オフになるのは夜間でした。そのため出ていることに気づけなかったようです
CO2を制御する電磁弁が故障しているようです。
グラフを書く
どのような推移になっているのか確認するため、CO2添加器を取り外したうえでグラフ化する準備をしましょう CSV出力するノードを利用して、ラズパイにCSV保存していきます。
モニタリング開始から24時間グラフ
- pHと水温の24時間グラフです。途中pHが跳ね上がっているタイミングでCO2添加器を取り外しています。
一時的に上振れていますが、その後pH4.5あたりに落ち着いているのが見られます
水温についてはサーモスタットが一定温度を維持しようと動いているのが可視化できていいですね。 サーモスタットの設定温度を26℃にしているので25℃を下回ると加温され、一定まで上がるとスイッチが切れる を繰り返している様子がグラフからわかります。
さらに2日
- CO2添加器をとめて2日経過しました。pHが5前後で安定してきているようですね。まだ低い状態ですが、CO2添加器止めた結果が可視化できて満足です。
最後に
技術的なあれこれをはしょってざっくり書いてみました!作業時間としては1日で終わっています。 今後はグラフの自動作成、室内気温の取得、異常値になれば装置の強制停止などの機能も追加していこうかなと思っております。 むずかしくごちゃごちゃ書いてしまいましたが、思っている以上に手軽なのでご興味ある方は気軽に挑戦されてみてはいかがでしょう🙋♂️
先輩方の素敵なアドベントカレンダーのトリを務めさせていただけて光栄でした🥰 読んでいてとても楽しかったので是非来年も……!と思っております。 ありがとうございました🥳🥳
竪山 裕文 Hirofumi Tateyama
エンジニアリング統括部 サービス開発部 第1グループ エンジニア
2021年4月に新卒でパーソルキャリアへ入社。フロントエンドエンジニアとして転職者定着支援サービス、社内向けサービスの開発に従事。現在は退職。
※2021年12月現在の情報です。