VR空間移動用いす型デバイスを作成する④体重計から重量センサの出力を読み取ってみる

技術説明です。作り方です。
体重計に使われている重量センサ（ロードセル）の出力をArduinoを使用して読み取ってみます。

#目次
１．体重計の中身
２．体重計の大きさを変えてみる
３．増幅回路の作成
４．ArduinoUNOを使う

#１．体重計の中身
ここではタニタの体重計「HD660」を使用します。ほかの体重計や重量センサを使用する場合はセンサから出ている配線の数や色が異なっている可能性があるので注意です。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/b9f1a4d5-a69a-4964-e871-f6477714a1bf.png>
重量センサ自体はネット上の電子部品ショップでも手に入ります。あえて、体重計を買う理由は安いからです。この値段で重量センサ４つ＋センサ用の筐体と足部が手に入るのはお得です。
買ったら筐体を開けてみましょう、四隅に重量センサが配置されています。
中心部の基板は不要です。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/58ffcff0-7ed2-c05d-ee98-e317f59642fc.png>
四隅のカバーの中にある金属の部品が重量センサ（ロードセル）です。
重いものが載ると金属は曲がる。金属も含め物体は曲がると伸びます。伸びると抵抗値が変化します。つまり抵抗値を見てやれば重さがわかるという原理です。
<img width=30% src=https://qiita-image-store.s3.amazonaws.com/0/184089/b2dacc47-e660-0402-5679-ee5c038859e5.png>
重量センサから配線が赤、白、緑の3本出ている。
抵抗値を測定すると、赤‐白間2kΩ、赤‐緑間1kΩ、白‐緑間1kΩであった。下記のように抵抗が直列につながっているのではないか。
<img width=50% src=https://qiita-image-store.s3.amazonaws.com/0/184089/32eede5c-86c2-ec63-a583-3ce88ed36b58.png>
この1kΩの抵抗二つのうちのどちらかまたは両方の値が変化すると思われる。

#２．体重計の大きさを変えてみる
体重計では少しサイズが小さい。使いやすいように改造してみました。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/2db9ff84-a7b9-2bc7-715a-e6fbcd798f4e.png>
中を開けた後、中央の基板とセンサの接続を外し、のこぎりで３分割してみます。配線は細く切れやすいので、センサに近いところで切断し、別に太い配線を購入して、はんだ等でつないだほうが良いでしょう。配線は電子部品のお店やホームセンターで売っています。細い配線の方は筐体にテープで固定＆保護しておくと何かにぶつかったりして切れる心配がなくなるかと思います。太い線の先にはArduinoとの接続用にコネクタをつけています。
次にAL板を梁として間に渡します。ホームセンターにあります。金属は平板だと曲がりやすいため、上下の縁にはL字の物を使っています。両面テープと接着剤でつけてます。
この上に百均の衝撃吸収パッドを並べ、上にホームセンターで買った３㎜のアクリル板を載せます。アクリル板についているのは振動モーターです。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/7054b54e-bc7f-4c8a-7eb1-49a5881eadac.png>
振動モーターの話はここではしませんが、わざわざ３㎜のアクリル板を使っているのは振動させるためです。厚い板だと振動モーターで振動させるのが難しくなります。振動モーターを使用しない場合はALや樹脂の板など使用せず、そのまま上に厚みのある木板を直接乗せたほうが作成が楽でしょう。
そのままでは上に座りにくいので、上にスポンジなんかつけてやるとよいかと。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/46a6d671-f2af-977a-e0b0-ee1a3c1ff5a0.png>

#３．増幅回路の作成
抵抗値の変化を電圧値の変化にするための回路を組みましょう。ブリッジ回路とか言われてるやつです。
<img width=50% src=https://qiita-image-store.s3.amazonaws.com/0/184089/249d58e8-bfcf-acbc-e7c8-162cf3dc7023.png>
<font color="Red">　修正（2017/12/03）'配線（白）と配線（赤）の接続が逆であったため修正’</font>

1kΩの抵抗を直列につなぎ、ロードセルの内部構成と同じものを作ってやります。これとロードセルとの差を見てやります。何も乗ってなければ差は0ですが、モノが乗るとロードセルの抵抗値が変化するため、差が出てきます（1kgの重さに対し3，40μVくらいか？）。
ここで使用する1kΩの抵抗2本（上の回路図のR1、R2）はデジマル（デジタルマルチメーターね）で抵抗値を測定し、選んでください。デジマルは1Ωくらいまで見れるものが良いでしょう。抵抗は100本入りの物でも安く売られている（カーボン抵抗なら100円とか）ので、これを購入し、1Ωまで合う2本を探してください（0.998kΩと0.998kΩとか）。
普通に売られている抵抗はカーボン抵抗と金属皮膜抵抗の2種類ですが、カーボン抵抗は±5％、金属皮膜抵抗で±1％の誤差を持っています。後述するように増幅回路で360倍するので1％の誤差も360％になってしまいます。0.1％まで合わせてやれば、36％で済みます。
もし、デジマルがないとかめんどくさい場合は、少し高いが（といっても100～200円）高精度の金属皮膜抵抗を使う手もありかなぁ・・・。

次にArduinoUNOで取得できるように増幅回路で値を大きくします。
全体の回路は下のようになります。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/4ff27314-40a9-83fe-6543-b0d7181ed921.png>
<font color="Red">　修正（2017/12/03）’配線白と配線赤の接続が逆であったため修正’</font>
<font color="Red">　修正（2018/11/25）’NJM2902→NJM2747DN　NJM2902フルスイングちゃうやん’</font>

ArduinoUNOのアナログ入力は5Vで使用した場合4.9mVくらいの分解能で電圧値を取得できます。この分解能でも十分なように360倍の増幅回路を組みます。オペアンプにはNJM2747Dを使用しています（5Vで動き、出力フルスイングが良いかと）。出力はArdunoUNOのA0～A3につなぎます。
実際の回路とか
<img width=50% src=https://qiita-image-store.s3.amazonaws.com/0/184089/9fb0b28b-40f9-188f-43dc-94b702122a60.png>

#４．ArduinoUNOを使う
ArduinoUNOを使います。ネットとかいろんなところで手に入ります。
A0～A3ピンの電圧値を読み取ってPCに表示できるようにプログラムを書いてみます。
以下のようにArduinoのスケッチに書き込んでみました。

```
float analogInput[4];

void setup() {
	Serial.begin(9600);
}

void loop() {
	delay(500);
	for(int a = 0;a < 4;a++) analogInput[a] = analogRead(a)*4.88/1000;
	Serial.print("Analog");
	Serial.print("LR ");
	Serial.print(analogInput[0],2);
	Serial.print("V  LF ");
	Serial.print(analogInput[1],2);
	Serial.print("V  RR ");
	Serial.print(analogInput[2],2);
	Serial.print("V  RF ");
	Serial.print(analogInput[3],2);
	Serial.print("V");
	Serial.print("\n");
}
```

Arduinoのツール→シリアルモニタを起動し結果を見てみます。
デバイスの上に乗ると電圧値が変化するのがわかります。
<img width=75% src=https://qiita-image-store.s3.amazonaws.com/0/184089/fbf327a9-b49b-7284-6995-aa9613c887aa.png>

ちょっと解説です。
ⅰ．Arduinoのプログラムについて
　delay(500)　⇒　500ms毎に動作。時間に特に意味はない。
　analogRead(a)*4.88/1000　⇒　analogReadで各ピンのアナログ値を取得します。For文で４回繰り返すことで、A0～A3までの4ピンの値を取得します。ArduinoUNOでは0～5Vまでを0～1023の数値で表しますので、1あたり約4.88mVとなります。取得した値に×4.88/1000することで、電圧値（V）になります。
　Serial.print(analogInput[0],2)　⇒　PC側へ数値を文字形式に変換して送っています。小数点以下をすべて送ると長いので、,（カンマ）の後に2をつけて小数点以下は2桁のみとした。直前にあるLRとかの文字は、単純に座った時に重量センサのある位置が左後（Left Rear）でどの位置のセンサか区別するためにつけてます。

ⅱ．結果について
　何も乗っていない場合は理想的には2.5Vが出力されるはずですが、実際には最大で0.6V程度ずれた値（1.88Vが出力）が出力されています。２．で説明した抵抗値の誤差が大きな要因ではありますが、ほかにもいろいろ誤差発生要因がアナログ回路にはありこのようなずれになりまいた。1Ωレベルまで抵抗を選別してこれなので、そのまま使用してしまうと5Vや0Vに張り付いてしまう可能性があります。回路で抑えるような工夫をすることも可能でしょうが、選別したほうが楽かと思います。
　乗ってみると電圧値が上がります。乗ってない時との電圧値の差がセンサにかかっている重量になります。私の体重が60㎏で4つの重量センサの変化分が計750mVくらいありそうです。Arduino側の分解能4.88mVとすると、0.4㎏の変化までは見えそうです。まあ、十分でしょうか。

以上になります。

UnityとかのPCとのデータの受け渡しをどうするのかについては、ネット上にいろいろあるので参考にして作ってください。
次はいすの回転を検知してみたいかと。