今日は土壌抵抗の平均化処理を考えます。
前回までに土壌抵抗を読むことと、それに応じてポンプまたはLEDを動作させることを実装しました。
実験的には金属膜抵抗をつかっているので、抵抗はある程度安定しています。
しかし、土壌抵抗はそのようにいかないと予想しています。
これは、土壌の中の水分は動いていて、また、センサーと土壌との接触が不安定である可能性があり、観測値が乱れるためです。
そのため、数回の測定を連続して実施することで、”確からしい”土壌抵抗を測定する必要があります。
ここでは、土壌抵抗を測定するタイミングにきたら、設定した(平均化の)サンプリング周期で、設定した(平均化の)サンプリング数をサンプリングし、平均の土壌抵抗をもって、このときの土壌抵抗とします。
前回からの追加変更点は青字です。
========================
float regist = 900; //土壌抵抗
int power = 255; //ポンプpwm
int threshold = 600; //水遣り敷居値
int GREEN = A1;
int YELLOW = A2;
int RED = A3;
int POMP = 5;
int LED = 150;
int cycle = 1000; //水遣りチェック周期(ms)
int aveNum = 10;//平均化のサンプリング数
int aveCycle = 30; //平均化サンプリング周期(ms)
void setup() {
Serial.begin(9600); //シリアルモニタを使う(カッコ内は通信速度)
pinMode(A0, INPUT); //土壌抵抗Read
pinMode(5, OUTPUT); //電圧を印可する宣言
pinMode(A1, OUTPUT); //GREEN
pinMode(A2, OUTPUT); //YELLOW
pinMode(A3, OUTPUT); //RED
}
void loop() {
float REGIST = 0; //平均計算のための中間の数値を格納
int i; //繰り返しのためのカウンター
for (i = 0 ; i < aveNum; i++) {
regist = analogRead(A0);
REGIST = REGIST + regist; //読み値を足し合わせ合計していく
Serial.print(regist);
delay(aveCycle);
}
regist = REGIST / aveNum; //合計から平均を算出しregistとして出力
~~続きは前回と同じ
=============================
平均化のサンプリング数、一度のタイミングでサンプリングする回数をaveNum、その周期をaveCycleと定義しました。
測定された土壌抵抗 registは小数点以下を有効にするため、これまで使っていた「int」ではなく「float」に変更します。
intは正の整数しかとれないので、少数が使えるfloatにします。
for (i = 0 ; i < aveNum; i++) {
の文で、analogReadの抵抗値をサンプリング回数分、測定し、自身に足していきます。
ここで、REGISTという仮の数を用意し、ここにregistの読み値を足していきます。
このようにして、読むごとにREGISTに足していくと、registの合計が算出できます。
最後にREGISTをサンプリング回数で割ることで、registの平均が算出できます。
そのサンプリングの様子と、平均化した結果をSerial.printに表示してみました。
これで平均処理の完成です。