50: Raspberry Pi3 で歪みセンサーとアンプで scale を作る

# はじめに
こちらは
[Arduino と Raspberry Pi の違い](https://qiita.com/KZ2/items/5e0e79f84e4dd26bd373)
の個別記事で、歪みセンサーとアンプで scale を作る。

# 目的
ここではキッチンスケールのように重さを測ることができるシステムを作ることを目的とする。通常のキッチンスケールでは重さが表示されるのみで重さや時間により何か処理をするということができない。そこでスケールを作り、重さに応じて処理をしたり、時間経過とともに質量がどう変化したかをグラフにしたり、ということができるようにする。

また通常のキッチンスケールでは測定対象をスケールに載せるという方法しかとれない。しかし、自分でスケールを作るということは計測できない対象の測定ができるということになる。今回のProjectでは測定対象を固定するフレームを作って、それを計測したいという要求があったため、作らざるを得ないという背景があった。


# 想定読者
- 将来の忘却した自分
- ArduinoやRaspberry Pi でセンサーの値を読み取り、何か処理をしたい人


## Parts:　部品
- ロードセル
 + amazon [電子天秤ロードセルセンサー0-1Kg](https://www.amazon.co.jp/gp/product/B00U8MSCAK/ref=oh_aui_detailpage_o07_s00?ie=UTF8&psc=1)
 + いろいろなところで売っている。自分が計測したい重さの上限を見てセンサーを選ぶ。自分は1kg未満のため、こちらを選択した。100g以下の精密なタイプや100kgとかの体重計などに使えるタイプもある。
 + 本日時点で、amazonは購入価格の2倍近くになっており、ebay.comだと半額で手に入る。
- HX711
 + load cellからの出力を直接Arduinoなどで読むことは信号の振幅が小さすぎて難しいらしくアンプが必要とのこと。モジュールになっているものを選んだ。これはamazon.co.jpやebay.comなどで安価に入手できる。
- Display
 + LCDだとまぶしいし、サイズが大きいため小型のOLEDを使った。

# Arduino 編

## Hardware
- Arduino
 + Arduino Nano, Uno, MEGAなどなんでもいいだろう。今ならUSB Type-CコネクタタイプのSeeed XIAOなんかも安くて使いやすい。


### ロードセルと、HX711の接続

load cell --- HX711 --- Arduino の接続となる。つまり、load cellの出力をHX711で増幅し、Arduinoで読むわけである。

load cell は、通常、wheatstone bridge の構成で4本の線がある。多くは次のようになっているらしい。

|表記|意味|線の色|
|---|:----------------|:-:|
|**E+** |Excitation+, VCC |赤|
|**E-** |Excitation-, GND |黒|
|**A-** |Output- |緑|
|**A+** |Output+ |白|


試してみてOutputがプラスマイナス逆だったら、つなぎ替えればいい。

```c:connection
    [Sensor]
      E+: Red
      E-: Black
      A-: Green
      A+: White
      B-: NC
      B+: NC
```

### load cellと HX711との接続

[photo]


### load cellの設置
アクリルの板をカットして作った。
[Photo]

## Software
- HX711 library for Arduino: [HX711](https://github.com/bogde/HX711)
 + いろいろ存在するけど、これを使ってみた。

ここではArduinoでの詳細は省略する。


# Raspberry Pi3 編

## Hardware

Arduinoと同様にHX711を使う。

### 接続

好きなGPIOを使えばよいが、dataとclockを間違えないようにする。ちなみに電源を別のピンに刺すと、HX711が高温になってやけどする。実際に指にやけどしてしまった。


```c:接続

VCC - Raspberry Pi3 5V  Pin 2
GND - Raspberry Pi3 GND Pin 6 
DT  - Raspberry Pi3 GPIO#5 Pin#29
SCK - Raspberry Pi3 GPIO#6 Pin#31 
```

![Screen Shot 2018-07-01 at 13.12.50.png](https://qiita-image-store.s3.amazonaws.com/0/162341/757b65b4-f2fc-e60d-a724-97feef473950.png)

![2018-06-30 12.46.08.jpg](https://qiita-image-store.s3.amazonaws.com/0/162341/d42bdb31-7e73-4565-fe28-9a9473931c99.jpeg)


## Software
GitHubでHX711 pythonで検索した結果で、良さそうなものを選択した。

まずは試す。

```console:ソフトウェアの入手

$ git clone https://github.com/tatobari/hx711py
Cloning into 'hx711py'...
remote: Counting objects: 77, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 77 (delta 3), reused 5 (delta 2), pack-reused 68
Unpacking objects: 100% (77/77), done.
```

中身はこうなっている。

```console

$ cd hx711py/
$ ls
example.py  hx711.py  LICENSE  README.md
```

このexample.pyを利用し、これで数字が出てくるかを確認する。

```bash

$ python example.py 
-2
-3
-2
-3
-1
-2
-2
-4
-2
-2
^CCleaning...
Bye!

```

ある程度安定した数字が出てくるようなら、結線は間違っていないのだろう。

### 調整
重さが分かるものを用意する。とは言っても校正用の重りの500gや1kgのは持っていないので、普通のキッチンスケールで重さがわかるものを用意して、それを利用する。
100gのload cellなど軽めのものを利用する場合は、複数の1円玉を使うのもいいかもしれない。1円硬貨の質量は1.0 g であるためだ。

オジリナルのexample.pyはそのまま取っておいて、copyして　scale.pyを修正することにする。調整方法は、set_reference_unitを 1 にして、実行する。

```python:scale.py

hx.set_reference_unit(1)

```

### soure code

コメントを除く全体のcodeを念のため記載する。hx.tare()にて、基準をゼロにしている。

```py:scale.py
$ cat scale.py 
import RPi.GPIO as GPIO
import time
import sys
from hx711 import HX711

def cleanAndExit():
    print "Cleaning..."
    GPIO.cleanup()
    print "Bye!"
    sys.exit()

hx = HX711(5, 6)
hx.set_reading_format("LSB", "MSB")

#hx.set_reference_unit(1)
hx.set_reference_unit(-2137)

hx.reset()
hx.tare()

while True:
    try:
        val = hx.get_weight(5)
        print val 
        time.sleep(0.3)
    except (KeyboardInterrupt, SystemExit):
        cleanAndExit()
```

キッチンスケールでペットボトルを計量したら 538g だった。
そののペットボトルを利用したとき、こんなふうになった。

### 実行ログ

```bash:scale.py

$ python scale.py 
-25
73
-82
-3
-150
-95
-110
-57
49
-184
4
22
-209
-106
-808741
-1149784
-1149939
-1149879
-1149792
-1149855
-1149858
-1149907
-1150056
-1149702
-1149636
-1149808
-1149592
-1149842
-1149802
-1149677
-1149906
-1149669
-1149690
-1149806
-1149947
-1149842
-1149697
-1149884
-1149812
-1149759
-1149964
-1149687
-1149879
-1149871
-1149696
-1149860
-1149862
-1149678
-1148717
-1149672
-1149641
-1149839
-1149880
-1149798
-1149694
-1149699
-1149844
-1149758
-1149673
-1149829
-1149762
-1149848
-1149749
-1149791
-1149822
-1149745
-1149728
-1149879
-1149642
-1149705
-1130690
-1149711
-1149673
-1149813
-1149850
-1149636
-1149735
-1149752
-1149789
-1149887
-1149658
-1149752
-1149892
-1149736
-1149596
-1149914
-1149910
^CCleaning...
Bye!
```

最初の15行を無視して、残りの72個の平均を取ると、-1149504.8なので、

```text

-1149504.8/538 = -2136.6
```

となるのでこの値を使う。別に72個に意味はない。適当に平均を取れば良い。

```python:scale.py

hx.set_reference_unit(-2136)
```

として実行する。最初の -1,0などの表示はまだ測定対象を載せていないときの表示である。四捨五入すると2137だが、まぁ誤差の範囲だろう。

狙い通りの538gが取得できるようになった。

```bash

$ python scale.py 
-1
0
0
-1
-1
-1
60
538
538
538
538
```

# まとめ
load cell を利用してマイコンで重さが取得できるようになり、何らか条件を加えての処理ができる準備が整った。

# 親記事
[Arduino と Raspberry Pi の違い](https://qiita.com/KZ2/items/5e0e79f84e4dd26bd373)