🌾
SDI-12センサの安価な測定システムの作り方 #2(測定データ保存編)
この記事のゴール
- マイコン(M5Stack ATOM)を用いたSDI-12センサデータのSDカードへの保存
- 保存形式はCSV
前提
- この記事をご覧になるのは研究者の方を想定していますので,コードに関しては比較的丁寧に記載いたします
- この記事はSDI-12センサの内,Acclima社製のTDTセンサを使用する例を記載しています
- この記事は筆者のHPから移植している部分が多いため,最新でない情報も含まれています
- Mac環境の例を記載していますので,Windowsの方は必要に応じて読み替えをお願いします
- 前回の記事を先にご覧になることを推奨します
必要な知識・もの
- Arduino言語の基本的な知識
- PC
必要な物品リスト
- SDI-12センサ(TDTセンサ) × 1
- ブレッドボード × 1
- 端子台(3極) × 1
- ジャンパワイヤ × 10本程度
- ATOM Lite × 1 (* その他のM5Stack系のマイコンでも動作可能ですが,適宜配線を変更する必要があります)
- USB type-c ケーブル × 1
以下前回からの追加
-
microSDカードスロットDIP化キット × 1
- 秋月電子等で購入できます
- microSDカード × 1
- 容量は 32GB 以下をおすすめします(動作確認できていないため)
ライブラリのインストール
- 今回は前回に加えて
SD.h
とSPI.h
のライブラリを使用します- おそらくデフォルトでインストールされていると思います
配線
- ATOM LiteとSDI-12センサ,SDカードスロットを接続します
-
配線は下記の通りです(SDカード側のピンの呼称については
microSDカードスロットDIP化キット
のデータシートを参照ください)SDI-12センサ ATOM GND GND PWR 5V DATA 33 SD ATOM VDD 3.3V VSS GND DAT0 21 CMD 25 CLK 19 CD/DAT3 23
-
センサデータ保存の流れ
-
5秒間隔で測定・保存するシンプルなデータ取得の流れは下記の通りです
- センサに測定コマンドを送信(*1)
- 測定にかかる時間を取得(*2)
- 測定にかかる時間分待機(*3)
- センサに測定結果取得コマンドを送信(*4)
- 測定結果を表示(*5)
- 測定結果文字列の
+
を,
に置換し,末尾に改行コードを追加(*6) - SDカードにデータを保存(*7)
- 測定間隔分待機(*8)
-
上記に加えて下記の設定・処理を行っています
- 測定データを書き込むファイルを指定(*A)
- SDカードを読み取れない場合,エラーを出力し,処理を停止(*B)
- 処理が停止されるので,配線等を再度確認してください
- 書き込み対象のファイルが存在しない場合,ファイルを作成する(*C)
#include <SDI12.h> #include "SD.h" #include "SPI.h" #define DATA_PIN 33 #define SD_PIN 23 #define SD_MISO_PIN 21 #define SD_MOSI_PIN 25 #define SD_CLK 19 SDI12 mySDI12(DATA_PIN); String responseArray[10]; const String sensorAddress = "1"; String measureCommand = sensorAddress + "M!"; String resultCommand = sensorAddress + "D0!"; // *A const char *path = "/result.csv"; void setup() { Serial.begin(115200); mySDI12.begin(); // *B if (!SD.begin(SD_PIN)) { Serial.println("SDカードのが読み取れません"); while (1) { } } // *C File file = SD.open(path); if (!file) { SD.open(path, FILE_APPEND); } file.close(); } 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 String record = replace(result) + "\n"; // 改行コードを追加 // *7 writeFile(path, record); // *8 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; } /** * @brief SDカードに書き込む * * @param path ファイルパス * @param message 書き込む内容 */ void writeFile(const char *path, String message) { File file = SD.open(path, FILE_WRITE); if (!file) { return; } file.print(message); file.close(); } /** * @brief +区切りの文字列をカンマ区切りに置換 * * @param data +区切りの文字列 * @return String 置換後の文字列 */ String replace(String data) { int index = 0; int arraySize = (sizeof(data) / sizeof((data)[0])); int dataLength = data.length(); String resultString = ""; for (int i = 0; i < dataLength; i++) { char dataChar = data.charAt(i); if (dataChar == '+') { resultString += ","; index++; } else { resultString += dataChar; index++; } } return resultString; }
おわりに
- 上記のコードで5秒毎に測定されたデータをSDカードに保存することができます
- 今回はSDカードに測定データを保存するまでをご紹介しました
- 次回は測定データをインターネットを通じて任意の場所に保存する方法の前段として,マイコンをインターネットに接続する方法について紹介したいと思います
Discussion