初心者がIoTに挑戦　M5stackCore2でペット体重計を作る

## はじめに
新卒1年目の超初心者がペット体重計の制作過程をつづった備忘録です。
プログラミングやIoTなどの学習の一環として、先輩と協力してペット体重計を制作することになりました。先輩はアプリを、私はハードウェア・サーバー側を担当することに。

制作スタート時

- ハードウェアの知識0
- M5stackはHelloworldできて喜んでいた
- プログラミングは勉強を始めたばかり、学習済みの内容は
 -データ型：Excelのデータ型、文字列型、数値型
 -Excel操作：ファイル操作、フォーマット（セルの塗りつぶし、罫線など）

まだまだ学習途中なので間違った内容も含まれてしまっているかもしれません。なにかあれば教えていただけると嬉しいです。
## 構成
作業構成としては以下の通りです。
1) RFIDの読み取り
2) 体重の測定
3) データ送信

全体のイメージ、概要は下の図のようになっています。
測定された値がニフクラに送られ、アプリから閲覧できるといった仕様です。
![IoT全体イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611628/08382d91-b074-34e2-f61e-399923b7af11.jpeg)
グラフで体重の変化を確認できたり、日々のメモを残しておけたりなどアプリにもまだまだ機能はありますが、それに関しては[@nanano08さんの記事](https://qiita.com/nanano08/items/d946f31a7ec5aa0164ad)をご覧ください。

制作に当たって主に[@machatanさんの記事](https://qiita.com/machatan/items/9f684ab0375664df9885)を参考にさせていただきました。

接続図や使用方法、コードは[こちら](https://github.com/KechanaGohan/Pet_Scale)にあります。
## 使用したもの
使用機器はほぼすべて上司からお借りしました。
事前学習に使用したアプリやDBもおすすめしていただいたものを使ってみることにしました。
#### 体重計
使用予定だった体重計がうまく反応しなかったため、自宅のにあったキッチンスケールで代用しました。
#### M5stackCore2
メインとなる[M5stackCore2](https://www.switch-science.com/catalog/6530/)
今回I2CとUARTの両方を同時に出力したかったため、[M5Core2BaseLite](https://www.switch-science.com/catalog/6763/)を取り付けポート拡張を行いました。
#### RFIDリーダー
RFIDリーダーには[Grove-125KHzRFIDリーダー](https://wiki.seeedstudio.com/Grove-125KHz_RFID_Reader/)を使用しました。
タグは[こちら](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-0RBC)。キーチェーンタグ3つとブランクカード2枚が入っています。
#### アンプ
今回使用したロードセルアンプは[NAU7802](https://www.switch-science.com/catalog/5539/)です。
当初は一般的によく使われるHX711を使用予定でしたが、SoftwareSerial問題が解消できなかった点（「RFIDの読み取り部の作成」に記載）と、M5Core2BaseLiteによってI2CとUARTの両方を同時に出力できるようになったことから、BaseLiteとI2Cでデータのやり取りができるNAU7802を使用することにしました（UARTの通信はRFIDリーダーで使用）。
NAU7802はHX711に比べドキュメントが少なく初心者には扱いが少し大変でした。
#### データ保存先
データ保存先には[ニフクラ mobile backend](https://mbaas.nifcloud.com/)を使用しました。
サーバー開発、運用などが必要なく、ドキュメントも豊富でとても使いやすいです。初心者でも直感的に操作できました。
先にアカウントを作成しておく必要があります。
## 制作に取り掛かる前に
なにをするにも知識がない状態だったので、まずはこれから作るもののイメージをつかむところから始めました。
行ったこととしては
1) APIの理解
2) ENVセンサーを使ってみる
3) 2をDBに送ってみる
### APIの理解
ニフクラを使用する上でAPIを理解する必要があるということで学習を進めました。
実際にどのような使われ方をするのかについては、[Postmam](https://www.postman.com/)を使って郵便番号検索APIを試すなどしてイメージをつかみました。
### ENVセンサーを使ってみる
M5stackCore2の基本となるところはここで学んだ気がします。
10秒おきにセンサーから温度・湿度・気圧を読み取りディスプレイに表示するパターンと、ボタンが押されたときに温度・湿度・気圧を読み取るパターンを試しました。
センサーの使い方は主に[こちら](https://lang-ship.com/blog/work/m5stickc-env-hat-1/)を参考にさせていただきました。
[ボタンを使用する際はM5.update();が必須](https://qiita.com/shoiijima463/items/13d9e1887b40ceea29f5)のようです。
### DBに送ってみる
ENVセンサーで読み取った情報をニフクラに送ってみました。
wifi接続はPreferences.hを使用してwifiのssidとpasswordを保存しておく方法をとりました。
ニフクラとのデータ連携は[M5stack用のライブラリ](https://github.com/NIFCLOUD-mbaas/ncmb_m5stack)があるのでそちらを参考にさせていただきました。

ニフクラ、M5stackCore2の使用、データ送信のイメージをつかんだところで本格的に体重計の制作に入っていきます。
## RFIDの読み取り部の作成
まず製品ページにあるサンプルをArduinoUnoで試し、うまく動作することを確認しました。
ここからM5stackCore2用にコードを書き換えます。
M5.begin()などCore2を動かすための処理を入れますが動かず。
Serialの初期化がうまくできていないのが原因でした。
最終的にはこれでうまくいきました。
```php
M5.begin(true, false, true, true); // lcd,sd,serial,i2c
Serial.begin(9600); // the Serial port of Arduino baud rate.
Serial2.begin(9600, SERIAL_8N1, 13, 14);
```
SoftwareSerialは使わず、Serial1,2で書き換えました。
M5.beginの引数については[こちら](https://qiita.com/penguinprogrammer/items/5abf3e4f9583e41e9cfa)を参考にさせていただきました。
今回サンプルがうまく動かなかった原因として、[Serial.begin()の2重呼び出し](https://www.1ft-seabass.jp/memo/2021/01/24/m5stack-core2-bug-recover-tip/)や、[Serial1がDefaultで使えない](http://shinshu-makers.net/shinshu_makers/2020/09/02/%E3%80%90l-rtk%E3%80%91m5stack_serial2%E6%8E%A5%E7%B6%9A%E3%81%A7%E6%89%8B%E9%96%93%E5%8F%96%E3%81%A3%E3%81%9F%EF%BC%9Cf9p_rtcm%E5%8F%97%E4%BF%A1%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95%E3%81%8C%E4%B8%8D/)といった情報もありましたが、はっきりとした原因はわかっていません。
通信速度の上げすぎ、下げすぎは文字化けを引き起こすため9600bpsがちょうどよかったです。
シリアルモニタに表示された値から必要なところを抜き出し、10進数に変換するとタグの値と一致しました。
## 体重測定部の作成
当初使用予定だった体重計の故障により、キッチンスケールで作業を進めることに。
キッチンスケールを分解し、ロードセルから伸びているコードを長めにとって切り、アンプにつなぎました。
アンプの基本情報は[ガイド](https://learn.sparkfun.com/tutorials/qwiic-scale-hookup-guide?_ga=2.144158709.1920891234.1560906655-245387275.1555564048)にあります。

まずはライブラリのインストール。
補正係数を求めるため、サンプルExample1_BasicReadingsを実行しました。
手順は[こちら](https://www.denshi.club/cookbook/sensor/g/3-nau7802.html)を参考にさせていただきました。
ただ、参考にさせていただいたものと少し表示が違う箇所も見られたので、これに関しては詳しくサンプルコードを読んでいくしかないと思います。
最終的に"New cal factor"として出てきた値が補正係数でした。
何度か別の重さのものを乗せ試してみるのがよさそうです。

キャリブレーションも完了したので、今度は実際に重さを量るためのコードを書いていきます。
サンプルExample1_BasicReadingsを試すとわかると思いますが、補正係数が算出されたあとに乗せているものの重さがきちんと確認できるようになっています。そのため、このサンプルから必要な部分を抜き出し、計測用コードにしていきます。
測定結果はM5stackCore2のディスプレイに表示されるようにし、Aボタンを押すとオフセット値がリセットされるようにしました。

1g単位で結果に揺れが生じますが誤差ということで許容しています。

できたものは別の関数にしておきます(readWeight)。
## データ送信
wifi接続とデータ送信は体重計制作前の作業をベースに行っています。
ニフクラには事前に新しくデータストアとフィールド等を作成しておきました。
測定が完了したと同時にデータが送信され、体重は"petWeight"、個体番号は"petTagId"として保存されます。
![ニフクラフィールド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611628/9a17fa27-964e-4067-4823-79e51277f4ec.png)
## そして完成へ
![IMG_0574.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611628/5043bd34-b4b9-1b2c-ed6c-57b46e19fda3.jpeg)
これまで作ってきたものをつなぎ合わせます。
## まとめ
スタート時の知識がほぼ0だったため、想定した動きがうまくできなかったときに、コードの書き方が間違っているのか、つなぎ方の問題なのか、それとも機器そのものなのか...など、どういった原因が考えられて、どのようにアプローチしていくべきかがわからなかったことがすごく大変でした。そのため、一つの問題に対してとても遠回りをしてしまった気がします。それはそれで勉強になったので、知識を深める上ではよかったのかなと。
あと機器紹介でも触れましたが、NAU7802のドキュメントが少ない！笑

改善したいポイントを挙げると
- 体重計のケース作成
- wifi接続方法の変更（ホットスポット接続からWiFi設定を記憶、次回起動から自宅WiFiに自動接続）
- 次こそキッチンスケールから体重計へ
は必須かなと思います。
あとは見た目（ディスプレイ表示も含め）やコンセプトの設定、アイコン作成なんかもできたらすごく面白いかなと思います。
やっとベースとなるところができたので、ここからは「やりたいこと」を意識できたらと思います。