ロードセルを使った簡易スケールの製作

これまで、重さを測定する秤(キッチンスケールとか、体重計とか)の仕組みを考えた事もなかったけれど、ひょんな事から、「重さを量ってパソコンで処理する」という必要性が出てきたので、ちょっとためしてみることにした。

ロードセルには、いろんなタイプがあるが、今回の目的に最適な条件としては、

  • 厚さ(高さ)を要しない事
  • 測定範囲は、最大でも10kg程度
  • 精度は数グラム程度でOK
  • 対象物を置く面積は、そこそこ広い
  • 高価なセンサーはNG
  • 簡単にArduinoへ接続出来ること

【ロードセルの色々】

1 「ロードセル」の画像検索結果 中央部にかかる圧力で重さを計測するタイプ。
2 「ロードセル」の画像検索結果 中央部で測定できるからバランスは良いが、高さが高くなる
3 「load cell」の画像検索結果 安価
いろんな重さ範囲の商品あり。
4 「load cell」の画像検索結果 ハーフブリッジタイプ。フルブリッジにするには2個必要。
薄く出来て、かつ4個使えば広い面積を安定して測定するのに良いが、10kg程度に丁度よい物が見つからない。体重計等で4個使う用途が多い。(50kgタイプ x 4とか)

これらの条件を考えて、今回は3のタイプで10kgのフル・ブリッジ・ロード・セルを使うことにした。(link)


【結線】

フルブリッジのロードセルは、こんな感じの配線になっていて、バーの上下に搭載された歪センサーが、重みによる歪みで抵抗値が変わり、その上下のバランス(差分)を読み取ることにより重さを測定するという仕組み・・・らしい。(今回知った・・・)

抵抗値の変化は非常に小さいので、Arduinoで簡単に使うため、アンプ+ADコンバーターが一体になったモジュール(HX711モジュール)を使うことにした。(このサイトを参考にさせて頂きました

Alloy Steel Tension Compression Load Cell Weighing 5kg - 10t For Hopper Scale

今回購入して使用したロードセルと、HX711モジュールはこちら。

ロードセル HX711モジュール

ロードセルの仕様どおり、赤:E+、黒:E-、緑:A+、白:A- と接続し、Arduinoとは、Dataを “8”, CLKを “6”に接続した。(基板製作記事で作った基板で、MAX6675用にヘッダーを出してあるので、それを活用した)

仕様通りに配線して、HX711からのデータを試しに読んでみると、何故か数値が全部マイナスで出てきてしまった。 何度もデータシートや、WEBの記事を参考にしながら確認したけれど、自分の接続や、ロードセルの矢印の向きは正しいように思うので、「きっと、ロードセルの矢印シールの貼り間違えだろう!!」と勝手に解釈して、ロードセルの上下を逆にして取り付ける事により解決させた・・・(強引・・・)

【ケース加工他】

手元にあったケースを利用して、ロードセルを固定してみた。ロードセルのメカ仕様を見ると、下部固定用のネジはM5、上部固定用のネジはM4となっているので、それに合わせたサイズのスペーサーを間にはさんで、取り付ける形にした。

image

ベース部分の上に、スペーサーを介して、M5のネジでロードセルを固定。
ベース部分の中でHX711(高速化済み)と配線。
天板を外した全体像
天板をM4ネジ二本で固定した。本当は「皿ネジ」で固定すべきだが、手元に無いので・・。  

【ソフトウエア製作編】

まずは、GtiHubのページから、HX711ライブラリのZIPファイルをダウンロードして、ArduinoのIDEにインストールした。

例を真似しながら、読んでみたら簡単にデータが取れた・・・。

 


もちろん、読み取った数値は、「グラム」とかの単位とは全く関係ない大きな数値で、かつ、大きくばらついているが、HX711のADC解像度は24bitもあるから、まぁ当然でしょう。今回の目的では、もともとそんなに精度を必要としていない。

グラムの数値として読めるようにするための方法がGtiHubに次のように書いてあったのでそれに従った。

  1. Call set_scale() with no parameter.
  2. Call tare() with no parameter.
  3. Place a known weight on the scale and call get_units(10).
  4. Divide the result in step 3 to your known weight. You should get about the parameter you need to pass to set_scale.
  5. Adjust the parameter in step 4 until you get an accurate reading.

訳せば、

  1. set_scale() 関数を引数無しで呼ぶ
  2. tare() 関数を引数無しで呼ぶ・・・これで、現在の値がゼロになる。
  3. 重さのわかっている物を載せて、get_units(10)を呼ぶ。(10回平均)
  4. 3のステップの読み取り値を、その重りの重さで割った数値が、set_scale()関数にセットすべき数値になる。
  5. 正しい数値が読めるまで、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

 

手元にあった、1円玉、5円玉、10円玉、50円玉、100円玉をかき集めて、色々な組み合わせで、上記のステップを繰り返して、今回の環境では、「206」という数値を、set_scale()に設定すると、大体・・・正しいグラム値として読み取れることが分かった。

【キャリブレーション】

起動時のゼロ点リセットと、データの平均化、LCDモジュールへの結果出力も追加して、とりあえず、現時点でのコードは、以下の通り。(ただし、次項に記載した、サンプリングの高速化加工をしたHX711を使った時のコード。購入時のデフォルト、10SPSのままでこのコードを走らせると、反応がとても遅いです。起動に30秒くらいかかる。)


#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としておく。

image\

今回のプロジェクトでは、消費電力を気にしない。 ADCのノイズを減らすためには、なるべく多くのデータを平均したほうが良いという考えから、このピンをHにして、80 SPSで使う事にした。ただ、残念ながらこのピンは前述のように、基板上でGNDに接続されており、かつその配線パターンがICの下側で接続されているため、パターンカットで修正することは難しい。

仕方が無いので、このピンを浮かせて、空中配線でVDDへ接続する方法を取った。先端の細いツールを使って、PIN16と PIN15の両方を浮かせ、この2つのピンを接続して、VDDへ接続することによって実現した。(写真では見づらいが、PIN15とPIN16とC6のVDD側が細い単線で繋いである)

image

8倍のサンプリングレート高速化は、価値あり・・と思う。

【スペーサーについて】

スペーサーの選定は、結構頭を悩ませた。 アメリカでは、相変わらずインチが標準単位として使われているが、ネジや、スペーサー、ナットのサイズ等をメートル法のネジ規格と比較する際、とてもわかりにくい(たとえば、M5のネジに最適な大きさの穴を持つスペーサーを探す時の比較とか)

「screw size chart」の画像検索結果

M4ネジ用のスペーサーとして、ナットを使うとした場合、どのサイズが良いのか?と考えると、4.5mm程度の外形のネジのナットを探すとすると、#9か #10が適している事になる。M5ネジ用のスペーサーとしてのナットを探すと、#12用のナットが最適と思われる。

それで、近くのホームセンターのネジコーナーへ行くと、すべての#は無く、#10ネジの次に太いネジは、1/4ネジとある・・・。 とりあえず、これを使ったら用は足したが、わかりにくい・・・・。

ナットを使わず、ちゃんとしたアルミスペーサーをアマゾンで探してみると、また難しい。

  1. #8 Screw Size, 5/16″ OD, 0.166″ ID, 3/16″ Length
  2. #12 Screw Size, 3/8″ OD, 0.218″ ID, 3/16″ Length

ODと、Lengthが分数表記なのに、何故、IDだけは小数表記なのか? 0.218”は、7/32”で、0.166”は・・・・。 全部、mmに変換しないと、とても僕には比較できないが、アメリカ人は、よくこれでやっているなぁ・・・と感心しますわ。

で、実際にこの2つのスペーサーを買ってみると、現物の表記はまたこれとは違い、

  1. 8×3/16 #5/16
  2. 12×3/16 #3/8

となっている。IDは結局内径だから、ネジ番号(#8とか#12とか)を指定すれば自明ということか。わかりにくい・・・。

【課題】

今回、とりあえず、簡単に測定できる秤は出来たが、色々と満足できない課題が残っている。

  • ゼロ点リセット直後でも、測定結果がフラフラしている(0gと、マイナス0gを行ったり来たり)
  • 時間の経過と共に、何も重さを加えていなくても、ゼロ点がずれていく(最大5グラム程度)
  • 周辺の温度が変化すると、ゼロ点の調整がずれる。(最大5グラム程度)

1件のコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です