スタートアップエンジニアの作ってみた日記

ものづくりが下手な横好きなエンジニアによる作ってみた的なブログです。

Arduinoで重さ計測してみた(ロードセルを使ってみた)

重さを計測したいと思い、簡単に手に入るロードセルを使って重さ計測してみました。

要求スペックとしては
最大計測重量 2kg
分解能 0.1g

使ったのは以下の二つです。
Arduino uno
Amazonで購入したロードセル(Arduinoと接続するためのモジュール付き)
購入したロードセルはこちらです。

www.amazon.co.jp



こちらの商品はロードセルとArduinoの通信(アンプ+AD変換)を行うためのモジュールがついているので、便利です。
これがないとArduinoにて使えません。
ただし、モジュールはピンがハンダづけされていないので、ハンダ付けする必要があります。
ハンダ付けができない方はもともとピンがハンダ付けされているものを選んで購入しましょう。


購入して届いたロードセルがこちら

f:id:goengine:20190324230904j:plain

(手前のねじ穴に青い物体がつまっているのは、固定用に3Dプリンタの部品を詰め込んだら折れてしまったものです。当然、買ったときにはねじ穴が空いています。)

使い方は、奥側のねじ穴の部分をベースに固定して、手前の矢印のシールが貼ってあるほうに重量物を載せるための皿などを固定して計測をします。

f:id:goengine:20190324231359p:plain

このロードセルは写真の白い樹脂が塗ってあるところに歪みを計測する歪みセンサーが入っており、その歪みを計測することで重量を計測しています。なので、重量に対して正しく金属歪ませることが正確に測定するコツになります。なので、固定をしっかりと行うことが重要になります。
きちんと固定しないとロードセル自体が傾いたりしてしまい正しく計測できません。(かくいう僕もネジが手元になかったので、適当に固定して計測しました。。そして苦戦しました、、)

次に接続についてです。
以下のようにArduino、モジュール、ロードセルを接続してください。

 ■ロードセル - モジュール

 赤線    - E+

 黒線    - Eー

 白線    - A-

 緑線    - A+ 

■モジュール - Arduino

 GND    - GND

 DT     - Digital 8

 SCK     - Digital 9

 VCC     - 5Vf:id:goengine:20190324232432p:plain


このように接続したらArduinoに以下のコードを書き込みましょう。
(サンプルコードは以下の秋月電子のサイトにあったものを参考にしました。)
http://akizukidenshi.com/catalog/g/gK-12370/

#include <Arduino.h>

void AE_HX711_Init(void);
void AE_HX711_Reset(void);
long AE_HX711_Read(void);
long AE_HX711_Averaging(long adc,char num);
float AE_HX711_getGram(char num);

//---------------------------------------------------//
// ピンの設定
//---------------------------------------------------//
#define pin_dout  8
#define pin_slk   9

//---------------------------------------------------//
// ロードセル S字型 SC301A 100kG [P-12036]
//---------------------------------------------------//
//#define OUT_VOL   0.002f      //定格出力 [V]
//#define LOAD      100000.0f   //定格容量 [g]

//---------------------------------------------------//
// ロードセル シングルポイント( ビーム型) SC601 120kG [P-12035]
//---------------------------------------------------//
//#define OUT_VOL   0.001f      //定格出力 [V]
//#define LOAD      120000.0f   //定格容量 [g]

//---------------------------------------------------//
// ロードセル シングルポイント( ビーム型) SC133 20kG [P-12034]
//---------------------------------------------------//
//#define OUT_VOL   0.002f      //定格出力 [V]
//#define LOAD      20000.0f    //定格容量 [g]

//---------------------------------------------------//
// ロードセル シングルポイント(ビーム型) SC616C 500g[P-12532]
//---------------------------------------------------//
//#define OUT_VOL   0.0007f   //定格出力 [V]
//#define LOAD      500.0f    //定格容量 [g]

#define OUT_VOL   0.001f   //定格出力 [V]
#define LOAD      2000.0f    //定格容量 [g]

float offset;

void setup() {
  Serial.begin(9600);
  Serial.println("AE_HX711 test");
  AE_HX711_Init();
  AE_HX711_Reset();
  offset = AE_HX711_getGram(30); 
}

void loop() 
{ 
  float data;
  char S1[20];
  char s[20];
  data = AE_HX711_getGram(5);

//data = 55.0 / 50.0; //ここで校正を行う
sprintf(S1,"%s [g] (0x%4x)",dtostrf((data-offset), 5, 3, s),AE_HX711_Read()); Serial.println(S1); } void AE_HX711_Init(void) { pinMode(pin_slk, OUTPUT); pinMode(pin_dout, INPUT); } void AE_HX711_Reset(void) { digitalWrite(pin_slk,1); delayMicroseconds(100); digitalWrite(pin_slk,0); delayMicroseconds(100); } long AE_HX711_Read(void) { long data=0; while(digitalRead(pin_dout)!=0); delayMicroseconds(10); for(int i=0;i<24;i++) { digitalWrite(pin_slk,1); delayMicroseconds(5); digitalWrite(pin_slk,0); delayMicroseconds(5); data = (data<<1)|(digitalRead(pin_dout)); } //Serial.println(data,HEX); digitalWrite(pin_slk,1); delayMicroseconds(10); digitalWrite(pin_slk,0); delayMicroseconds(10); return data^0x800000; } long AE_HX711_Averaging(long adc,char num) { long sum = 0; for (int i = 0; i < num; i++) sum += AE_HX711_Read(); return sum / num; } float AE_HX711_getGram(char num) { #define HX711_R1 20000.0f #define HX711_R2 8200.0f #define HX711_VBG 1.25f #define HX711_AVDD 4.2987f//(HX711_VBG*((HX711_R1+HX711_R2)/HX711_R2)) #define HX711_ADC1bit HX711_AVDD/16777216 //16777216=(2^24) #define HX711_PGA 128 #define HX711_SCALE (OUT_VOL * HX711_AVDD / LOAD *HX711_PGA) float data; data = AE_HX711_Averaging(AE_HX711_Read(),num)*HX711_ADC1bit; //Serial.println( HX711_AVDD); //Serial.println( HX711_ADC1bit); //Serial.println( HX711_SCALE); //Serial.println( data); data = data / HX711_SCALE; return data; }

こちらのコードでは、上のほうに書かれているところでロードセルの最大可測重量と分解能を設定しています。
今回のロードセルでは定格出力1mV、定格重量2Kgなので以下のように書き加えています。
#define OUT_VOL 0.001f //定格出力 [V]
#define LOAD 2000.0f //定格容量 [g]

あとはArduinoに書き込めばOKです。

シリアルモニタを開いてみるとこんな感じに表示されると思います。

f:id:goengine:20190324235850p:plain
これだけでも簡単には重量計測はできますが、ロードセルの個体差や計測環境などによって多少ずれがありそうです。

なので、スケールを校正しましょう。
重量が分かっているもの(小銭などが便利かと思います。)を使って校正していきます。
なるべく、可測重量内で大きなものがいいかと思います。

校正用に用意した物をロードセルに載せます。
ロードセルで計測した値とその用意した物の本来の値を以下のようにdataにかけ合わせます。
data * 本来の重量 / ロードセルで計測した値

これを
AE_HX711_getGram関数内か
loop関数内に書きましょう。

どちらに描いても機能としては同じですが、
今回はloop関数内に書きます。以下のように書きます。

 

この例では 本来の重量が50gのモノを計測したときに55gと計測された場合の例を示しています。

f:id:goengine:20190324234911p:plain


これでスケーリングも正しくできて正確な値を計測できると思います。

以上です。