TDSセンサーとArduino UNO Wifi Rev2で水耕栽培液肥の濃度計測

栽培ガジェット

TDS(総溶解固形分)センサーを使って液肥の濃度を計測したいと思い、DFRobotのTDSセンサーを買ってみました。

当初ESP32で計測するつもりでしたが、どうしてもうまく計測できなかったのでArduino UNOを使って計測してみました。

まずはTDSとはどういったものか?ちょっと調べてみました。

TDSとは?

TDSはTotal Dissolved Solid=総溶解固形分でカルシウム、マグネシウム、カリウム、ナトリウムなど、水に溶けている物質の総量を濃度で表した数値。

ECとTDSは以下のように計算できるようです。

  • EC(mS/cm) X 1000 / 2  = TDS(ppm)
  • TDS(ppm) x 2 / 1000 = EC(mS/cm)

水道水や水耕栽培に適したTDS値など調べてまとめてみました。

PH EC(電気伝導度)
1mS/cm=1000μS/cm
TDS(総溶解固形分)
PPM
純水 5.4-5.7 1μS/cm 0.5ppm
水道水 6.8-8.1 100~200μS/cm 40ppm
水耕栽培 5.5-7.0 基準2.4mS/cm 1250ppm
レタス 5.5-6.5 0.8-1.2 560-840ppm
キャベツ 6.5-7.0 2.5-3.0 1750-2100ppm
ブロッコリ 6.0-6.5 2.8-3.5 1960-2450ppm

TDS以外のPHやECは次回、センサーを使ってEC値を取得してサーバーにデータをアップするところまでテストしてみます。

以下のページを参考に表にしてみました。

ECメーターを利用したホームハイポニカの肥料の追加方法
ハイポニカ肥料はECメーターを利用しない場合、500倍に薄めてご利用いただいております。ですがこの500倍、設定としては実は薄い濃度で、この500倍の追加を続けるうちに徐々に濃くなっていきます。※詳しくは以下の記事をご参照ください。「肥料濃度の調整・肥料の追加方法」ですができるだけ正確な栽培をご希望の場合、ECメータを...
ph/ TDS/PPM Levels for Vegetables

ハイポニカでは500倍に薄めた濃度なので、TDSは500ppm前後になっていて、上の表よりもちょっと薄い濃度ですが季節や温度・植物によって吸収する養分が違うので薄めでも良いそうです。ただ、大体的に厳密に育てるにはTDS・EC値を測って液肥の濃度を変えていく必要がありそうですが、

今のところテスト的に育てているだけなのでセンサーで計測できていれば気にしないことにして、ハイポニカは500倍に薄めて育てています。

TDSについてちょっとだけ分かったところで実際にTDSを計測して、データをサーバにアップするテストをしていきます。

TDSセンサー + Arduino UNO WIFI Rev2でデータ取得成功

いろいろとテストした結果、Arduino UNO WIFI Rev2を使ってうまくTDS計測ができました。以下のページにArduino UNO WIFI Rev2でWifi接続、サーバーのInfluxDBにTDSデータ送信するまでは以下で書いてますので参考にしてくださると嬉しいです。

DFRobotのセンサーを使うためにArduino UNO Wifi Rev2を使ってみる
DFRobotのセンサーなどを使う場合は主にArduino UNOを使っていて、スケッチもArduino UNO用のスケッチなのでESP32やESP8266だとうまく動かない(試した限りでは動かなかった)。動くかもしれませんが、自分は詳しく

今回はその前段階として、Wifiが無いArduino UNOとESP32でTDSセンサーでうまく計測できるか実験している様子をメモ的に書いておきます。

成功したArduino IDE スケッチ

以下のようにしてラズパイのサーバーのInfluxDBにデータをアップできました。

現在は温度を計測してないので、後ほど温度計も導入してより正確にTDS値を取得できるようにしていきます。

#include <SPI.h>
//Wifi接続
#include <WiFiNINA.h>
#include "arduino_secrets.h"
char ssid[] = "Xiaomi_wifi";//Wifi SSIDを変更する
char pass[] = "xxxxxxxx";   //Wifiパスワード

//サーバにアクセスPOST送信
#include <ArduinoHttpClient.h>

//InfluxDB
#define PLACE "reef-TDS"
#define MEASUREMENT "air5"
#define HOST "UNO-Wifi-Rev2"
String influxUrl = "/write?db=sensor";
String influxUser = "root";
String influxPassword = "xxxxxxxx";

const char serverName[] = "192.168.31.53";
int port = 8086;
WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverName, port);
int status = WL_IDLE_STATUS;

//サーバー ラズパイに接続
void postToInfluxDB(int tdsValue) {
  String influxData  = MEASUREMENT;
  influxData += ",place=" PLACE ",host=" HOST;
  influxData += " tds=";
  influxData += tdsValue;
   
  String contentType = "application/x-www-form-urlencoded";
  client.beginRequest();
  client.sendBasicAuth(influxUser, influxPassword);//Basic認証
  client.post(influxUrl, contentType, influxData);
  
  int statusCode = client.responseStatusCode();
  Serial.print("Status code: ");
  Serial.println(statusCode);
  String response = client.responseBody();
  Serial.print("Response: ");
  Serial.println(response);
}

//TDS計測
#include <EEPROM.h>
#include "GravityTDS.h"
#define TdsSensorPin A1
GravityTDS gravityTds;
//温度 本当は温度も計測するとなお正確にTDS値が取得できる。
float temperature = 25,tdsValue = 0;

void setup() {
  Serial.begin(115200);
  while (status != WL_CONNECTED) {
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }
  
  //TDS計測
  gravityTds.setPin(TdsSensorPin);
  gravityTds.setAref(5);
  gravityTds.setAdcRange(1024);
  gravityTds.begin();
}

void loop() {
  //temperature = readTemperature();  
  gravityTds.setTemperature(temperature);
  gravityTds.update();
  tdsValue = gravityTds.getTdsValue();
  Serial.print(tdsValue,0);
  Serial.println("ppm");
  
  if (WiFi.status() == WL_CONNECTED) {
    delay(600000);//10分おきにInfluxDBにアップする
    postToInfluxDB(tdsValue);
  }
  delay(1000);
}

サーバー(ラズパイ)のInfluxDBにアップしてGrafanaでグラフ表示したところ↓徐々にPPMが上がってきた?ようです。小さなコップに液肥を入れて実験しているからかもしれません。

TDS

Arduino UNO

Arduino UNOは互換機を買いました。コレでも普通にArduino UNOとして使えるようです。

それと、以下のUNOにESP8266が合体してWifiも使えるというのも買ってみましたがArduino IDEでボードでたしか「Generic ESP8266 Module」を選ばなければいけなかったのでこちらではTDSセンサーは使えない。

Geekcreit®UNO + WiFi R3 ATmega328P+ESP8266

Geekcreit®UNO + WiFi R3 ATmega328P+ESP8266

Arduino UNO Wifi Rev2

UNOは全部で3台になった。

ESP32

できればESP32でTDSセンサーを使いたかったのですがうまく計測できず断念。

TDSメーターを用意する

こちらでTDSセンサーをキャリブレーションするときに同じ値にするために使う。激安であまり信用はできないメーターですが、無いよりはましそうなので使ってみます。(実際に使ってみたら全く問題ありませんでした。)

DFRobot Gravity Analog TDS Sensor Meter For Arduinoを用意

Mouserで購入

TDSセンサーは1464円ほどで非常に安かったです。6000円分買うと送料無料になるのも素晴らしいところ。

https://www.mouser.jp/ProductDetail/dfrobot/sen0244/?qs=W0yvOO0ixfHyUmHuEPwC1w==&countrycode=US¤cycode=USD

DFRobot Gravity Analog TDS Sensorの使い方ページ

使い方やArduino IDEのスケッチもこちらにありました。

Analog TDS Sensor Meter for Arduino / ESP32 / Raspberry Pi - DFRobot Wiki
This wiki explains what is TDS and how Analog TDS Sensor Meter works with Arduino, ESP32 and Raspberry Pi.

ブログで地下水のような水の水質調査していました。↓

DFRobot TDS Sensor first look - DFRobot
A few people at Public Lab have expressed interest in the DFRobot TDS sensor for Arduino data loggers. This sensor measures the electrical conductivity of water...

Arduino UNOでは以下のように配線すればよさそうです。UNOだと迷うことは無いのですが、ESP32ではどうすればいいのか不明。

出展:DFRobot

やはりArduino UNOを使ったほうが無難かもしれません。

Arduino UNO でTDSセンサー動作テスト

まずはノーマルなArduino UNO Rev3でTDSセンサーでちゃんと計測できるかやってみます。

Arduino IDEでボードを「Arduino/Genuino Uno」を選びました。

TDS

PIN

上の図のようにデータをA1にしました。

TDS Arduino UNO
+ VIN
GND
A A1

サンプルスケッチは2通りあって、ライブラリあり・なしのスケッチがありますので、それぞれ試してみます。

ライブラリありのスケッチ

ライブラリはDFRobot Gravity Analog TDS Sensor Meter For Arduino)このページ(DFRobot Gravity Analog TDS Sensor Meter For Arduino)の以下のリンクにあります。

TDS

ダウンロードできたら以下のようにスケッチ > ライブラリをインクルード > ZIP形式のライブラリをインストールを選択してダウンロードした GravityTDS-master.zipを選択する。

TDS

キャリブレーションする

まずはこちらのサンプルコードをArduino UNOに書き込む。

#include <EEPROM.h>
#include "GravityTDS.h"

#define TdsSensorPin A1
GravityTDS gravityTds;

float temperature = 25,tdsValue = 0;

void setup()
{
    Serial.begin(115200);
    gravityTds.setPin(TdsSensorPin);
    gravityTds.setAref(5.0);  //reference voltage on ADC, default 5.0V on Arduino UNO
    gravityTds.setAdcRange(1024);  //1024 for 10bit ADC;4096 for 12bit ADC
    gravityTds.begin();  //initialization
}

void loop()
{
    //temperature = readTemperature();  //add your temperature sensor and read it
    gravityTds.setTemperature(temperature);  // set the temperature and execute temperature compensation
    gravityTds.update();  //sample and calculate
    tdsValue = gravityTds.getTdsValue();  // then get the value
    Serial.print(tdsValue,0);
    Serial.println("ppm");
    delay(1000);
}

シリアルモニタで「enter」を押してキャリブレーションモードに、↓

TDS

液肥が入った水につけて「cal:474」で調整

TDS

そうすると、水道水で45くらいなのに90くらいになる・・・?うまくいかない?

Arduino UNO WIFI Rev2でもう一度キャリブレーションして試したところ、正確な数値が出たのでコチラのライブラリありのスケッチを使っています。

ライブラリ無しのスケッチ

ライブラリ使わないのだと液肥432、水道水43くらいで近い値になる。

TDS Value:432ppm
TDS Value:432ppm
TDS Value:432ppm
TDS Value:430ppm
TDS Value:428ppm
TDS Value:104ppm
TDS Value:23ppm
TDS Value:0ppm
TDS Value:0ppm
TDS Value:0ppm
TDS Value:2ppm
TDS Value:76ppm
TDS Value:76ppm
TDS Value:76ppm
TDS Value:76ppm
TDS Value:659ppm
TDS Value:1147ppm ←コップの金属の部分に触れた時
TDS Value:1147ppm
TDS Value:1147ppm
TDS Value:1147ppm
TDS Value:1147ppm
TDS Value:1147ppm

TDS Value:43ppm
TDS Value:41ppm

以下、ESP32でテストしたところうまくTDSデータを取得できませんでした。

失敗メモとして書いておきますので必要なければ読み飛ばしてくださいね。

ESP32(ESP-WROOM-32)でテスト

Arduino UNOでうまくいったので、本番環境で使いたいESP32で試してみる。

ボードをESP32 Dev Moduleを選ぶ。

ESP32

ESP32はスケッチを書き込む時にBOOTボタンを押す。

PIN

データはGPIO13ピンにする。

TDS ESP32
+ VIN
GND
A GPIO13

ライブラリ使わないスケッチ

Anarog PinをGPIO13に変更(左下から3番目D13のPIN)

#define TdsSensorPin 13

液肥につけると12293と高い値が出る。水道水だと0になる。

TDS Value:12293ppm
TDS Value:12293ppm
TDS Value:12382ppm

以下の行を1024→4096に変更

      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 4096.0;

これで、上のほうにある行を5Vから3.3V↓にしても変わらずうまくいかない・・・

#define VREF 3.3

ライブラリありのスケッチ

同様にPINをGPIO13にする。ライブラリもA1→13に直さないといけない。以下のライブラリのあるパスのGravityTDS.cppファイルを編集する。

C:\Users\User名\Documents\Arduino\libraries\GravityTDS-master\GravityTDS.cpp

以下の行を13に変更

this->pin = 13;

キャリブレーションする。

TDS

Calで値を送信しても受け付けてくれず・・・ESP32をリセットしてもダメだった。ううん

以下の行を5→3.3に、1024→4096にして再度試すとキャリブレーションで「cal:474」を送信したら成功したが、水道水だとまだ0ppmのまま・・・

    gravityTds.setAref(3.3);  //reference voltage on ADC, default 5.0V on Arduino UNO
    gravityTds.setAdcRange(4096);  //1024 for 10bit ADC;4096 for 12bit ADC

ESP32のADCは12BITらしい。なので4096にする。4094で3.3V・5Vにしてもダメだった。

ということで、残念ながら現状ではESP32でTDSセンサーを使えませんでした。

Arduino UNO Wifi Rev2で試してみる

Arduino UNOでWifi接続してデータ送信

WifiがついたArduino UNOを買って、計測したTDSデータをWifiで送信できるようにしました。

Arduino UNO Wifi Rev2でWifiやデータをInfluxDBに投げるまでは書いてありますので省略します。

DFRobotのセンサーを使うためにArduino UNO Wifi Rev2を使ってみる
DFRobotのセンサーなどを使う場合は主にArduino UNOを使っていて、スケッチもArduino UNO用のスケッチなのでESP32やESP8266だとうまく動かない(試した限りでは動かなかった)。動くかもしれませんが、自分は詳しく

ライブラリありのスケッチで再度テスト

  • 水道水:TDSテスター・TDSセンサーともに38ppmで同じ。
  • 液肥:TDSテスターでの計測は577ppmの時にTDSセンサーだと538ppm。少し誤差はありますが許容範囲といったところでしょうか?

温度も一緒に計測すればより値が正確になりそうです。

以上、最終的にTDSセンサーとArduino UNO WIFI Rev2でデータ取得成功しました。

コメント

タイトルとURLをコピーしました