ロードセルで重量測定、Soracom harvestに送る
- アマゾンで買ったロードセル(歪みセンサ、重量センサ)のデータをSoracom Harvestに送って、鉢植えの重量を監視してみました。
用意するもの
- ロードセル
- ADモジュール
- Wio 3G SORACOM Edition
- 丈夫な板 二枚
- ネジとワッシャー
- 何か足になるもの。
- ブレッドボードなど
配線
WIO と AD module の接続
Wio 3GのD38ポートとAD moduleを以下のように接続して下さい。
WIO 3G D38 port | AD module |
---|---|
GND | GND |
3V3 | VCC |
D39 | DT |
D38 | SCK |
AD module と ロードセル の接続
AD moduleとロードセルから出ているリード線を以下のように接続して下さい。
AD module | Lord cell |
---|---|
E+ | Red |
E- | Black |
A- | Green |
A+ | White |
ハードの組み立て
- 適当な板(硬めのアクリル板など)を用意します。
- 下の板に3本の足を取り付けます。また、ロードセルの片側をM4ネジで取り付けます。この時、ロードセルの白いシリコンが板に触れないように厚めのワッシャーを噛ませます。
- 上の板をのせ、M4ネジでロードセルを固定、同じようにワッシャーを噛ませます。
- 実験ではアクリル3mm厚を使用しましたが、たわんでしまうので、重いものを量る時はもっと頑丈な板の方が良いと思います。
- 載せる対象物の重心は上板のM4ネジ付近が好ましいですが、わざと隅に重りを置いても余り誤差は出ませんでした。
プログラム
以下の資料を参考にさせていただきました。
#include <WioCellLibforArduino.h>
#define INTERVAL (60000) // 1分に一回送信します。
#define RECEIVE_TIMEOUT (10000) // 受信タイムアウト
#define DAT WIO_D39 // WIO 3GのD39ポート
#define CLK WIO_D38 // WIO 3GのD38ポート
float offset=0;
WioCellular Wio;
void setup() {
delay(200);
SerialUSB.begin(9600); // PCデバッグ用
SerialUSB.println("start");
pinMode(CLK, OUTPUT); // D38を出力に設定
pinMode(DAT, INPUT); // D39を入力に設定
offset = Read();
SerialUSB.println("### I/O Initialize.");
Wio.Init(); // Wioの初期化
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyCellular(true);
delay(500);
SerialUSB.println("### Turn on or reset.");
#ifdef ARDUINO_WIO_LTE_M1NB1_BG96
Wio.SetAccessTechnology(WioCellular::ACCESS_TECHNOLOGY_LTE_M1);
Wio.SetSelectNetwork(WioCellular::SELECT_NETWORK_MODE_MANUAL_IMSI);
#endif
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to \"soracom.io\".");
if (!Wio.Activate("soracom.io", "sora", "sora")) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Setup completed.");
}
void loop() {
float data; // ロードセルデータ
char data_txt[100]; // soracom送受信用バッファ
char str_temp[10]; // 文字列作成のためのワークエリア
data = Read(); // ロードセルデータ取得
SerialUSB.print(-data,2);SerialUSB.println("g"); // For debug
dtostrf(-data, 4, 2, str_temp); // データを文字列に変換して、
sprintf(data_txt, "{\"weight\":%s}", str_temp); // Soracom送信用文字列(json)に整形して、
SerialUSB.println(data_txt); // For debug
SerialUSB.println("### Open.");
int connectId;
connectId = Wio.SocketOpen("harvest.soracom.io", 8514, WIO_UDP); // Harvestに接続
if (connectId < 0) {
SerialUSB.println("### ERROR! ###");
goto err;
}
SerialUSB.println("### Send.");
SerialUSB.print("Send:");
SerialUSB.print(data_txt);
SerialUSB.println("");
if (!Wio.SocketSend(connectId, data_txt)) { // 送信
SerialUSB.println("### ERROR! ###");
goto err_close;
}
SerialUSB.println("### Receive.");
int length;
length = Wio.SocketReceive(connectId, data_txt, sizeof (data_txt), RECEIVE_TIMEOUT); // 受信
if (length < 0) {
SerialUSB.println("### ERROR! ###");
goto err_close;
}
if (length == 0) {
SerialUSB.println("### RECEIVE TIMEOUT! ###");
goto err_close;
}
SerialUSB.print("Receive:");
SerialUSB.print(data_txt);
SerialUSB.println("");
err_close:
SerialUSB.println("### Close.");
if (!Wio.SocketClose(connectId)) {
SerialUSB.println("### ERROR! ###");
goto err;
}
err:
delay(INTERVAL);
}
float Read(void){
long sum = 0;
for (int i = 0; i < 30; i++) {
long data=0;
while(digitalRead(DAT)!=0);
for(char i=0;i<24;i++) {
digitalWrite(CLK,1);
delayMicroseconds(1);
digitalWrite(CLK,0);
delayMicroseconds(1);
data = (data<<1)|(digitalRead(DAT));
}
digitalWrite(CLK,1); //gain=128
delayMicroseconds(1);
digitalWrite(CLK,0);
delayMicroseconds(1);
data = data^0x800000;
sum += data;
}
float data = sum /30;
float volt;float gram;
volt =data*(4.2987/16777216.0/128); // スミマセン。定数4.2987の意味はよくわかりません。
gram=volt/(0.001*4.2987/5000.0); // 5000=Load cellの定格5kg
return gram-offset;
}
結果
[2019/5/4 修正] 一晩動かしたら色々と問題が確認されました。
-
水分が蒸散している様子が見られるようです。ロードセルの温度特性が悪い様です。 -
振動もよく拾っています。(アクリル板の剛性が弱いため?)原因不明ですが、(ほぼ)定期的なノイズが発生しています。 -
ロードセルを大きな定格に変えれば、もっと重い物を量ることも可能だと思います。測定したい重量に合わせた定格を選択しないと温度特性含め、誤差が大きいです。また、精度を求めるならば、それなりに信頼性のある(高価な)ロードセル、アンプを使用する必要があるかもしれません。