ロードセル(SC616C)とADコンバータ(HX711)を使用して、Arduinoで質量やトルクを測定する方法を紹介します。githubで公開されているHX711ライブラリを使用することで、校正や測定のプログラムを簡単に記述できます。
使用する部品一覧
- Arduino Mega 2560 (ELEGOO製キット付属品を使用)
- ロードセル シングルポイント(ビーム型) SC616C 500g(秋月電子)
- HX711使用 ロードセル用ADコンバータ モジュール基板
ロードセルの特徴や取り扱い方法
ロードセルは、質量やトルクを測定するために用いられるものです。今回使用するロードセルは、アルミにひずみゲージが貼り付けられており、アルミの先端に力がかかると、その力に対する電圧を出力します。力を加える方向は決まっており、ロードセルの矢印方向に力を加えると、プラスの電圧変化になります。配線は4本あり、電源(赤)、GND(黒)、センサ出力プラス(緑)、センサ出力マイナス(白)、となっています。
ひずみゲージは、金属の抵抗材料を下図のように蛇行させて、その両端に端子を付けたものです。これをアルミ角柱などに貼り付けて、図Bのように蛇行パターンが引き伸ばされる方向に力が加えられると、電気抵抗が高くなります。反対に、図Cのように蛇行パターンが縮む方向に力が加えられると、電気抵抗が小さくなります。
今回使用するロードセルは、最大500gまで測定できます。仕様は下記のとおりです。同じシリーズで、2kg, 10kg, 120kgのロードセルも販売されているようなので、用途に合わせて選んで下さい。
- 定格容量:500g(フルスケール)
- オーバーロード絶対定格:フルスケールの150%
- 定格出力:0.8±0.15mV/V
- 精度:0.05%(フルスケールに対して)
- ゼロバランス:±0.05%(フルスケールに対して)
- リニアリティ誤差:0.05%(フルスケールに対して)
- 印加電圧範囲:3~10V
- 温度範囲:-10℃~+40℃
ロードセル用ADコンバータモジュールHX711の特徴や取り扱い方法
ロードセルの出力電圧をArduinoに取り込むため、ロードセル用のADコンバータモジュールHX711を使用します。分解能は24bitで、Arduinoとの通信は2信号(CLK, DATA)で行います。ロードセルとの接続は4信号(VDD, GND, INA+, INA-)です。HX711はライブラリが公開されており、これを使用すれば、簡単にプログラムを書くことができます。
- 動作電圧:4.5V~5.5V
- 出力データレート:10SPS
- ADコンバータ分解能:24ビット
回路
HX711のチャンネルBは使用しないので、ジャンパーJ3とJ4は半田でショートしておきます。HX711のVDDとGNDは、Arduinoの5VとGNDに接続します。HX711のINA+とINA-は、ロードセルのセンサ出力プラス(緑)とセンサ出力マイナス(白)に接続します。測定した結果は、LCDモジュールに表示させます。HX711のDATAはArduinoの2番ピン、CLKは3番ピンに割り当てました。
組立完成写真
プログラム1
はじめに、動作確認をします。ライブラリを使用するので、以下からダウンロードして下さい。そして、サンプルプログラムを動作させます。この段階ではまだLCDには何も表示されません。
https://github.com/bogde/HX711
/** * * HX711 library for Arduino - example file * https://github.com/bogde/HX711 * * MIT License * (c) 2018 Bogdan Necula * **/ #include "HX711.h" // HX711 circuit wiring const int LOADCELL_DOUT_PIN = 2; const int LOADCELL_SCK_PIN = 3; HX711 scale; void setup() { Serial.begin(38400); Serial.println("HX711 Demo"); Serial.println("Initializing the scale"); // Initialize library with data output pin, clock input pin and gain factor. // Channel selection is made by passing the appropriate gain: // - With a gain factor of 64 or 128, channel A is selected // - With a gain factor of 32, channel B is selected // By omitting the gain factor parameter, the library // default "128" (Channel A) is used here. scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); Serial.println("Before setting up the scale:"); Serial.print("read: \t\t"); Serial.println(scale.read()); // print a raw reading from the ADC Serial.print("read average: \t\t"); Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC Serial.print("get value: \t\t"); Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet) Serial.print("get units: \t\t"); Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided // by the SCALE parameter (not set yet) scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details scale.tare(); // reset the scale to 0 Serial.println("After setting up the scale:"); Serial.print("read: \t\t"); Serial.println(scale.read()); // print a raw reading from the ADC Serial.print("read average: \t\t"); Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC Serial.print("get value: \t\t"); Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare() Serial.print("get units: \t\t"); Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided // by the SCALE parameter set with set_scale Serial.println("Readings:"); } void loop() { Serial.print("one reading:\t"); Serial.print(scale.get_units(), 1); Serial.print("\t| average:\t"); Serial.println(scale.get_units(10), 1); scale.power_down(); // put the ADC in sleep mode delay(5000); scale.power_up(); }
プログラムの中身を簡単に説明します。
14~15行目は、HX711のデータ線とクロック線を接続したポート番号を定義し、32行目でライブラリの初期設定をしています。
34~45行目は、スケールをセットする前の値を読んで表示させています。scale.read()でADコンバータの生値を読みます。scale.read_average(20)とすると、20回平均した値を読めます。scale.get_value(5)は、5回平均してゼロ補正の値を引き算した結果を得ることができますが、ここではまだゼロ補正をしていません。scale.get_units(5)は、get_value(5)をSCALEで割り算した値を得ることができますが、ここではまだSCALEを設定していません。
48~49行目は、スケール設定とゼロ点補正を行っています。set_scale(2280.f)は、ADコンバータの生値をグラムに変換するSCALEを設定しています。この値は、おまじないだと思い、そのまま使います。scale.tare()は、ゼロ点補正です。例えば、空のトレイを0gと表示させる場合は、トレイを載せた状態で、この関数を実行します。
51~63行目は、スケール設定とゼロ点補正を行った場合の値を表示させています。先程、生値を表示させたときの対比ですね。
loop内では、1回測定した値と5回平均した値を5000msごとに表示させています。power_down()でADコンバータをスリープモードに入れることができ、省電力状態になります。power_up()でADコンバータを起動して測定します。
プログラム2
次に、測定した質量をLCDに表示するプログラムを作ります。LCDを使ったプログラムは以前に作成しており(ArduinoでSTEM教育 基礎編:LCDモジュール)、これをそのまま流用します。プログラムの中身は単純で、setup内でゼロ点補正とスケール設定をし、loop内で10回測定の平均値をLCDに表示し、1000ms毎にそれを繰り返します。
//stemship.com //2020.06.17 #include "HX711.h" #include <LiquidCrystal.h> // HX711 circuit wiring const int LOADCELL_DOUT_PIN = 2; const int LOADCELL_SCK_PIN = 3; HX711 scale; LiquidCrystal lcd(7, 8, 9, 10, 11, 12); void setup() { //LCD設定 lcd.begin(16, 2); // LCDを2行16列で使用する lcd.print("Initializing"); //LCDの1行目に表示する内容 //HX711設定 Serial.begin(38400); scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details scale.tare(); // reset the scale to 0 lcd.setCursor(0, 0); lcd.print("Measuring "); //LCDの1行目に表示する内容 lcd.setCursor(7, 1); lcd.print("[g]"); } void loop() { float value=0; Serial.print("read average: \t\t"); value = scale.get_units(10); Serial.println(value); lcd.setCursor(0, 1); lcd.print(value); scale.power_down(); // put the ADC in sleep mode delay(1000); scale.power_up(); }
動かしてみよう
1円玉を1枚ずつ載せて、測定してみました。結果、1枚当たり1.3~1.4gと表示されました。汚れた1円玉なので何とも言えませんが、少し重めに表示されていそうなので、分銅などを使ってスケール調整をしたほうがよさそうですね。
今回学んだポイント
HX711とそのライブラリを使うことで、面倒なゼロ点補正や平均値処理を簡単にプログラムすることができました。正確に測りたい場合は、スケール調整が必須です。ボタンを追加して、簡単にスケール調整できる機能があれば便利かもしれませんね。
コメントを残す