Hello. I'm building a project for school using an R4 Wifi and 6 sen0193 capacitive soil moisture sensors.
I'm using these exact ones: Capacitive_Soil_Moisture_Sensor_SKU_SEN0193-DFRobot
I'll try to explain my setup, but please feel free to ask any questions about what I might have missed.
The sensors are wired to pins A0-A5 through 6 x 3.5" audio jack cables (The sensors each have a 1.5m cable ending in a male 3.5" audio jack. The audio jack is connected to a female audio jack connector which is then wired to the Arduino inside my project box).
The sensors are powered through the arduino 5v pin.
Since the R4 Wifi supports up to 14bit Analog Resolution, I've set the resolution to 14 bits in my setup() function using analogReadResolution(14).
I've also set the analog Reference to AR_EXTERNAL and connected the 3.3v pin to AREF (I've done this to get more usable values out of the sensors that output 3v max according to their specifications).
Now let's move on to my question.
The problem I was having was that each sensor has its own value range. This requires each sensor to be calibrated manually (in water and in air) to get the usable range. So in my graphs, I get slightly different results from each sensor even in the same exact conditions (water vs air).
What I thought I would do was make it so the sensors auto-calibrate after a few readings.
My code which returns the data is as follows (it's a function that runs when the arduino receives an HTTP request from a server)
int bitHalf = (pow(2, ADC_BITS)-1)/2;
int sensorMin[] = {bitHalf, bitHalf, bitHalf, bitHalf, bitHalf, bitHalf};
int sensorMax[] = {bitHalf, bitHalf, bitHalf, bitHalf, bitHalf, bitHalf};
void getHumidityAll() {
String valuesArr[6];
String finalTextReturn = "";
int i;
int dummyAnalogRead;
int realAnalogRead;
for (i=0; i<=5; i++){
dummyAnalogRead = analogRead(ain[i]);
delay(10);
realAnalogRead = analogRead(ain[i]);
if(realAnalogRead < sensorMin[i]){
sensorMin[i] = realAnalogRead;
}
if(realAnalogRead > sensorMax[i]){
sensorMax[i] = realAnalogRead;
}
realAnalogRead = map(realAnalogRead, sensorMin[i], sensorMax[i], 1000, 0);
valuesArr[i] = String(realAnalogRead);
if(i<5){
finalTextReturn += valuesArr[i] + ",";
} else {
finalTextReturn += valuesArr[i];
}
}
// Serial.println(bitHalf);
webserver.send(200, "text/plain", finalTextReturn);
}
The variable ADC_BITS is there just in case I switch the analog resolution in the future. It just holds an int value of 10/12/14.
I then create two arrays that hold the half-point value depending on the ADC_BITS. So for 10bit resolution, the half value would be 511.
I set the values at that half-point to make sure they are in the useful range of the sensor.
Then, when an HTTP request reaches the Arduino, I take 2 readings for each sensor to "reset" the ADC (as I've seen in many such threads).
Here comes the auto calibrating bit (hopefully)
if(realAnalogRead < sensorMin[i]){
sensorMin[i] = realAnalogRead;
}
if(realAnalogRead > sensorMax[i]){
sensorMax[i] = realAnalogRead;
}
As I understand it, each item of my sensorMin and sensorMax arrays will take the minimum and maximum possible value of its corresponding sensor.
These min/max values are the values of the sensors in water (sensorMin) and in air (sensorMax) respectively.
So each time the Arduino is reset, I will put the sensors in air and in water for a few readings and then the minimum and maximum values for each on will be set automatically.
After that, I map these values to a range of 0-1000 (1000 being in water) and return them.
What I hope to accomplish with this is to get a 0 value for all sensors when they are in air, and 1000 value for when they are in water, regardless of their unique values.
I've tried the above and it seems to be working. But since I don't have a lot of experience, I'd like to get a few more opinions in case I'm missing something.
So, is my approach correct?
Do you see any other potential issues with my setup?