AtomS3 で重さを量ってみる
背景
家で使用していたキッチンスケールが壊れたため、新しいものを買いました。その際に、「ロードセル」というもので重さを量ることができること、それをセンサー値として取得するために HX711 というアンプを使用することを知り、壊れたものを捨てずに保管していました。
HX711 はすでに購入していたものの、なかなか作ってみるまでに至らなかったのですが、今回 M5AtomS3 があるので、これを使って重さを量ってみることにしました。
なお、M5AtomS3 で使用できる HX711 用のライブラリとして、bogde/HX711 by bogde がありますので、こちらを活用してみます。
使うもの
- AtomS3
- HX711
- ロードセル
ロードセルは、背景に記載した壊れたキッチンスケールのものを流用します。HX711 は Amazon でも売っていますが、Aliexpress だと 100 円程度で購入することができます。
接続
(参考) 壊れたキッチンスケールの結線
ロードセルからの各線がどの線なのかは、もともとのキッチンスケールの基盤に記載がありました。E+ と E- は電源で、S+ と S- が信号 (Signal) になるようです。
HX711
ロードセルからの線を、HX711 に接続します。先ほどのもともとのキッチンスケールの結線を抜いて、こちらに接続する形です。
HX711 の基盤には、E+, E-, A+, A-, B+, B- の6か所接点があります。E+/- は同じマークがあるのでいいとして、S+/- はどこにつなぐのか、というと、HX711 の A や B は、HX711 は入力が2チャンネルあるので、ロードセルの S+/- は A+/- か B+/- のどちらかにつなげればよいみたいです。しかし、チャンネルによる違いがあるようなので、基本的には A+/- に接続したほうがよさそうです。そのため、以下のような接続にしました。
ロードセル | HX711 | |
---|---|---|
E+ | 赤 | E+ |
E- | 黒 | E- |
S+ | 黄 | A+ |
S- | 白 | A- |
AtomS3
Grove 端子に接続します。AtomS3 の grove 端子にケーブルを接続し、ジャンパワイヤーを (少々無理やり) 差し込みます。
ジャンパワイヤーの反対側は、HX711 に接続します。
接続は以下のようになります。
AtomS3 | Grove | Jumper | HX711 |
---|---|---|---|
GND | 黒 | 黒 | GND |
5V | 赤 | 赤 | VCC |
G2 | 黄 | 緑 | SCK |
G1 | 白 | 青 | DT |
コーディング
PlatformIO IDE の環境 を使い、プロジェクトを新規作成します。まず、ライブラリを追加するため、platformio.ini
の libs
を修正し、「bogde/HX711」を追加します。
lib_deps =
m5stack/M5Unified@^0.1.16
bogde/HX711@^0.7.5
そのうえで、main.cpp
を以下のように作成します。
#include <M5Unified.h>
#include <HX711.h>
const int LOADCELL_DOUT_PIN = 1;
const int LOADCELL_SCK_PIN = 2;
HX711 scale;
// 要キャリブレーション
float k = 815.0;
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.setTextSize(3);
USBSerial.begin(115200);
// HX711の初期化
USBSerial.println("HX711 scale setup");
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(k);
scale.tare();
}
void loop(void) {
M5.update();
if (M5.BtnA.wasPressed()) {
// ボタンを押すと現在値を0gにセット
USBSerial.println("M5.BtnA.wasPressed()");
scale.set_scale(k);
scale.tare();
}
if (scale.wait_ready_timeout(1000)) {
float weight = scale.get_units(5);
M5.Display.setCursor(2, 3);
M5.Display.setTextColor(WHITE, BLACK);
M5.Display.print("Weight\n");
M5.Display.setTextColor(GREEN, BLACK);
M5.Display.printf("%5.1f g ", weight);
//USBSerial.printf("units :\t%5.1fg\n", weight);
}
delay(500);
scale.power_up();
}
計測
ビルドしてアップロードすると、AtomS3 の画面に weight 0.0 g
と表示されるはずです。手元にあったスマートフォンをおいてみると、
しっかりと計量してくれてそうです。
キャリブレーション
コード中の変数 k ですが、この値でロードセルの個体差を調整します。重さがわかっているもの (計量用の錘などでもいいですし、別のはかりで計測して重さを調べたものでもいいと思います) を量って、値に誤差があればその誤差がなくなるように変数 k の値を増減していって、意図した出力になるように調整します。これはロードセルの個体によって変わってくるので、調整が必須だと思います。
そうやって調整した結果が、上記コードの変数 k の値です。
まとめ
AtomS3 のピン配列なども理解していなかったので、意図した結果にならない場合のデバッグが難しかったです。途中、いくらやっても重さを検出してくれなくなったので、どこが間違えているのかいろいろ試したのですが、結果的には基盤と配線のはんだ付けが弱く、線が抜けかかっていたなんてこともありました。
結果的にはある程度正確な値を計測できるようになったので、あとは扱いやすいように電源を工夫する (乾電池で使えるようにするとか) とか、重さを量って何かのアクションにつなげるとかもやってみたいと思っています。