これまで、重さを測定する秤(キッチンスケールとか、体重計とか)の仕組みを考えた事もなかったけれど、ひょんな事から、「重さを量ってパソコンで処理する」という必要性が出てきたので、ちょっとためしてみることにした。
ロードセルには、いろんなタイプがあるが、今回の目的に最適な条件としては、
- 厚さ(高さ)を要しない事
- 測定範囲は、最大でも10kg程度
- 精度は数グラム程度でOK
- 対象物を置く面積は、そこそこ広い
- 高価なセンサーはNG
- 簡単にArduinoへ接続出来ること
【ロードセルの色々】
1 | 中央部にかかる圧力で重さを計測するタイプ。 | |
2 | 中央部で測定できるからバランスは良いが、高さが高くなる | |
3 | 安価 いろんな重さ範囲の商品あり。 |
|
4 | ハーフブリッジタイプ。フルブリッジにするには2個必要。 薄く出来て、かつ4個使えば広い面積を安定して測定するのに良いが、10kg程度に丁度よい物が見つからない。体重計等で4個使う用途が多い。(50kgタイプ x 4とか) |
これらの条件を考えて、今回は3のタイプで10kgのフル・ブリッジ・ロード・セルを使うことにした。(link)
【結線】
フルブリッジのロードセルは、こんな感じの配線になっていて、バーの上下に搭載された歪センサーが、重みによる歪みで抵抗値が変わり、その上下のバランス(差分)を読み取ることにより重さを測定するという仕組み・・・らしい。(今回知った・・・)
抵抗値の変化は非常に小さいので、Arduinoで簡単に使うため、アンプ+ADコンバーターが一体になったモジュール(HX711モジュール)を使うことにした。(このサイトを参考にさせて頂きました)
今回購入して使用したロードセルと、HX711モジュールはこちら。
ロードセル | HX711モジュール |
ロードセルの仕様どおり、赤:E+、黒:E-、緑:A+、白:A- と接続し、Arduinoとは、Dataを “8”, CLKを “6”に接続した。(基板製作記事で作った基板で、MAX6675用にヘッダーを出してあるので、それを活用した)
仕様通りに配線して、HX711からのデータを試しに読んでみると、何故か数値が全部マイナスで出てきてしまった。 何度もデータシートや、WEBの記事を参考にしながら確認したけれど、自分の接続や、ロードセルの矢印の向きは正しいように思うので、「きっと、ロードセルの矢印シールの貼り間違えだろう!!」と勝手に解釈して、ロードセルの上下を逆にして取り付ける事により解決させた・・・(強引・・・)
【ケース加工他】
手元にあったケースを利用して、ロードセルを固定してみた。ロードセルのメカ仕様を見ると、下部固定用のネジはM5、上部固定用のネジはM4となっているので、それに合わせたサイズのスペーサーを間にはさんで、取り付ける形にした。
ベース部分の上に、スペーサーを介して、M5のネジでロードセルを固定。 | |
ベース部分の中でHX711(高速化済み)と配線。 | |
天板を外した全体像 | |
天板をM4ネジ二本で固定した。本当は「皿ネジ」で固定すべきだが、手元に無いので・・。 |
【ソフトウエア製作編】
まずは、GtiHubのページから、HX711ライブラリのZIPファイルをダウンロードして、ArduinoのIDEにインストールした。
例を真似しながら、読んでみたら簡単にデータが取れた・・・。
1 |
もちろん、読み取った数値は、「グラム」とかの単位とは全く関係ない大きな数値で、かつ、大きくばらついているが、HX711のADC解像度は24bitもあるから、まぁ当然でしょう。今回の目的では、もともとそんなに精度を必要としていない。
グラムの数値として読めるようにするための方法がGtiHubに次のように書いてあったのでそれに従った。
- Call set_scale() with no parameter.
- Call tare() with no parameter.
- Place a known weight on the scale and call get_units(10).
- Divide the result in step 3 to your known weight. You should get about the parameter you need to pass to set_scale.
- Adjust the parameter in step 4 until you get an accurate reading.
訳せば、
- set_scale() 関数を引数無しで呼ぶ
- tare() 関数を引数無しで呼ぶ・・・これで、現在の値がゼロになる。
- 重さのわかっている物を載せて、get_units(10)を呼ぶ。(10回平均)
- 3のステップの読み取り値を、その重りの重さで割った数値が、set_scale()関数にセットすべき数値になる。
- 正しい数値が読めるまで、4の数値を修正する。
という事。これに従ってやろうとしたが、さて、「重さのわかっている物」が手元に無いこと」に気がついた。適当に、500mlの水の入ったペットボトル、とか試してみたがすっきりしない。そこで、「そうだ、コインがあるじゃないか・・・」と思い立ち、日本の各コインの重さを調べてから、基準の重さとして使ってみることにした。
日本のコインの重さは、このページを参考にさせていただいた。
コインの種類 | 材質 | 直径(cm) | 重さ(g) |
1円 | アルミ100% | 20.0 | 1.0 |
5円(黄銅貨幣) | 銅60~70% 亜鉛40~30% |
22.0 | 3.75 |
10円(青銅貨幣) | 銅95% 亜鉛4~3% スズ1~2% |
23.5 | 4.5 |
50円(白銅貨幣) | 銅75% ニッケル25% |
21.0 | 4.0 |
100円(白銅貨幣) | 銅75% ニッケル25% |
22.6 | 4.8 |
500円(ニッケル黄銅貨幣) | 銅72% 亜鉛20% ニッケル8% |
26.5 | 7.0 |
【キャリブレーション】
起動時のゼロ点リセットと、データの平均化、LCDモジュールへの結果出力も追加して、とりあえず、現時点でのコードは、以下の通り。(ただし、次項に記載した、サンプリングの高速化加工をしたHX711を使った時のコード。購入時のデフォルト、10SPSのままでこのコードを走らせると、反応がとても遅いです。起動に30秒くらいかかる。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include "HX711.h" #include <LiquidCrystal.h> LiquidCrystal lcd(A5, A4, A3, A2, A1, A0); // = (RS,E,D4,D5,D6,D7) HX711 scale(8, 6); // (data, clk) parameter "gain" is ommited; the default value 128 is used by the library #define N_AVERAGE 3 float xx[N_AVERAGE] = {0.0}; void setup() { int i; Serial.begin(115200); lcd.begin(16, 2); //16 columns x 2 rows scale.set_scale(205.3f); lcd.setCursor(0, 0); lcd.print("Calibrating... "); delay(400); scale.tare(50); delay(400); scale.tare(50); lcd.setCursor(0, 0); lcd.print("Done. "); delay(1000); } void loop() { float v; float sum = 0.0; for (byte i = 1; i < N_AVERAGE; i++ ) { xx[i - 1] = xx[i]; sum += xx[i]; } xx[N_AVERAGE - 1] = scale.get_units(20); // no averaging in the function; sum += xx[N_AVERAGE - 1]; v = sum / N_AVERAGE; // v = scale.get_units(10); Serial.println(v, 0); lcd.setCursor(0, 0); lcd.print(v, 0); lcd.print(" "); // scale.power_down(); // put the ADC in sleep mode // delay(200); // scale.power_up(); } |
【サンプリング周期の高速化】
HX711のモジュールの設計では、HX711のPIN15(RATE)は、基板上でGNDに接続されているが、このピンを、”H”に設定することにより、簡単にHX711のサンプリングレートを、10SPSから、80SPSへ上げる事が出来る。(データシートの2ページ参照) 80SPSにすることに寄り、測定精度等への副作用があるのか?という心配はあるが、データシートをパラパラッと見たところによると、そういう記載は見つからないので、とりあえずOKとしておく。
今回のプロジェクトでは、消費電力を気にしない。 ADCのノイズを減らすためには、なるべく多くのデータを平均したほうが良いという考えから、このピンをHにして、80 SPSで使う事にした。ただ、残念ながらこのピンは前述のように、基板上でGNDに接続されており、かつその配線パターンがICの下側で接続されているため、パターンカットで修正することは難しい。
仕方が無いので、このピンを浮かせて、空中配線でVDDへ接続する方法を取った。先端の細いツールを使って、PIN16と PIN15の両方を浮かせ、この2つのピンを接続して、VDDへ接続することによって実現した。(写真では見づらいが、PIN15とPIN16とC6のVDD側が細い単線で繋いである)
8倍のサンプリングレート高速化は、価値あり・・と思う。
【スペーサーについて】
スペーサーの選定は、結構頭を悩ませた。 アメリカでは、相変わらずインチが標準単位として使われているが、ネジや、スペーサー、ナットのサイズ等をメートル法のネジ規格と比較する際、とてもわかりにくい(たとえば、M5のネジに最適な大きさの穴を持つスペーサーを探す時の比較とか)
M4ネジ用のスペーサーとして、ナットを使うとした場合、どのサイズが良いのか?と考えると、4.5mm程度の外形のネジのナットを探すとすると、#9か #10が適している事になる。M5ネジ用のスペーサーとしてのナットを探すと、#12用のナットが最適と思われる。
それで、近くのホームセンターのネジコーナーへ行くと、すべての#は無く、#10ネジの次に太いネジは、1/4ネジとある・・・。 とりあえず、これを使ったら用は足したが、わかりにくい・・・・。
ナットを使わず、ちゃんとしたアルミスペーサーをアマゾンで探してみると、また難しい。
ODと、Lengthが分数表記なのに、何故、IDだけは小数表記なのか? 0.218”は、7/32”で、0.166”は・・・・。 全部、mmに変換しないと、とても僕には比較できないが、アメリカ人は、よくこれでやっているなぁ・・・と感心しますわ。
で、実際にこの2つのスペーサーを買ってみると、現物の表記はまたこれとは違い、
- 8×3/16 #5/16
- 12×3/16 #3/8
となっている。IDは結局内径だから、ネジ番号(#8とか#12とか)を指定すれば自明ということか。わかりにくい・・・。
【課題】
今回、とりあえず、簡単に測定できる秤は出来たが、色々と満足できない課題が残っている。
- ゼロ点リセット直後でも、測定結果がフラフラしている(0gと、マイナス0gを行ったり来たり)
- 時間の経過と共に、何も重さを加えていなくても、ゼロ点がずれていく(最大5グラム程度)
- 周辺の温度が変化すると、ゼロ点の調整がずれる。(最大5グラム程度)
コメント
[…] ← 前へ […]
突然失礼いたします、私も今ArduinoとHX711を使ってロードセルの制御をしようとしているのですが、キャリブレーションがうまくいかず困っています。
上記に
3のステップの読み取り値を、その重りの重さで割った数値が、set_scale()関数にセットすべき数値になる。
とあるのですが「その重りの重さで割った数値」の部分の単位はgなのでしょうか?それともポンドなのでしょうか?その辺りがわかりませんでした。
教えていただけると嬉しいです
[…] 使い方は、 こちらのサイトで丁寧に説明されてますが、Arduinoです。 http://bcn.xsrv.jp/?p=23 […]
[…] […]
[…] ●HX711プログラム 私は、VBA,mbed、Processingが得意でArduinoは、あまりいじったことがないので、3時間くらいかかりました。 参考にさせていただいたサイトは、昔からリンクさせていただいていますがArduinoを使うにあたって改めて参考にさせていただきました。数多くのリンク客が訪れているサイト様です。 http://bcn.xsrv.jp/?p=23 […]
[…] ●HX711プログラム 私は、VBA,mbed、Processingが得意でArduinoは、あまりいじったことがないので、3時間くらいかかりました。 参考にさせていただいたサイトは、昔からリンクさせていただいていますがArduinoを使うにあたって改めて参考にさせていただきました。数多くのリンク客が訪れているサイト様です。 http://bcn.xsrv.jp/?p=23 […]
[…] 使い方は、 こちらのサイトで丁寧に説明されてますが、Arduinoです。 http://bcn.xsrv.jp/?p=23 […]
[…] 使い方は、 こちらのサイトで丁寧に説明されてますが、Arduinoです。 http://bcn.xsrv.jp/?p=23 […]