로드셀에서 무게 측정, Soracom harvest로 보내기

8085 단어 SORACOMSoracomHarvest

로드셀에서 무게 측정, Soracom harvest로 보내기


  • 아마존에서 구입한 로드셀(왜곡 센서, 중량 센서)의 데이터를 Soracom Harvest에 보내 화분의 중량을 감시해 보았습니다.

  • 준비하는 것


  • 로드셀
  • AD 모듈
  • Wio 3G SORACOM Edition
  • 튼튼한 판 두 장
  • 나사와 와셔
  • 뭔가 다리가 되는 것.
  • 브레드 보드 등

  • 배선



    WIO와 AD module 연결



    Wio 3G의 D38 포트와 AD 모듈을 다음과 같이 연결하십시오.


    WIO 3G D38 포트
    AD module


    GND
    GND

    3V3
    VCC

    D39
    DT

    D38
    SCK




    AD 모듈과 로드셀 연결



    AD module과 로드셀에서 나오는 리드선을 다음과 같이 연결하십시오.


    AD module
    Lord cell


    E+
    레드

    E-
    블랙

    A-
    그린

    A+
    화이트




    하드 조립


  • 적당한 판(딱딱한 아크릴판 등)을 준비합니다.
  • 아래 판에 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 수정] 하룻밤 움직이면 여러가지 문제가 확인되었습니다.


  • 수분이 증산하는 모습을 볼 수 있는 것 같습니다. 로드셀의 온도 특성이 나쁜 것 같습니다.

  • 진동도 잘 줍고 있습니다. (아크릴판의 강성이 약하기 때문에?) 원인 불명입니다만, (거의) 정기적인 노이즈가 발생하고 있습니다.

  • 로드셀을 큰 정격으로 바꾸면 더 무거운 물건을 다는 것도 가능하다고 생각합니다. 측정하고 싶은 중량에 맞춘 정격을 선택하지 않으면 온도 특성을 포함하여 오차가 크다. 또한 정밀도를 추구한다면 나름대로 신뢰할 수 있는 (비싼) 로드셀, 앰프를 사용할 필요가 있을지도 모릅니다.


  • 좋은 웹페이지 즐겨찾기