水槽をラズパイで見守ろう #techtekt Advent Calendar 2021

アドベントカレンダー

この記事は techtekt アドベントカレンダー2021 の 最終日の記事 です。 24日目は吉次さんの "なぜDone is better than perfectなのか考えてみた" という記事でした🎉

こんにちは! エンジニアリング統括部でフロントエンドエンジニアをしております21卒の竪山(たてやま)です。 今日はRaspberry Piというマイクロコンピューターを使って水槽を手軽にモニタリングしよう!というお話をいたします

ただ…先輩方の記事を拝見していると少し俺テイスト間違えてね…?と不安になっております笑 (ナイトプールに競泳水着🏊‍♀️)で来てしまったような気持ちですが頑張ってラスト、泳ぎ切っていきます。

はじめに

f:id:Nif_Urchi:20211224131737j:plain
自宅の水槽水槽

自宅には60cmの水槽があります。水槽では水草と魚を育てているのですが、彼らのためにはCO2添加器ヒーターが欠かせません。 十分な光合成を行うためのCO2がなければ水草は綺麗に育ちませんし、熱帯魚は冬場水温が下がりすぎると死んでしまいます

f:id:Nif_Urchi:20211224132029j:plain
水槽のCO2添加器 上部からCO2が出ます
CO2はスマートコンセントによりライトと共にタイマー動作をしており、ヒーターは設定水温を自動的に一定に保ってくれるため、基本的には任せきりです。 しかしこの二つの機械にはある不安がつきまといます。

壊れた時……どうする?🤔

実際CO2添加器は弁の設定を誤って大量のCO2が放出され、炭酸水のようになり大絶滅を招いていしまった過去があります…😇 ヒーターも寿命になり暴走してしまった場合、(エビ🦐もいますので)水槽がダシの効いたスープになってしまうことでしょう。 これをなんとしても防がなくてはいけません。

変化を見守りたい!

  • そこで常に水槽の状態をチェックできるようなシステムをつくり、事故を防ぐ体制を作っていけたらなぁ…というのが今回のテーマです💪🏻

初めにCO2とpHについて👩‍🔬

CO2の添加量については水のpH(現在の読み方はピーエイチです)を計測して知ることができます。 pHは1〜14で表され、小さくなるほど酸性、大きくなるほどアルカリが強いことを示します。 水草水槽にとって最適なpHは5.5~7あたりが良いとされており、CO2の添加量が増えるとpHが下がって**いきます。

f:id:Nif_Urchi:20211224132238p:plain
phについて

science-log.com


要するにpH下がりすぎるとまずいから見ようね!水温上がりすぎもダメよ!

ということです


今回つくる仕組み

今回は次の2点の仕組みをお手軽に作っちゃおうかな?と思っております。
- pHと水温を計測しLINEに通知する📟 - 計測した値をCSVに入れる

調べたらほぼ同じようなことをされている方が複数いらっしゃったのでこちらを参考にしながら作っていけばよさそうですね! 詳細な手法についてはこちらのブログをご参照ください
Raspberry Pi で 金魚水槽管理システム を構築 - Advent Calendar - HomeMadeGarbage homemadegarbage.com

Raspberry Pi + Node-RED + DS18B20 防水型温度センサー でメダカ水槽の温度を管理する (1) | THE POOH FILES

min2club.com

使うものの説明

RaspberryPi zeroW

ちいさなコンピューター(マイコン)で、とても安価に手に入ります。 今回の主役です。GPIOピンと呼ばれる端子がついており、センサーと繋ぐことでセンサーの値を取ることができるようになります。 ザ・電子工作といった見た目ですね🤖

f:id:Nif_Urchi:20211224132939j:plain
ラズベリーパイ

Raspberry Pi Zero W - スイッチサイエンス

www.switch-science.com

ピンにジャンパワイヤーを繋ぎ、センサーと接続させます。

f:id:Nif_Urchi:20211224133109j:plain
ラズパイと電子工作ボードをつなぐイメージ

*なおラズパイは品薄&高騰が続いておりぶっ壊したら後がありません news.mynavi.jp

ラズパイについてはこちらのサイトが28回にわたって⁉️ 丁寧に説明してくださっています。興味ある方にはおすすめです。

tool-lab.com

アナログ出力pHセンサー

www.amazon.co.jp

f:id:Nif_Urchi:20211224133601j:plain
左下が制御基盤 右の黒い棒がセンサーです

ブログ参考にさせていただきました。セッティングがやや面倒そうです。

防水水温計

www.amazon.co.jp

f:id:Nif_Urchi:20211224133813j:plain
柔らかいケーブルです 銀色部分が温度センサーです
同じく参考にして購入しました。3本入り。そんなにいらないですね……ケーブルがぐにゃぐにゃしていて取り回ししやすそうです

マイコンボード (pro Micro)

pHメーターとラズパイの仲立ちをしてくれます。 彼自身はOSを持たず、書き込まれたプログラムを実行するだけです。 自作キーボード作りに使われたりします。

www.amazon.co.jp

詳しく

購入したpHセンサーはアナログ出力により電圧を返しますが、ラズパイにはアナログピンがないためこのArduino Leonard互換マイコンを使いアナログ出力をとり、microUSBを介してラズパイにデジタル値として返します。

ジャンパワイヤ.ブレッドボード.抵抗

自宅にあったものを使いました。ブレッドボードとジャンパワイヤーを使うと簡単にセンサーなどのパーツを繋げられます

f:id:Nif_Urchi:20211224134125j:plain
抵抗 ジャンパワイヤー ブレッドボード

はんだごて

自宅にあったものを使いました。Amazonで一番安かったものです

f:id:Nif_Urchi:20211224134312j:plain
はんだごてとはんだ

pH校正液

水に溶かすだけで使えます。

www.amazon.co.jp

つくりかた

今回、センサーの値をラズパイで取得し、LINEに送ったりするフローはNode-REDというサービスを使うこととしました

nodered.jp

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ピンにアクセスできます。

f:id:Nif_Urchi:20211224134509p:plain
rpi-gpio-outのどのpinを操作するか指定します
どのピンを使うかは画像のように指定でき、これにinputノードを繋げばすぐにアクセスできます。便利

今回はこのようにしてみます。

f:id:Nif_Urchi:20211224134845p:plain
PIN16に1を送るノードと0を送るノードをそれぞれ繋ぎます

こんな感じでノードを繋いで、 f:id:Nif_Urchi:20211224135025p:plain これ↑を押すと16番のピンに信号が送られます。

ラズパイの16番のピンとマイナス極(GND)をLEDにつなぎ、Node_REDで1を押すとライトがつきます。

f:id:Nif_Urchi:20211224152305j:plain
手前の黄色いLEDが光っています

0を押すと消えます。 f:id:Nif_Urchi:20211224135341j:plain


問題なく使えそうですのでセンサーたちを繋いでいきましょう!

測定機器のセッティング

温度センサーをつなぐ🌡

  • 温度センサーをつなぎます。 (写真を撮り忘れました……)
  • 温度センサーは専用のノードnode-red-contrib-ds18b20-sensorが用意されているので本当に簡単に値を取れます。
  • センサーをラズパイに繋いだ状態で左のボタンを押します

    f:id:Nif_Urchi:20211224135403p:plain
    getTempratureがセンサー用ノードです。左ノードは起動スイッチのようなもの

  • 緑色のログ出力ノードから値が出力されました

    f:id:Nif_Urchi:20211224135527p:plain
    25.625℃のようですね

  • いい感じに取れていますね!

pHメータの設定

www.indoorcorgielec.com

  • コードについてはこちらを参考にしつつ、ひとまず生の電圧を返すようにしました。(0リセットのため)
  • はんだづけをしてpHメータの基盤部分とつなぎます。

    f:id:Nif_Urchi:20211224145414j:plain
    (はんだが汚すぎる……生物学科出身なので許してください。)

  • pHメーターのセンサー部分はこんな感じ。この先端を水中に入れpHを測定します

    f:id:Nif_Urchi:20211224145439j:plain
    先端にはガラス極があります

  • 上述のサイトを参考に0リセットとpH計算式の決定をしました

  • ……が初めうまく0リセットができず、はんだづけをやり直しました。

    f:id:Nif_Urchi:20211224154736p:plain
    本来右写真のようにランプがつくはずですが接触不良で点灯していません

  • はんだづけと0リセットを行い、pHBuffer液で校正をしました。

  • センサーは直接のpHではなく電圧を返します
    f:id:Nif_Urchi:20211224152849j:plain
    pH校正液 水に溶かせばOK
  • 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には用意されています alt

  • ラズパイとマイコンボードをmicroUSBで接続し、シリアル通信を有効にします

  • ノード設定画面で利用するシリアルポートを指定するとリクエストを送り、マイコンボードが動作し、値を返してくれます。便利すぎか?

    f:id:Nif_Urchi:20211224150840p:plain
    ポートはttyACM0を指定

  • requestで1を送ると先ほど書いたコードが実行され、センサーからの値が返ってきます

    f:id:Nif_Urchi:20211224150957p:plain
    request_payloadがrequest内容 payloadが戻り値です

LINEに値を送る

取られた値をスマホで見れるよう、 LINEbotを作成し、messagingAPIを使って計測結果をLINEで送ります。 developers.line.biz

  • なんとこれもノードがあります
  • こちらを参考に設定をします。
  • 各種Keyをセットするだけで利用可能です
    f:id:Nif_Urchi:20211224151319p:plain
    ブロードキャストノードを設定します

今回はLINEbotの友達全員にメッセージを送るブロードキャストノードを使いました。

ノードを作る

  • これらのノードを繋ぎ、定期的に水温とpHが送られるようにします。フローを実行するinjectノードを定期実行するように設定しました。

    f:id:Nif_Urchi:20211224151615p:plain
    ノードの起動トリガーとなるinjectノードで定期実行&自動開始を設定しています

  • さらに一回の測定ではばらつきが大きいので10回平均を結果として返すようにします。

  • 完成したノードがこちら
    f:id:Nif_Urchi:20211224151517p:plain
    トリガーを手動で押すことでも起動します msgノードはデバッグ用です

詳しく

  • getphとgetTemplatureでそれぞれの値を取得し、ph格納と数値を配列に格納ノードで整形しています。(outputは全てmsg.payloadに格納されて上書きされるので移動させています。)
  • switchで計測回数を確認し、10回計測したら上のノードに、違えば下のサーキットループに戻します。
  • CalcAvgpH、CalcAvgTempはcalcノードを利用しました。こいつは配列に対しての統計処理をお手軽にしてくれるノードです

完成がこちら

f:id:Nif_Urchi:20211224151915j:plain
- 左から ラズパイ、水温計と接続しているブレッドボード、マイコンボード、pHメーター基盤です。

  • ただこのままだと設置ができないのでブレッドボードをどかして直接配線します

    f:id:Nif_Urchi:20211224154641p:plain
    抵抗ははんだで配線と直接つなぎ、フリーザバッグに穴を開けて簡単に防水しました
    f:id:Nif_Urchi:20211224154856j:plain
    全体はこのようになりました

  • 水槽横に仮設置し、センサーを水中に入れて測定しました。

  • 動作間隔を2分にしたのでやべー人からのLINEみたいになっていますが、ちゃんと測定できているようです

    f:id:Nif_Urchi:20211224154945j:plain
    2分おきにきています(未読は公式アカウントのやつです)

  • 動作中はこのようにライトがピカピカします

    f:id:Nif_Urchi:20211224155025g:plain
    ピカピカピカ

異変に気づく

設置したのは火曜夜でしたが、水曜朝にあることに気が付きます

f:id:Nif_Urchi:20211224155340j:plain
夜中の値 CO2添加器が切れているのにpHが低い
………………pHが低すぎる
pH3~4だと炭酸水〜レモン水レベルであり、魚にいい状況とは言えません
正しく校正してあるのでそこまでずれはないはずです。水流があるため不安定になるはずですが……
しかもこの時間帯はCO2スイッチはオフになっているはずです。

原因判明

CO2添加器のスイッチが切れているのにCO2がちょぼちょぼ出ていました……
スマートコンセントによってタイマー制御しており、オフになるのは夜間でした。そのため出ていることに気づけなかったようです CO2を制御する電磁弁が故障しているようです。

グラフを書く

どのような推移になっているのか確認するため、CO2添加器を取り外したうえでグラフ化する準備をしましょう CSV出力するノードを利用して、ラズパイにCSV保存していきます。

f:id:Nif_Urchi:20211224155542p:plain
測定結果をCSV形式にし、fileノードでラズパイ内のcsvに追記していきます

モニタリング開始から24時間グラフ

  • pHと水温の24時間グラフです。途中pHが跳ね上がっているタイミングでCO2添加器を取り外しています。
  • 一時的に上振れていますが、その後pH4.5あたりに落ち着いているのが見られます

    f:id:Nif_Urchi:20211224155636p:plain
    誤差も考えられるが明らかにpHが上がっている

  • 水温についてはサーモスタットが一定温度を維持しようと動いているのが可視化できていいですね。 サーモスタットの設定温度を26℃にしているので25℃を下回ると加温され、一定まで上がるとスイッチが切れる を繰り返している様子がグラフからわかります。

    f:id:Nif_Urchi:20211224155741p:plain
    CO2添加器取り外し時に温度センサーとヒータの距離が変わってしまっています

さらに2日

  • CO2添加器をとめて2日経過しました。pHが5前後で安定してきているようですね。まだ低い状態ですが、CO2添加器止めた結果が可視化できて満足です。
    f:id:Nif_Urchi:20211224161655p:plain
    少々見づらいですが赤線のpH5あたりに安定してきているようです

最後に

技術的なあれこれをはしょってざっくり書いてみました!作業時間としては1日で終わっています。 今後はグラフの自動作成、室内気温の取得、異常値になれば装置の強制停止などの機能も追加していこうかなと思っております。 むずかしくごちゃごちゃ書いてしまいましたが、思っている以上に手軽なのでご興味ある方は気軽に挑戦されてみてはいかがでしょう🙋‍♂️

先輩方の素敵なアドベントカレンダーのトリを務めさせていただけて光栄でした🥰 読んでいてとても楽しかったので是非来年も……!と思っております。 ありがとうございました🥳🥳

エンジニアリング統括部 サービス開発部 エンジニア 竪山 裕文の写真

竪山 裕文 Hirofumi Tateyama

エンジニアリング統括部 サービス開発部 第1グループ エンジニア

2021年4月に新卒でパーソルキャリアへ入社。フロントエンドエンジニアとして転職者定着支援サービス、社内向けサービスの開発に従事。

※2021年12月現在の情報です。

▶エンジニアリング統括部の求人ページはこちら