2 soil moisture sensors on i2c, readings are tied

Hi everyone,

I’m using 2 of these i2c soil moisture sensors with an Arduino Mega. The goal is to have two+ soil moisture sensors scattered around my garden that will be connected to some automatic watering jig.

I set different addresses for each sensor and the output verifies this (i think):

22:44:13.294 -> I2C 1 Soil Moisture Sensor Address: 21
22:44:13.340 -> I2C 2 Soil Moisture Sensor Address: A1
22:44:13.387 -> Sensor 1 Firmware version: 26
22:44:13.387 -> Sensor 2 Firmware version: 26
22:44:13.433 -> 

22:44:13.480 -> SMS1 Reading register 0 : Soil Capacitance
22:44:13.526 -> register byte value == 178.00
22:44:13.573 -> Soil Capacitance: 178.00
22:44:13.573 -> Soil Moisture: 71.20%
22:44:13.619 -> 
22:44:13.619 -> SMS2 Reading register 0 : Soil Capacitance
22:44:13.665 -> register byte value == 191.00
22:44:13.665 -> Soil Capacitance: 191.00
22:44:13.711 -> Soil Moisture: 76.40%

The problem is, the readings aren’t independent of each other and placing them in different levels of moisture doesn’t reflect different values. I’ve tried a considerable amount of code and wiring variations and too much time on this.

Can anyone please help? Arduino sketch below…


#include <I2CSoilMoistureSensor.h>
#include <DFRobot_CCS811.h>
#include <I2CScanner.h>
#include <Wire.h>


I2CScanner scanner;


//I2CSoilMoistureSensor SMS;
//I2CSoilMoistureSensor SMS2;

//int address_SMS= 0x20; //Soil Monitor Sensor
//I2CSoilMoistureSensor SMS1;

I2CSoilMoistureSensor SMS1(0x21);
int address_SMS1= 0x21; //Soil Monitor Sensor

//I2CSoilMoistureSensor SMS2;
I2CSoilMoistureSensor SMS2(0xA1);
int address_SMS2= 0xA1; //Soil Monitor Sensor


// SMS1.setAddress(0x21, true);
//  SMS2.setAddress(0xA1, true);

//DFRobot_CCS811 CCS811;
//int address_AQS= 0x5A; //Air quality Sensor
//volatile  int8_t GPIO1TRIG = 0;

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
//    Wire.setClockStretchLimit(4000);
    SMS1.begin(); // reset sensor
    SMS2.begin(); // reset sensor
    delay(1000); // give some time to boot up

    scanner.Init();
}

void loop() {
  delay(1000);

  
  scanner.Scan();
  Serial.print("I2C 1 Soil Moisture Sensor Address: ");
  Serial.println(SMS1.getAddress(), HEX);
  Serial.print("I2C 2 Soil Moisture Sensor Address: ");
  Serial.println(SMS2.getAddress(), HEX);

  
  Serial.print("Sensor 1 Firmware version: ");
  Serial.println(SMS1.getVersion(), HEX);
  Serial.print("Sensor 2 Firmware version: ");
  Serial.println(SMS2.getVersion(), HEX);
  Serial.println();

  Serial.println("");  

Serial.println("please work:    ");
Serial.println(SMS1.getCapacitance());
Serial.println(SMS2.getCapacitance());


int regi = 0;

//Serial.println("SMS I BEGIN");

bool stop = true;

Serial.print("SMS1 Reading register ");
Serial.print("0 : ");
Serial.println("Soil Capacitance");

Wire.beginTransmission(address_SMS1); 
//Wire.beginTransmission(int(addr)) ; 
//Send Calculation Request for register 'regi' 
//Wire.write(0x00);Wire.endTransmission(false);
Wire.write(0);Wire.endTransmission();
//Request sensor value; including number of bytes to read
Wire.requestFrom(address_SMS1, byte(2) );//request 2 byte from address xx
Wire.endTransmission();

Serial.print("register byte value == ");
float readbyte1 = Wire.read();
float readbyte2 = Wire.read();
//Serial.println(Wire.read(), DEC);      // is it 42 hex ?
//Serial.println(Wire.read(), HEX);      // is it 92 hex ?

Serial.println(readbyte2);Wire.endTransmission();
Serial.print("Soil Capacitance: ");
Serial.println(readbyte2);

Serial.print("Soil Moisture: ");
float Sen1_P_H2O =  ( (readbyte2 / 250) ) * 100 ;
Serial.print(Sen1_P_H2O);
Serial.println ("%");

////////////// SENSOR 2 REGISTER 0
Serial.print("\nSMS2 Reading register ");
Serial.print("0 : ");
Serial.println("Soil Capacitance");

Wire.beginTransmission(address_SMS2); 
Wire.write(0);Wire.endTransmission();

Wire.requestFrom(address_SMS2, byte(2) );//request 2 byte from address xx
Wire.endTransmission(false);

Serial.print("register byte value == ");
readbyte1 = Wire.read();
readbyte2 = Wire.read();


Serial.println(readbyte2);Wire.endTransmission();
Serial.print("Soil Capacitance: ");
Serial.println(readbyte2);

Serial.print("Soil Moisture: ");
Sen1_P_H2O =  ( (readbyte2 / 250) ) * 100 ;
Serial.print(Sen1_P_H2O);
Serial.println ("%");

delay(2500);


} //end void loop

Hello @armandjg and welcome to the RobotShop community,

As you’re getting different values for each sensor the problem doesn’t seem to be setting the addresses, but it might be a calibration problem.

Calibration

To get absolute readings you have to calibrate the sensor to particular soil type as sensors are sensitive to saline content of the soil. More salinity makes readings non-linear. A great calibration guide can be downloaded here

Ah crap I meant to delete this post because I figured the issue out and didn’t want to waste anyones time responding. I really appreciate your response, though!

The main issue, among others, turned out to be that the sensors kept getting reset to the 0x21 address. Troubleshooting this would have been easier had the pins from the breadboard/arduino not get knocked loose anytime I made the slightest adjustment, which caused erratic behavior anytime I might have fixed the issue.

Also for troubleshooters looking at this from the future, the direct call to the wire library was not necessary.

Code similar to below will work:

#include <I2CSoilMoistureSensor.h>
#include <DFRobot_CCS811.h>
#include <I2CScanner.h>
#include <Wire.h>

I2CScanner scanner; 

I2CSoilMoistureSensor SMS1(0x20);
int address_SMS1 = 0x20; //Soil Monitor Sensor [20]

I2CSoilMoistureSensor SMS2(0x21);
int address_SMS2= 0x21; //Soil Monitor Sensor [21]


int pumpPin = A0; //Analog pin to control pump

void setup() { 
  Serial.begin(9600); 
  scanner.Init(); //I2C Scanner
  delay(100);

  pinMode(A0, OUTPUT);

  
} // END SETUP

void loop() {
  scanner.Scan();

  int SMScapLow = 180;
  int SMScapHigh = 488;
  
// SOIL MOISTURE SENSOR [20] /////////////
  Serial.print("Sensor [20] Capacitance: ");
  Serial.println(SMS1.getCapacitance());
  Serial.print("Sensor [20] Soil Moisture: ");
  
//  float Sen1_P_H2O =  ( (SMS1.getCapacitance()/ 255) ) * 100 ;
  float SMS1cap = SMS1.getCapacitance();
  float Sen1_P_H2O =  ( (SMS1cap- SMScapLow ) / (SMScapHigh -SMScapLow ) * 100);
  Serial.print(Sen1_P_H2O);Serial.println ("%");
  
  Serial.print("Temperature: "); 
  float Celsius1 = (SMS1.getTemperature() / (float)10 - 4);
  float Sen1_Temp_C = Celsius1;
  
  Serial.print(Celsius1); Serial.print("C / "); //temperature register
  float fahrenheit1 =  ( Celsius1 * 9 / 5) + 32; Serial.print(fahrenheit1);
  Serial.print("F"); Serial.println("");


  if(Sen1_P_H2O < 50){ //PUMP FOR SOIL 1
    digitalWrite(pumpPin, HIGH);
  } else {
    digitalWrite(pumpPin, LOW);
    }////PUMP FOR SOIL 1 END LOOP
  
  delay(200);
// SOIL MOISTURE SENSOR [21] /////////////
  Serial.print("Sensor [21] Capacitance: ");
  Serial.println(SMS2.getCapacitance());
  Serial.print("Sensor [21] Soil Moisture: ");
//  float Sen2_P_H2O =  ( (SMS2.getCapacitance()/ 255) ) * 100 ;
  float SMS2cap = SMS2.getCapacitance();
  float Sen2_P_H2O =  ( (SMS2cap- SMScapLow) / (SMScapHigh - SMScapLow ) * 100);
  Serial.print(Sen2_P_H2O);Serial.println ("%");

  Serial.print("Temperature: "); 
  float Celsius2 = (SMS2.getTemperature() / (float)10 - 4);
  float Sen2_Temp_C = Celsius2;
  
  Serial.print(Celsius2); Serial.print("C / "); //temperature register
  float fahrenheit2 =  ( Celsius2 * 9 / 5) + 32; Serial.print(fahrenheit2);
  Serial.print("F"); Serial.println("");

  
  
  delay(2500);
  
} //END VOID LOOP
1 Like