「すべてはにゃんこのため」：にゃんこ用体重計をシリアル通信連携で作る

#にゃんこ用体重計をシリアル通信連携で作る（Arduino Pro Mini＋ESP8266＋7Segduino）

<img src="https://qiita-image-store.s3.amazonaws.com/0/207819/126f6504-fd26-9a6e-4acc-4890a705a4db.jpeg" with"40%">

# 意外に忘れる体重測定
にゃんこの体重を計るというのはうっかりするとすぐに忘れてしまったり、似たような大きさの多頭飼いの場合、メモした体重がどちらの個体かわからなくなったということが我が家ではよくある。
できれば個体を識別しつつ体重を計り、自動的にクラウドに保存してくれれば後でどうにでもなるということで引き出しの奥に眠っている部材を使って作ってみることにした。
ハードウェアや電気の知識に乏しいためいろいろ間違いはあると思うが何かあれば教えてもらえると嬉しいです。

制作にあたっては次のように考えることにした。

-RFID読み取り部
-体重測定部
-測定結果表示部
-測定値送信部
の４部構成で作っていった。

機能的にはマイコン1台でもできそうなものだが、余裕のないのが嫌いな性格のため贅沢にArduino、ESP8266、7Segduinoの3つを使うことにしてみた。
RFID読み取りと測定にArduino Pro Mini（5V,16MHz）、測定表示部に7Segduino、測定値送信部にESP8266を使用している。
これらをUARTで接続しそれぞれの機能をモジュール化し万一故障しても故障しているモジュールのみ交換すればいいのでいろいろつぶしも利くしそれぞれシリアル通信すればモジュールの動作確認も簡単だった。
大人の遊びにはちょうどいいかも。
<img src="https://qiita-image-store.s3.amazonaws.com/0/207819/9ef2ffb8-8f89-bccd-6b4b-0f6f7034f729.jpeg" width="40%">
<img width="320" alt="cabling.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/207819/d3943e19-72a3-36d5-d293-bf14c56ef37f.jpeg">
各ソースと接続図や利用方法に関してはGithubに置いてます。

https://github.com/machatan/PetScale

ではそれぞれのモジュールに使った資料と作り方を書いていくことにする。

## １）RFID読取＋測定部
まずは心臓部のArduino Pro Mini
https://www.switch-science.com/catalog/946/
お手頃価格で買えるのでUnoよりも気に入っている。
AdafruitからもMetro Miniが出ていたりするが、こちらのほうがケース用のドリルもしてあり便利かもしれない。

 RFIDリーダーは今回125kHzのGROVEモジュールを使うことにした。

Groveシリーズ用RFIDリーダー(Grove用4ピンコネクタ搭載)　単価 ¥1890
 http://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-0GKE

その他のNFCリーダ（SONYのやつとか）はブルジョアな人が買えばいいと思います。
 そして、RFIDタグは５個（カード2枚＋キーホルダー型3個）入っているこれにした。

Seeed Studio　125KHz RFIDタグ 5個入り 単価 ¥370
 http://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-0RBC

5 IDで370円は安い、試すには十分。

重さセンサー（いわゆるロードセル）は大型のにゃんこが乗っても大丈夫なように余裕のあるものがよいのとセンサーを単品で買うよりも体重計を買ってばらせばセンサーのケースを考えなくてもよくなるのでこの辺りを買ってみた。
https://www.amazon.co.jp/1byone-%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E4%BD%93%E9%87%8D%E8%A8%88-%E3%83%9C%E3%83%87%E3%82%A3%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB-%E8%A8%88%E9%87%8F%E7%AF%84%E5%9B%B2180kg%E3%81%BE%E3%81%A7-%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3/dp/B06XSXLMJ8/ref=sr_1_3?ie=UTF8&qid=1508143214&sr=8-3&keywords=%E4%BD%93%E9%87%8D%E8%A8%88+%E3%82%AC%E3%83%A9%E3%82%B9

※今回の体重計の場合は計測台が大きいため上の部品を分断して計測台に貼り付ける

そして肝心の計測に使うアンプはこれ
SparkFun　SEN-13879 ロードセルアンプ HX711 単価 ¥1200
 http://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4ZU4
秋月の場合は350円とaitendoと並んでかなり安い。
http://www.akizukidenshi.com/catalog/g/gK-12370/
どれを買ってもArduino用のスケッチやライブラリがあるので困らない。

また今回は市販の体重計からロードセルを拝借するためコンビネーションボードがあると便利だ。

ロードセルコンビネーションボード
https://www.sparkfun.com/products/13878

## ２）測定結果表示部
計測結果の表示には今回これを利用した。

7segduinoキット　単価 1,851円
https://www.switch-science.com/catalog/745/

直接LEDをArduino から表示してもよかったが、今回はRFIDの読み取り、ESP8266との通信、7SegLEDと6本（SoftwareSerial 3回線）のシリアル通信をするため、通信するピンの本数を減らす目的でこれを選んだ。

## ３）測定値送信部
Wifi接続することが前提にあったのでおなじみのこれ。

ESPr® Developer（ESP-WROOM-02開発ボード）　単価 1,944円
https://www.switch-science.com/catalog/2500/

※これももちろんもっと安いのでもよい。これを選んだのはブレッドボードをケチったため

また、このモジュールだけ3.3Vで動作するためシリアル通信用にロジック変換してやる必要がある。
今回は安くていいのでこれにする。
https://www.switch-science.com/catalog/1523/

電源に関してはRFIDリーダーが5Vを要求しているためESP8266への電源をArduino ProMiniに供給する電源から3.3Vを作ってあげてそれをESP8266の電源としている。
例のLDO　100円
http://www.akizukidenshi.com/catalog/g/gI-00538/
５Vのラインに50V100uFのコンデンサを入れておくのも忘れずに。

# ４）データの保存先（クラウド）
今回のクラウドへのデータ蓄積基盤はnifty mobile Backendを使用することにした。
http://mb.cloud.nifty.com/
アカウントを作成し、データストアにフィールドを作成しておいてください。
作成するフィールドはuid,Weightの2つ（String）で問題ありません。
作り方などは公式のドキュメントが充実しています。
http://mb.cloud.nifty.com/doc/current/dashboard/datastore.html

個体管理のため、「日時、個体番号、体重」のレコードをJSON形式にしてPOSTすれば簡単にデータがたまる。
そして無料なうえに会員管理で患者番号などと紐づければ動物病院でも使えるかも。
もちろんスマホなどでフロントエンドを作れば体重管理の履歴なども作ることはできる。
WEB系は苦手なのでそのうち気が向いたらやるかも。
また、サンプルは非常に充実しているのでいざ作成となってもあまり困らないのもいいけど。

ということで早速作成
# RFID読み取り部を作成する

まずRFIDの読み取りは製品のページにサンプルがあるので早速いただいて試してみる。
GROVEのコネクタはついているもののブレッドボードで使うときには４ピンジャンパメス付きのケーブルが便利。
https://www.switch-science.com/catalog/1048/

適当につないで早速サンプルを動かしてみる。
http://wiki.seeed.cc/Grove-125KHz_RFID_Reader/
![Read_Data_[1].jpg](https://qiita-image-store.s3.amazonaws.com/0/207819/c6a6e479-349a-100e-addb-ab984c28e6c1.jpeg)
※画像はサンプルページから引用

うむ、なんか出てきた。
が、カードに書いてある番号とはちょっと違う。
スタートストップバイトとチェックサムが付加されているのでここから必要なところだけ抜き出して10進数に変換するとカードに記載
の番号と一致するようだ。

なのでそのように処理を入れてみる。

<SRC>

うむ。比較的簡単にできた。
もちろんGroveのモジュール以外のNFCリーダーなどを使ってもよいがリーズナブルで読み取りも早い。
が、UARTでサンプルでもSoftware Serialを使っているが通信速度を上げすぎても正常に読み取れなくなるので9600bpsがいいところだった。
単体ならもう少し通信速度は速くできるようだった。

そしてこの読み取り部分を別の関数にしておく。
サンプルではLoop関数でずっと回っているのでうっかりしてしまいがちだが「非同期通信」なのでデータを読み切ってからカードの番号を成形
しなければならない。
成形したらグローバル変数にでも保存しておけばよい。

# 測定部を作成する。
これもサンプルをパクッてｗ変えてみる。
使い方のガイドはここにあるので参考に。
https://learn.sparkfun.com/tutorials/load-cell-amplifier-hx711-breakout-hookup-guide

ちなみにこのガイド中にも触れているが、体重計を改造してロードセルコンビネーションボードを利用する場合はコンビネーションボードに印刷してある「＋」と「Ｃ」を逆に挿す必要があるので注意してほしい。
ガイドをよく読まないで適当につないでハマったのは私ですｗ

繋いだらライブラリがあるのでそれをダウンロードしてArduino IDEにライブラリとして登録しておく。
https://github.com/bogde/HX711

ガイドの下に「SparkFun_HX711_Calibration」のコードがあるのでこのコードをIDEにコピペして転送するとキャリブレーションができる。
適切に設定したつもりでも誤差はあるので１ｇ単位での揺れは許容する。
市販の体重計でも必ず誤差はあるので5～50gの誤差の範囲で収まるようにキャリブレーション値を設定していく。
また、重さの単位がポンドになっているのでlbs値に定数を掛けてグラム表記に直してからシリアルで表示している。
サンプルではlbs値だけなのでグラム表記も併用して表示させておくと調整には便利。

またキャリブレーションの方法は「重さのわかっているもの」で3回以上計測して値が安定したらその値でset_scale()を呼び出せばキャリブレーションできる。
キャリブレーションできたら市販の体重計やスケールも使ってその値に近づくように設定した。
今回はベビースケール、キッチンスケールを使って合わせていった。

重さのわかっているものはとりあえず手近にあったiPhone5s（110g）を使ってみた。
不安ならば市販の分銅を使ってもいいがそこまでではないのとおよそわかればいいので見送り。
シリアルモニタで調整できたら測定部は完成とし、このスケッチをモジュール化する。
ただし、いくつかBlogでも書かれていたが測定値が揺れる、、、。
時間が経つと基準が変わる、、、。
などありなかなかジャストな数値が得られず悩んでいたが市販の体重計でもそこまでの精度は出しておらず誤差に関してはロードセルの材質や利用する温度によって影響を受けるもののこの辺りを全く無視して精度を出すのは難しいしそれにはもっといい計測器やひずみゲージを利用したほうがよく市販の体重計と同じようなものにするなら20～50g程度の誤差は許容したほうが良いらしい。
その辺の詳しい話は共和電業さんのページがかなり男前なのでそちらを見てほしい。
http://www.kyowa-ei.com/jpn/

今回は測定値を見ながら測定値に2146.66666666666667fを掛けて1/1000する荒業で10g以下の誤差になった。
20kgまでのにゃんこ（いるのか！？）なら問題なく測れると思う。
使用する場所やロードセルの種類で変更してほしい。

# 測定結果表示部を作る
測定結果の表示は7Segduinoに測定した数値を文字列でシリアル送信してやれば表示してくれるようにする。
"XX.XX"の形式で”X.X”、”X.XX”など3桁～5桁までの文字列を入力できるようにし、それ以外は「Err」と表示することにする。
また最後の通信から3秒以上経過したところで数値を点滅した後10秒固定して消灯するという市販の体重計に習って同じような表示仕様とする。
7SegduinoのサイトにGPSクロックのサンプルがあるので早速パクり、変更していく。
http://morecatlab.akiba.coocan.jp/lab/index.php/aruino/7segduino/7segduino-application-6-gps-clock/

いや、ほんとありがたいです。
USBシリアル変換を使って作成できたらarduinoのRX,TXに割り当てたピンに接続していく。
7Segduinoは5V仕様なのでそのまま何も考えずにつないでいく。
電源も同じところから取ってやればよいだろう。

7SegduinoとHX711を組み合わせれば体重計の完成だ。
いろいろなものを乗せて計測してみるといいだろう。
もともとは人間用の体重計なのでもちろん人間が乗っても問題ないが、今回はにゃんこ用ということでMDF材とアクリルボードを組み合わせて
測定台を作ったが、メタボなおじさんが乗っても大丈夫だったのでよしとする。

# そして合体！？
ここまでで測定と表示の部分はできたのでRFID読み取り部と組み合わせてみる。
最初に組み合わせた時にはGROVEシールドとLCDシールドを組み合わせてビーム型のロードセルを使っていたので写真のような形になっていた。
ビーム型で完成したあたりで人間用の体重計を買ってきて改造したため部材ごと余ってしまったが、これはこれで小動物用などに転用しようかな。

# 結果送信部の作成
さて、ここまでくればあと少し。
ESP8266を使ってnifty mobile Backend（以下NMB）を使ってhttpsクライアント機能で送信してやれば問題ない。
ESP8266で送信する前にcurlなどで実際に送信し動作を確認しておく。
NMBのデータソース画面の右下にREST APIツール画面があるのでそこを押すとREST APIでの送信方法が表示されるのでそのまま送るとよい。
便利な世の中になったもんだ。
また、ESP8266を使うためのArduino IDE設定に関しては下記が圧倒的に詳しいうえによくわかっている方なのでそちらを参考にしてほしい。
https://www.mgo-tec.com/blog-entry-esp8266-wroom-02-espr-developer-trouble-shooting.html

送信は基本的に{uid,weight}の形式で送信し、ヘッダにAPIキーなどが入る使用になっているのでuid,weightの形式で受け取ったら｛｝を付与してヘッダとともにHTTPS Clientモジュールで送信してやればよい。
今回は多少わかりやすくするためにLEDをつけてWifi接続時と送信時にそれぞれ点滅するようにした。
HTTPSのPOSTもHTTPと同じようにClientを使って発行するだけなので以外にあっさりいける。

通信テストが終わったら通常のSerialからSoftware SerialでArduino と通信する際にピン接続するが、RXに関しては3.3Vに変換してやり、TXはそのままつないでいる。
レベル変換を通すと信号の減衰が思ったよりも早いため、もっと高級なものにしてやらないといけないのかもしれないが今回はこれで良しとする。

# 完全合体！！？
それぞれのモジュールを作成したのであとはケースにしまい込んで繋いでやった。
が、電池を入れるスペースを考え忘れてえらく不格好になった。
また暇を見つけて基板に着けるようにしてうまくケーシングしよう。
今回は最高に不格好だったが次は見てろよ！（T-T）

なんだかんだとケースを作ったりするのが一番大変だということに気付く。


ということで、ここまで来るのにほんとはちょっとずつしか作れなくてなかなか時間も取れなかったがこうしてまとめることもできたのですっきりした。
まだまだ、ここからいろいろ完了できる点はもちろんあるのでそうした面も考慮しつつ、もちろん元は我が家のにゃんこのためであるのでにゃんこに適したUI/UXでなければならない。
そこが一番重要なので今後も我が家のにゃんこのためにいろいろ作っていくことにする。