LoginSignup
5

More than 3 years have passed since last update.

ロードセルで重量測定、Soracom harvestに送る

Last updated at Posted at 2019-05-03

ロードセルで重量測定、Soracom harvestに送る

  • アマゾンで買ったロードセル(歪みセンサ、重量センサ)のデータをSoracom Harvestに送って、鉢植えの重量を監視してみました。

用意するもの

配線

WIO と AD module の接続

Wio 3GのD38ポートとAD moduleを以下のように接続して下さい。

WIO 3G D38 port AD module
GND GND
3V3 VCC
D39 DT
D38 SCK

29B26381-0485-43B4-AB9C-E782F21397CB.jpg

AD module と ロードセル の接続

AD moduleとロードセルから出ているリード線を以下のように接続して下さい。

AD module Lord cell
E+ Red
E- Black
A- Green
A+ White

33564FA2-0424-46B5-9000-254F14B01C9C.jpg

ハードの組み立て

  • 適当な板(硬めのアクリル板など)を用意します。
  • 下の板に3本の足を取り付けます。また、ロードセルの片側をM4ネジで取り付けます。この時、ロードセルの白いシリコンが板に触れないように厚めのワッシャーを噛ませます。
  • 上の板をのせ、M4ネジでロードセルを固定、同じようにワッシャーを噛ませます。
  • 実験ではアクリル3mm厚を使用しましたが、たわんでしまうので、重いものを量る時はもっと頑丈な板の方が良いと思います。
  • 載せる対象物の重心は上板のM4ネジ付近が好ましいですが、わざと隅に重りを置いても余り誤差は出ませんでした。

1A41C3BE-3E8A-4969-A20F-6E3EBED5B86F.jpg
4DF6E226-4D61-40E4-89F1-6E4E0BF8B530.jpg

プログラム

以下の資料を参考にさせていただきました。
- 秋月電子さんのページ

#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 修正] 一晩動かしたら色々と問題が確認されました。
screenshot.png

  • 水分が蒸散している様子が見られるようです。 ロードセルの温度特性が悪い様です。
  • 振動もよく拾っています。(アクリル板の剛性が弱いため?) 原因不明ですが、(ほぼ)定期的なノイズが発生しています。
  • ロードセルを大きな定格に変えれば、もっと重い物を量ることも可能だと思います。 測定したい重量に合わせた定格を選択しないと温度特性含め、誤差が大きいです。また、精度を求めるならば、それなりに信頼性のある(高価な)ロードセル、アンプを使用する必要があるかもしれません。

B76EBFC0-891E-468C-BB7E-2E87C1712EBC.jpg
screenshot.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5