🌾

SDI-12センサの安価な測定システムの作り方 #1(マイコン準備編)

2024/03/17に公開

この記事のゴール

  • マイコン(M5Stack ATOM)を用いた安価でシンプルな測定環境の構築

前提

  • この記事をご覧になるのは研究者の方を想定していますので,コードに関しては比較的丁寧に記載いたします
  • この記事はSDI-12センサの内,Acclima社製のTDTセンサを使用する例を記載しています
  • この記事は筆者のHPから移植している部分が多いため,最新でない情報も含まれています
  • Mac環境の例を記載していますので,Windowsの方は必要に応じて読み替えをお願いします

現状のSDI-12の課題感(個人的感想)

  • SDI-12を用いているセンサが基本的に数万程度と比較的高価
  • 上記に加えて,日本語の事例や文献が少ない
    • 実際に筆者のHPにも何度かお問い合わせがありました
  • 安価なデータロガーを使用した例が少ない

必要な知識・もの

  • Arduino言語の基本的な知識
  • PC
必要な物品リスト
  • SDI-12センサ(TDTセンサ) × 1
  • ブレッドボード × 1
  • 端子台(3極) × 1
  • ジャンパワイヤ × 3
  • ATOM Lite × 1 (* その他のM5Stack系のマイコンでも動作可能ですが,適宜配線を変更する必要があります)
  • USB type-c ケーブル × 1

Arduino IDE のセットアップ

ライブラリのインストール

  • Arduino IDE を開き, ツールタブ -> ライブラリを管理 からライブラリマネージャーを開き,SDI-12 と検索し,同名のライブラリをインストール

配線

  • ATOM LiteとSDI-12センサを接続します
    • センサの配線がATOM本体にそのまま刺さるケースは稀かと思いますので,適宜端子台やブレッドボードを使用してATOMに接続してください

    • 配線は下記の通りです

      SDI-12センサ ATOM
      GND GND
      PWR 5V
      DATA 33

SDI-12センサのコマンド

  • SDI-12センサは特定のコマンドに応答するようになっています
    • センサが異なっていても,基本的に同様のコマンドで同様の結果を得ることができます
  • コマンドには下記のようなものがあります
    • <センサアドレス>M!
      • 例)1M!
      • 測定コマンド
      • レスポンスは下記のような構成になっています
        • <センサアドレス>AAAXX
          • ここで,Aは測定にかかる秒数(3桁),Xは測定データ数(2桁)を指しています
    • <センサアドレス>D0!
      • 例)1D0!
      • 測定結果取得コマンド
      • レスポンスは下記のような構成になっています
        • <1つ目の測定結果>+<2つ目の測定結果>+<3つ目の測定結果>+...

センサデータ取得の流れ

  • 5秒間隔で測定するシンプルなデータ取得の流れは下記の通りです

    1. センサに測定コマンドを送信(*1)
    2. 測定にかかる時間を取得(*2)
    3. 測定にかかる時間分待機(*3)
    4. センサに測定結果取得コマンドを送信(*4)
    5. 測定結果を表示(*5)
    6. 測定間隔分待機(*6)
    #include <SDI12.h>
    #define DATA_PIN 33
    
    SDI12 mySDI12(DATA_PIN);
    
    const String sensorAddress = "1";
    String measureCommand = sensorAddress + "M!";
    String resultCommand = sensorAddress + "D0!";
    
    void setup()
    {
      Serial.begin(115200);
      mySDI12.begin();
    }
    
    void loop()
    {
      // *1
      const String response = sendCommandCollectResponse(measureCommand); // 例)100104
    
      // *2
      int waitTime = response.substring(3, 4).toInt() * 1000;
    
      // *3
      delay(waitTime);
    
      // *4
      const String result = sendCommandCollectResponse(resultCommand); // 例)1+20.27+15.2+10.67+0.41
    
      // *5
      Serial.println(result);
    
      // *6
      delay(5000);
    }
    
    /**
     * @brief コマンド送信とレスポンスの取得
     *
     * @param command コマンド文字列
     * @return String レスポンス
     */
    String sendCommandCollectResponse(String command)
    {
      String response = "";
    
      mySDI12.sendCommand(command);
    
      while (mySDI12.available())
      {
        char responseChar = mySDI12.read();
        if ((responseChar != '\n') && (responseChar != '\r'))
        {
          response += responseChar;
          delay(10);
        }
      }
      mySDI12.clearBuffer();
    
      return response;
    }
    

おわりに

  • 上記のコードから基本的な測定を行うことができます
  • 今回は基本的な測定環境を整備するまでを記載しております
    • 次回は測定データの保存方法について紹介したいと思います

Discussion