Raspberry Piを使ったIoT重量計


# はじめに
少し前に知人が会社内で「廃棄物重量のエクセル集計大変なんだよなぁ」というつぶやきをしておりました。
「自分だったらこうするな」を形にするために、まずは(学習を兼ねて)データ収集用IoT機器制作を作成してみました。内容はラズパイを使ったIoT重量計です。
既存のセンシングプログラムを少し改良し、Webアプリを適用し使いやすくしたというものです。なお、Webアプリについては、長くなるのでGitHubのリンクを貼るだけに留めます。
動作については[こちらのリンク](https://drive.google.com/file/d/10wVljW_FPMP60P_2FPflISVxYUKlTvIt/view?usp=drive_link)をご確認ください。(google drive内の動画になります)
一般的にIoT x Webアプリに対して壁は厚いように思えます。本記事を通して、どなたかの何のお役に立てば幸いです。

# 構成
## 概要
今回作成したIoT重量計は、「重量測定プログラム」と「Webアプリケーション」の二つのプログラムで構成されております。
この二つの中で値の受け渡しは、テキストファイルを用いて行うことにしました。重量測定結果をテキストファイルに書き込み、Flaskで作成したアプリケーションからテキストファイルの重量値を読み取る仕組みを採用しました。(DB入れようかと思ったのですが、導入するレベルではないと考えました)

### 重量計とWeb App間の値の受け渡し
![重量計とWebApp連携.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/0f9c9eaa-a329-1630-6cba-1eddf76d6600.png)

### Web Appの動き
＜フロントへの部署情報渡し＞
![IoT重量計動き_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/a0b73eb5-2991-fbc8-f88d-0ffeaf9f06b9.png)
＜フロントへの重量情報渡し＞
![IoT重量計動き_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/a249621a-8a56-f2d8-04d5-2945d1174fd2.png)
＜フロントからの廃棄物情報取得→DB保存＞
![IoT重量計動き_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/1dc6e95c-8256-9e7e-c7b3-9877ff54a52c.png)


## 重量計について
### 重量計の概要
まず重量計部分は家庭用のスケールを採用しました。(本番は測定物の重量に合わせたロードセル買って、工作するだけなので配線含めて基本変わらない)
これを分解して、内部の歪みゲージ部分の電線を少し太めの電線に繋げ(ハンダで補強)、それをHX711というAD変換器に通し、HX711からRaspberry Piに接続しました。
重量計のプログラムですが、tatobariさんの[GitHub](https://github.com/tatobari/hx711py)をベースに作成しました。
若干コードを修正し、環境変数で与えたパスに存在するテキストファイルに重量測定結果を書き込む仕組みに変更しました。


### 配線
#### 図
![配線図_hx711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/5e32598a-766e-45ae-80c8-4d656e7a7f02.png)

#### 写真
＜配線＞
![配線写真_1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/9eef8507-dd08-bbd5-bff4-18bc47e0a888.jpeg)
![配線写真_2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/33395b6c-62c4-b18e-ddb8-da3bb87fa4b6.jpeg)
＜半田付け＞ (スケールの歪みゲージ電線補強)
![スケール電線の半田付け.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/0dd739b3-f1d6-bad3-6ebe-90688d258846.jpeg)

### コード変更箇所
2箇所修正しました。
1. 測定データの換算方法を変更
1. 測定結果をテキストファイルに保存する処理を追記

＜換算についての補足＞
まずは、複数の測定物を重量計(正しい値が出力されると期待されるもの)に乗せて重量を確認しました。次に各測定物を複数回、IoT重量計で測定します。これらの重量と計測データを一次関数に線形回帰させ、傾きと切片を取得します。この傾きと切片データをラズパイの環境変数に格納し、コード内で重量に換算できるようにしました。
![hx711_コード変更箇所1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/ba3fe3b3-d094-8903-3941-0bf89800b1d8.png)
![hx711_コード変更箇所2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/ec49c5b0-6e55-8a3d-3a8e-fb97d8a08350.png)


### 使用部品一覧
- [Raspberry Pi 4B](https://www.switch-science.com/products/5680):　制御器兼Webサーバ
- [HX711](https://akizukidenshi.com/catalog/g/gK-12370/)：　AD変換器
- 電線：　私はAWG18前後 (外径1mm前後)の撚り線使用。(HX711でネジ止めできればOK)
- [スケール](https://www.amazon.co.jp/gp/product/B0BHDXTMKF)：　何でもOKです。


## Database
下記の想定でDBを作成しました。(PostgreSQL 14.5を使用)
- 部門情報DB(基幹システム)とアプリ用DBの二つが存在する
- 部門情報テーブルはIoT利用者(以降iot_user)によって閲覧可能
- 部門情報テーブルにiot_userは書き込み可能

詳細な内容は[GitHub内のsetting_files](https://github.com/f-mio/measure_and_register_weight_app/tree/main/setting_files/database)をご確認ください。


## アプリケーションについて
### アプリ概要
Raspberry PiがWebサーバとなるので軽量なフレームワークを使用したいと考えFlaskを採用しました。また、今回のプログラムは企業内の閉じたネットワーク内で使用することを想定しております。そのため、セキュリティがある程度確保されている前提のプログラムとしました。

### コードについて
GitHubのリンクを貼っておきます。
[ラズパイ重量計GitHubリンク](https://github.com/f-mio/measure_and_register_weight_app)


## 動作方法
### 重量計アプリ
ターミナルもしくはシェルを開き下記のコマンドを入力します。
```bash
$ source /(重量計用Pythonパス)/bin/activate
$ cd /(hx711 directory)/
$ python measure.py &
```
### Webアプリ
ターミナルもしくはシェルを開き下記のコマンドを入力します。
```bash
$ source /(flask用python path)/bin/activate
$ cd /(flask directory)/
$ flask run --host=0.0.0.0 &
```


# 反省点
## 電子工作
知らないことが多かったのでほぼコピペになってしまいました。少しずつでも吸収して幅を広げていきたいです。
その他には、重量測定部分と補強した電線が干渉し、適切な重量測定ができないことがありました。この辺りの工夫が必要だと感じました。
測定プログラムは、cronで起動直後に動く設定にした方がよかったかも。

## Webアプリについて
SQL Alchemyの使い方がわからず結構大変でした。いい書き方ができている気がしないのでもう少し学習しようと良います。
また、Flaskを使ったのが初めてだったのでどこに何を配置すればいいのか設計部分ができていないように思えます。Flaskを使い続けることはない予定ですが、今後FastAPIの学習を考えています。この辺りの設計をうまくできるように考えていきたい。



# 参考資料
## 重量計測プログラム
- https://github.com/tatobari/hx711py

## 電気部品の配線
- https://zenn.dev/kotaproj/books/raspberrypi-tips/viewer/270_kiso_hx711
- https://note.com/izawa/n/n0b4d4866470a

## Web App
- https://msiz07-flask-docs-ja.readthedocs.io/ja/latest/
- https://www.sqlalchemy.org/


# 今後の展望
重量を測定するものを作成したので、これを表示するための可視化アプリケーションを作ってみようと思います。
本来ならユーザ側でグラフを変えたほうが良いのでBIツールを使うべきです。ただ、学習と割り切ってChart.jsを使った何かをDjangoを使って作成してみたいと思います。
また、IoT重量計アプリを使ってみたい方はGitHubから再現されるか、よろしければお問い合わせください。仕事として要件に合ったものに作り直すことも可能です。