去年からアクアリウムというか水草水槽を15年ぶりぐらいに再開して、日々水槽に向かい合ったり調子の上がらない草に文句を言ったりしています。
水草水槽においては光合成のために CO2 を添加するのが一般的ですが、その添加量については諸説あるというか、水草関連機器の大手である ADA も結構適当な感じで説明していたりとよくわかりません。
一方で主に液体肥料などを販売している THE 2HR AQUARIST というシンガポールのメーカーでは科学的根拠に基づいた CO2 添加量についての記事を公開しており、この情報に従って私の水槽は CO2 添加を行っています。
How to measure CO2 levels in an aquarium - THE 2HR AQUARIST
ざっくり説明すると CO2 が入っていない飼育水の pH を測って、そこから -1 の pH になるまで CO2 を添加したらちょうどいい量になるよということです。
自動でやりたい
この方法を実施するには、CO2 添加前の pH の測定と添加後の pH の測定を日々行う必要がありますが、pH の値をメモしたりと色々面倒くさいです。
実際には一度添加量を設定すればそこまでズレることもないのですが、水槽の水は放置していると CO2 以外の色々な酸性物質が蓄積され pH が下がります。逆に水を換えたら水道水の水質によって pH が上がることもありますし、下がることもあります。
そこで、添加前の pH の測定と添加中の pH の監視を行い、CO2 の添加を制御する電磁弁を自動的にオンオフする装置があるといいなと思いました。

設定した pH に応じて電磁弁を制御する製品は他にもありますが、目標の自動設定を行えるものは存在しないため、自作するメリットがあります。
まず pH を測定してみる
pH を測定できないことには始まらないので、マイコンで pH を測定できるようにしてみます。

マイコンはいつも使っていて慣れているという理由で ESP32 を使っています。
とりあえず中華の pH 電極とアンプ基板をアリエクで買ってきたのと、ESP32 の ADC があまりにも微妙なので M5 から出ている ADC モジュールを使って pH を測定してみました。
結果としては水温と同じカーブで pH が揺れてしまい使い物になりませんでした。pH 電極の温度補償についてはネルンストの式というもので計算できますが、その通りに計算しても補正できなかったのでアンプ基板も温度で何か起こっているのか、とにかく全然ダメでした。
pH 電極が中華品なのが悪いのかと思い、堀場の電極に変えたりと色々試しましたがダメでした。今考えると アンプ基板の電源を ESP32 に繋がっている VBUS 5Vから取っていたり、その辺りもよくなかったのかもしれないです。
(d1がpH、d4が水温)
より高精度な pH 測定回路を作る
中華基板の組み合わせではうまくいかないということが分かり色々調べていたところ、アナログデバイセズから pH 測定回路の評価基板が出ていることが分かりました。
CN0326 温度補償機能付き絶縁型低消費電力 pH モニタ
この回路を使って pH 電極の電圧を読み取り、ESP32 に入力することで pH を測定することにしました。
基板を買うと結構な値段だったので、この回路を真似して測定基板を作りました。

この基板から I2C で ESP32 にデータを送り、それを使って処理してみたところ、謎の pH の揺れなどはなくなり、水温を変動させても安定した pH を測定できるようになりました。(d1がpH、d4が水温)

この回路では AD7793 という 3ch ADC を使用し、ph 電極のアナログ電圧と、測温抵抗体の抵抗値を測定しています。ですが日本で入手性のいい堀場の pH 電極は測温抵抗体ではなくスペック不明のサーミスタが使われており、この回路では pH 電極に入っているサーミスタで水温を測定するのが難しいです。
そのため今回は 1-Wire の温度センサーである DS18B20 を使って水温を測定しています。折角の複合電極なのに温度センサーを追加しないといけないのは残念ですが、仕方ありません。

水中の CO2 濃度の推定

画面表示の賑やかしに CO2 濃度を推定して表示する機能をつけました。
pH と kH(炭酸塩硬度)から水に溶け込んだ CO2 濃度を計算する式や換算表がありますが、この式の値をそのまま使うことはできません。何故なら水槽の水には CO2 以外の酸性物質が大量に含まれているためです。
式から単純に計算してしまうと、水槽にお酢を垂らすと CO2 濃度が上がるということになってしまいますが、そんなことはありません。
理論式と補正係数による推定方法
今回のプログラムでは、以下のような理論式をベースにしています。
CO2 (ppm) = 3.0 × kH × 10^(7.0 - pH)
しかし、この式をそのまま使うのではなく、CO2 添加開始時の pH を基準点として補正係数を自動計算しています。
double estimateCO2(double kh, double ph) {
double theoretical = 3.0 * kh * pow(10, 7.0 - ph);
return co2CorrectionFactor * theoretical;
}
補正係数の決定ロジック
CO2 添加が開始されるタイミングで、以下の処理が行われます。
double startPH = readPH();
double theo = 3.0 * khValue * pow(10, 7.0 - startPH);
co2CorrectionFactor = co2CorrectionReference / theo;
ここで co2CorrectionReference は「CO2 添加前の水槽の CO2 濃度」として設定した値です。
つまり、添加前の状態を既知の濃度として固定し、そこからの pH 変化分だけを CO2 濃度の変化として計算しています。これにより、CO2 以外の酸性物質による pH 低下分は計算から除外され、純粋に CO2 添加による濃度上昇のみを推定できるようになっています。ただしこの方式でも添加前の CO2 濃度が不確かであることから完璧な推定はできませんし、CO2 添加中に大量の酸性物質が水槽に入ってきた場合は推定した CO2 濃度は上がってしまうため、あくまで目安です。
測定回路以外の機能を全て作る
pH は測定できるようになりましたが CO2 の制御には他にも機能が必要です。
剥き出しのマイコンなどを水槽の周りにごちゃごちゃ設置するのも嫌なので、マイコンや測定回路、電磁弁の駆動回路などを1つにまとめた基板を製作し、1つに収めて設置します。
そのあたりについては別の記事でご紹介したいと思います。
