ロードセルを使ってみる

さを計る、ロードセルを使ってみました。

前回の豆知識で紹介した、2021年大学入学共通テスト 物理の、実際の使用例です。



子回路は、ロードセル → HX711モジュール → Arduinoの流れです。

ロードセルは、ホイーストンブリッジの形にひずみゲージが貼られ、ひずみを電気信号にし、出力します。

ロードセルだけでは、重りを載せた際、うまくひずんでくれません。

そこで上手くひずむよう、2点で固定させています。

物を載せる面は、アクリル板を使い、乗せやすくなっています。

ロードセルを使うには、上手くひずませたり、物を乗せやすくするなど、工夫が必要な事が分かります。

 
5kgまで測定できるタイプです。
 
 
 
 
2点で固定し、ひずみやすくなっています。
円形のアクリルの上に、物をのせます。


ードセル用のICは、HX711を使います。

HX711は、24ビットの信号を出力するADコンバーターです。

アンプとしての機能もあります。

ロードセルには、このICを使った、HX711モジュールが良く使われています(2021年2月現在)。

アマゾンだけでなく、秋月電子でも購入できます。

HX711使用 ロードセル用ADコンバータ モジュール基板 K-12370 ¥350

モジュールなので配線は、ロードセルにつなぐだけです。

Arduino側は、VCC(プラス5V)、GND(0V)、DT(データ線)、SCK(シリアルクロック)の4端子です。

HX711のデータシートに記載されたクロックを、ArduinoからHX711へ入力すると、HX711からArduinoへシリアル24ビットでデータが送られきます。

HX711から送られてくるデータの値は、HX711独特のデータです。


データシートを見ると、2の補数と記載されています。


rduinoの配線は、簡単です。

HX711モジュールからきている線を、配線します。

VCC(プラス5V)、GND(0V)はArduinoの電源端子に、DT(データ線)は8番端子、SCK(シリアルクロック)は9番端子です。

別に8番端子と9番端子以外でも良いのですが、ネットの情報に8番と9番を使う事が多いので、同じようにしました。


ログラムは、HX711モジュールから値を読み出すプログラムが、データーシートに記載されています。

アセンブリとCの2つが記載されています。

今回は、Arduinoに移植するため、Cを参考にしました。

Arduinoのスケッチに、移植したソースは、これです。

ロードセルからの信号を値にし、Arduinoのシリアルコンソール画面に表示します。

値は、HX711特有の値なので、gやkgではありません。

Arduinoに書き込み、重りを載せると、数字が変わるのが分かります。

プログラム1 Arduinoのシリアルコンソール画面に、値を出力するプログラム
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT);
pinMode(8, INPUT);
}

void loop() {
long atai=0;

for (char i = 0; i < 24; i++) {
digitalWrite(9, 1);
delayMicroseconds(1);
digitalWrite(9, 0);
delayMicroseconds(1);
atai = (atai << 1) | (digitalRead(8));
}

atai = atai ^ 0x800000;
Serial.println(atai);
delay(300);
}


↑右上のコンソール画面の数字が、パラパラ変わります。


ログラム1では使い難いので、g表示になるように追記したプログラムが、プログラム2です。

setupで、何も乗っていない時の値を1回だけ読み込みます。

重さを測定した結果は、omosa = ((atai - saisyo) / 1000) *2.2;の部分です。

測定結果ataiから、何ものっていない時の値saisyoをひいています。

さらにHX711特有の値は桁数が大きいので、1000で割っています。

2.2の部分は、g換算している部分です。

g換算にする式の求め方は、次のとおりです。

1kgの重りを乗せた時、HX711特有の値を求めます。

求めたHX711特有の値が1kgのため、

求めたHX711特有の値 × g換算する係数 = 1kg

これを計算すると、 g換算する係数=2.2でした。

値の微調整は、 omosa = ((atai - saisyo) / 1000) *2.2;の式の中で行えば良いです。

プログラム2 g表示にしたプログラム

long saisyo = 0;

void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT);
pinMode(8, INPUT);

delay(300);
for (char i = 0; i < 24; i++) {
digitalWrite(9, 1);
delayMicroseconds(1);
digitalWrite(9, 0);
delayMicroseconds(1);
saisyo = (saisyo << 1) | (digitalRead(8));
}
saisyo = saisyo ^ 0x800000;

}

void loop() {

long atai = 0;

for (char i = 0; i < 24; i++) {
digitalWrite(9, 1);
delayMicroseconds(1);
digitalWrite(9, 0);
delayMicroseconds(1);
atai = (atai << 1) | (digitalRead(8));
}

atai = atai ^ 0x800000;

long omosa;
omosa = ((atai - saisyo) / 1000) *2.2; //saisyoは何も乗っていない時の出力の値、桁が大きいので1000で割っている
Serial.println(omosa);

delay(300);
}


定すると、次のようになりました。

何も乗せていない時は、Arduinoのシリアルコンソール画面は、0と表示されています。

500gの鉛インゴットを乗せると、508と表示されます。

1000gの鉛インゴットを乗せると、1011と表示されます。

まだ、誤差があります。

シビアな値を求めるには、まだ改善の余地がありますが、重さがかかった、かからないといった、デジタルセンサーとして使うなら、すぐに使えます。


今回、データシートを見てプログラムしていますが、ArduinoのHX711ライブラリーが多く出回っています。

正確な測定をするなら、ライブラリーを使う事をお勧めします。

 

500gのインゴットを乗せた所

Arduinoのシリアルコンソール画面
やや誤差があります。
 
1000gのインゴットを乗せた所
1011と表示されています。
最初の220と886は、重りを載せた直後の値です。


ちなみに台全体をを引っ張ると、マイナスの表示になります。





数まで表示できるようにすると、次のようになります。

だんだんソースが長くなり、見にくくなってきました。

小数部分は、ロードセルの置く場所、電圧の状況、外部からのノイズ、内部の熱ノイズなど、色々な影響をうえているようで、パラパラ変動します。

小数まで正確に測るには、小さな値用のロードセルを購入したり、ロードセルの電圧を一定にするなど、対策が必要のようです。


プログラム3 小数も表示できるようにしたプログラム

long saisyo = 0;

void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT);
pinMode(8, INPUT);

delay(1000);
for (char i = 0; i < 24; i++) {
digitalWrite(9, 1);
delayMicroseconds(1);
digitalWrite(9, 0);
delayMicroseconds(1);
saisyo = (saisyo << 1) | (digitalRead(8));
}
saisyo = saisyo ^ 0x800000;

}

void loop() {

long atai = 0;

for (char i = 0; i < 24; i++) {
digitalWrite(9, 1);
delayMicroseconds(1);
digitalWrite(9, 0);
delayMicroseconds(1);
atai = (atai << 1) | (digitalRead(8));
}

atai = atai ^ 0x800000;

long omosa;
omosa = ((atai - saisyo) / 10) * 2.2;
Serial.print(omosa / 100); Serial.print(".");

long syousuu = ((atai - saisyo) / 10) * 2.2;
// Serial.println(syousuu);
byte a[4];
a[0] = (syousuu % 10); syousuu = syousuu / 10;
a[1] = (syousuu % 10); syousuu = syousuu / 10;
a[2] = (syousuu % 10); syousuu = syousuu / 10;
a[3] = (syousuu % 10);

Serial.print(a[1]); Serial.print(a[0]); Serial.println("g");

delay(500);
}



ードセルのようなアナログセンサーは、出力されるデータが、一般的に馴染みのない値2の補数で出力される事があります。

特に今回のように、重りをのせた場合(プラスの値)と、引っ張った場合(マイナスの値)を出力するため、HX711モジュールからは、2の補数として値が出力されます。

なぜ、2の補数として出力するかと言うと、現代のコンピューターは、基本的に0又は1を足し計算しているため、基本的に引き算の回路がありません。

ロードセルを引っ張った場合、マイナスの値を出力させますが、コンピュータはマイナスの概念がないので、マイナスの変わりに、2の補数を出力します。

【補数について】

補数は、コンピュータでマイナスを扱う時に使います。

コンピュータは、引き算の回路がないので、引き算をする場合やマイナスを表現する場合は、2の補数を使い処理します。

例えば、7−6=1です。

6の補数は、補数の定義より、10−6=4なので、4です。

7+6の補数 = 7+4 = 1 です。

十の位の1を無視すると、一の位はです。

7−6= ですが、一の位はと同じ値です。

このように、補数を使うと、足し算を使って、引き算が出来るようになります。

なぜ足し算が引き算になるかと言うと、たくさん足して桁をあげ、あがった位は無視し、下の位だけ考えているからです。

コンピュータが計算する箱の大きさが、8桁しか無い場合、9桁の位は保存できず、無視されてしまうからです。


ちなみに、7−6=1で、6の補数は4でしたが、これは10進法における補数です。

コンピュータは2進法なので、2の補数を使います。
 

【センサーから出力されるデータについて】

センサーから出力される値(アナログ値)は、大きく分けると5つの分類があります。

アナログ値

SBC
CSB
OBC
COB
CTC
+フルスケール
1111
0000
1111
0000
0111
0010
0001
1010
0101
0010
0001
0010
1001
0110
0001
0000
1111
1000
0111
0000
−1
0111
1000
1111
−2
0110
1001
1110
−フルスケール
0000
1111
1000
 
コンプリメンタリ
コンプリメンタリ
2の補数


SBC(ストレート・バイナリー・コード)
CSB(コンプリメンタリ・ストレート・バイナリー・コード)
OBC(オフセット・バイナリー・コード)
COB(コンプリメンタリ・オフセット・バイナリー・コード)
CTC(コンプリメンタリ・2’S・コード)
※2進数表記です。

SBCは、単純な比例で出力されます。
CSBは、SBCの0と1を逆にしたものです。

OBCは、SBCとCSBはマイナス表現が出来ないので、マイナス表現を可能にするために生まれました。
ビット数は増えますが、中央の0を基準にした考え方です。
COBは、OBCの0と1を逆にしたものです。

CTCは、アナログ値の0と、基準の0000を合わせた考え方です。
OBCとCOBでも良かったのでしょうが、合わせたほうがしっくりくるため合わせた考え方です。
2の補数を使って表現していて、結論だけ言えば、OBCのMSBだけ反転したものです。

 
【C言語(Arduino言語)の宣言について】

プログラムでは、定数や変数を使う場合、intやlongなどで、宣言します。

intを見てみると、int と unsigned  int の2種類があります。


intは、符号付き整数型で、値の範囲は-32768から32767までです。

負の数は2の補数で表現し、最上位のビットは符号ビットともいわれ、1だとマイナス、0だとプラスを意味します。


unsigned intは、符号なし整数型で、負の数が扱えず、0から65535までの正の数だけを格納します。

unsigned intは符号なしのため、符号ビットの概念がありません。

その代わり、沢山の正の数が格納できます。

今回のロードセルは、人間にとっては、2の補数で出力されても分からないため、人が分かる単位、gやkgなどに変換する必要があります。

Arduinoのスケッチで、atai = atai ^ 0x800000;の部分で、2の補数を符号付の整数にしています。

これでOBCの状態になりました。

ataiは、longで定義しているので、符号ビット付きです。

そのため、Arduinoのコンソール画面では、符号ビット付きの場合は、マイナス表示に変換してくれます。


今回作ったロードセルのプログラムで、 g換算は omosa = ((atai - saisyo) / 1000) *2.2;の部分です。

omosaもlongで定義しているので、符号ビット付きです。

そのため、Arduinoのコンソール画面では、符号ビット付きの場合は、マイナス表示に変換してくれます。



まとめると、信号の流れは次のとおりになります。

ロードセルは、ひずみゲージの抵抗値を電圧に変換
  ↓
HX711で増幅し、2の補数で出力
  ↓
Arduinoのプログラムで2の補数を受信し、OBCへ変換
  ↓
Arduinoのプログラムで人が分かるgに変更
  ↓
Arduinoのコンソール画面は、符号付きの場合はマイナスを表示


 
(2021年2月5日(金)作成)


 
 

 
Contents are copyright (c) 2009 MASAKATSU BABA All rights reserved.
This site is best viewed with Internet Exploerer 4.0, Netscape Navigator 4.0 or later
ホームページに関するご意見・ご要望はこちらまで .
 


  1. 無料アクセス解析