Built automatic irregation system for outdoor plastic pots. first tried soil sensor with capacitance - was extremely unrelyable, sensed moisture outside pot, and other unknown factors changed readings about 3 times more than the actual soil moisture I was trying to measure.
(Used absolute results)
Now stripped insulation and tried with simple analog readings with resistor. with the same plate. This works much better but still horrible.
there are 4 zones in different depths , moisture is sum of them, in the time there have been readins there has been no rain, so it should have been very stable slightly going down.
"target" is a potentiometer wich hasn't been touched, and it's also not stable in readings.
using 12v power for arduino because I use the same power supply for electric valves, but in measurement times they havn't been used.
(this is with using stabilization, by taking average of last 100 readings)
Light is also being measured with analog port, but appears to be working fine.
Averaging assumes the noise consists of values that are too high and values that are too low in approx. equal amount.
by adding the measurements the noise ++ and -- cancels each other out.
The averaging is bit faster if you take a power of 2 as #measurements as the computer can do the divide very fast.
Often a noisy signal is sampled multiple times and averaged with equal weights.
int sum = 0;
for (int m=0; m < 16; m++)
{
sum += analogRead(A0);
}
val = sum/16;
Possible drawback is that as the measurements have a different time stamps, the equal weight per measurement can introduce a systematic error.
To solve this "systematic error" one can add weights to different measurements e.g this average of 5 measurements with an increasing weight, so the last measurement gets most weight. Note the sum of the weights adds up to 100%.
sum = analogRead(A0) /16;
sum += analogRead(A0) /16;
sum += analogRead(A0) /8;
sum += analogRead(A0) /4;
sum += analogRead(A0) /2;
Another averaging scheme gives the largest weight to the middle measurement.
sum = analogRead(A0) /16;
sum += analogRead(A0) /16;
sum += analogRead(A0) /8;
sum += analogRead(A0) /2;
sum += analogRead(A0) /8;
sum += analogRead(A0) /16;
sum += analogRead(A0) /16;
Other schemes can be used of course, a generic way to use weights is to place the weights in an array
int weight[] = { 6, 3, 3, 6 }; // outer ones are equal the middle two
int sum = 0;
for (int m =0; m < 4; m++)
{
sum += analogRead(A0) /weight[m]; // sum of the weights add up to 100%
}
Possible drawback of the multiple divisions is the value is truncated with every division. Rounding solves this for most part.
sum = 0;
for (int m =0; m < 10; m++)
{
sum += (analogRead(A0) + weight[m]/2) /weight[m]; // sum of the weights add up to 100%
}