Overview
In this tutorial, we will learn how to make our own Soil EC & Salinity Meter using Arduino & Soil EC Sensor. Soil electrical conductivity (EC) is a measure of the amount of salts in soil (salinity of soil). It is an important indicator of soil health. It affects crop yields, suitability, nutrient availability, and activity of soil microorganisms. Salinity is a measure of soluble salts in soil or water. Salt molecules comprise a cation from sodium, potassium, calcium, and an anion from chloride or sulfate.
Excess salts hinder plant growth by affecting the soil-water balance. Although EC does not provide a direct measurement of specific ions or salt compounds but correlates to concentrations of nitrates, potassium, sodium, chloride, sulfate & ammonia. This is the reason why measurement of Soil Electrical Conductivity & Soil Salinity is important. Soil EC can be measured via electrodes inserted directly into the ground or by extracting soil water using a Lysimeter.
In this proposed system, we will measure the Soil EC & Salinity using our own DIY Arduino Soil EC Meter. The type of soil electrical conductivity sensor that we will be using is the JXCTIOT Soil EC Sensor. The sensor works on Modbus protocol. Using some Modbus command we can request Soil EC & Salinity value from the Sensor.
We will display the Soil EC Value and Salinity value on a 0.96″ OLED Display. Earlier we discussed the measurement of Soil NPK Value & Soil Ph Value using a similar Modbus Based Sensor. We will use the similar approach now to calculate the Soil Salinity & Soil Conductivity. The Soil EC Sensor along with Arduino can give digital reading of Soil EC & Salinity.
Bill of Materials
To make DIY Arduino Soil EC Meter, you need the following components. You can purchase all the components online from Amazon. For that check the following purchase links below. The Soil electrical conductivity sensor is a little bit expensive.
| S.N. | Components | Quantity | Purchase Links |
|---|---|---|---|
| 1 | Arduino Nano Board | 1 | Amazon | AliExpress |
| 2 | Soil EC Salinity Sensor | 1 | Amazon | AliExpress |
| 3 | 0.96" I2C OLED Display | 1 | Amazon | AliExpress |
| 4 | MAX485 Modbus Module | 1 | Amazon | AliExpress |
| 5 | 9-12V Power Supply | 1 | Amazon | AliExpress |
| 6 | Connecting Wires | 10 | Amazon | AliExpress |
| 7 | Breadboard | 1 | Amazon | AliExpress |
Meaning of Soil Electrical Conductivity & Salinity
Soil electrical conductivity (EC) is the measurement of the ability of soil water to carry electrical current. Electrical conductivity is an electrolytic process that occurs principally through water-filled pores.
The Cations like Ca2+, Mg2+, K+, Na+ & NH4+ and anions like SO42-, Cl-, NO3 – & HCO3 – from the dissolved salts carry electrical charges. The electrical charges are responsible for the conduction of electrical current. Thus, the concentration of ions determines the EC of soils.
In agriculture, EC is used principally as a measure of soil salinity. Soil salinity is a measure of the minerals and salts that can be dissolved in water. EC is expressed in Siemens per meter (S/m) whereas Salinity is expressed in mg/Kg.
Soil Electrical Conductivity (EC) & Salinity Sensor
The JXCTIOT Soil EC Sensor is a low-cost Soil Sensor for EC & Salinity Measurement application. It is designed with industry standards, featuring high precision, high sensitivity & durability. You can use this sensor for the evaluation of soil conditions. It can quickly test the conductivity & salinity of different kinds of soil. There are multiple soil electrical conductivity & Salinity Sensors. But this sensor is the best one for practical applications.
The inside of the sensor has a high-quality chip. The chip has low power consumption, high sensitivity, and also high stability. The probe of the sensor is made using austenitic 316 stainless steel as a raw material. This is why the sensor has anti-rust resistance, electrolysis resistance, salt, and alkaline corrosion resistance. This ensures long-term operation of the soil & is suitable for various types of soil.
You can use this sensor in scientific experiments, water-saving irrigation, gardening, greenhouses, outdoor farming, horticulture, golf & turf management. The sensor is also better suited for applications like forestry, precision agriculture & other professional environmental monitoring scenarios. You can use this Soil EC or Conductivity sensor Arduino or any other microcontroller.
Characteristics
- Imported high-quality soil EC sensor and chips
- Special designed Sensor, with great penetration of soil
- Unique sensing technology, with a wide working range
- High-quality soil salinity sensor with stable sensing ability
- Portable design and easy testing
- Low power consumption
- IP68 casing, with fully waterproof function
Specifications
- Power supply: 12-24V DC
- Output signal: Modbus RS485/4-20mA/0-5V/0-10V
- Working Temperature range: -40℃ to 80℃
- Electrical conductivity measurement range: 0-10000us/cm
- Conductivity resolution: 10us/cm
- Response Time: <1s
- Protection Level: IP68 Waterproof Casing
Sensor Pinout
The Sensor has 4 pins as VCC, GND, 485-A & 485-B. The Sensor operates on 12V-24V. You won’t get any output if you supply anything lesser than 12V.
Interfacing Soil EC sensor arduino
Now, let us interface the Soil EC Salinity Sensor with the Arduino Nano Board using the MAX485 Modbus Module. The connection diagram is given below.
Connect the R0 & DI pin of from the Modbus to D2 & D3 of Arduino using Software Serial. Similarly, we have to enable DE & RE high which is done by connecting them to the D7 & D8 pin of Arduino. The EC Sensor has 4 wires. The brown one is VCC which needs a 12V-24V Power Supply. The GND pin which is black in color needs to be connected to the GND of Arduino. Connect the Blue wire which is the B pin to the B pin of MAX485. Also connect the Yellow Wire which is the A pin to the A pin of MAX485.
The 0.96″ SSD1306 OLED Display is an I2C Module. Connect the OLED Display VCC & GND pin to the 3.3V & GND of Arduino. Similarly, connect the OLED SDA & SCL pins to the A4 & A5 of Arduino. You can follow the circuit diagram & assemble the circuit on a breadboard or make a custom design PCB.
Project PCB Gerber File & PCB Ordering Online
If you don’t want to assemble the circuit on breadboard and you want PCB for the project, then here is the PCB for you. The PCB Board for the DIY EC Meter is designed using EasyEDA online Circuit Schematics & PCB designing tool. The front side and back side of the PCB is given below.
The Gerber File for the PCB is given below. You can simply download the Gerber File and order the PCB from ALLPCB at 1$ only.
You can now upload the Gerber File by choosing the Quote Now option. From these options, you can choose the Material Type, Dimensions, Quantity, Thickness, Solder Mask Color and other required parameters.
After filling all details, select your country and shipping method. Finally you can place the order.
Modbus Command for Soil EC Sensor
Modbus commands can instruct a Modbus Device to:
1. change the value in one of its registers, which is written to Coil and Holding registers
2. read an I/O port: Read data from Discrete and Coil ports,
3. command the device to send back one or more values contained in its Coil and Holding register
A Modbus command contains the Modbus address of the device it is intended for (1 to 247). Only the addressed device will respond and act on the command, even though other devices might receive it.
The Soil EC Sensor has 3 different for reading the value of Soil EC & Soil Salinity. You can get the inquiry bit address from the instruction manual.
To learn more about the Modbus RTU Communication protocol, you may follow the following tutorials:
- Modbus RTU Communication with Arduino
- Modbus RTU Communication with ESP32
- Modbus RTU Communication with Raspberry Pi Pico
Soil EC Value
The inquiry frame for Soil EC Value is:
You will get the following as a response:
You can calculate the Soil Conductivity from the Response you receive. For example, if you get 5DC as a response then Soil EC Value will be:
5DC H(hexadecimal) =1500 (Decimal) => Conductivity =1500us/cm
Soil Salinity Value
The inquiry frame for Soil Salinity Value is:
You will get the following as a response:
You can calculate the Soil Salinity from the Response you receive. For example, if you get 69 as a response then Soil Salinity Value will be:
69 H(hexadecimal) =105 (Decimal) => Salinity = 105mg/L
Source Code/Program
Here is the source code for interfacing Soil Salinity Sensor with Arduino. You can use this code with Soil EC Sensor & Arduino to retrieve soil electrical conductivity value & Soil Salinity value via Modbus RTU command. You can send the command and retrieve the value in HEX Code. The HEX code needs to be converted into Decimal to get the Measured Soil Nutrient content data.
Since we are using OLED Display to display the Soil EC & Salinity value, you will need OLED Library. Download the following OLED Library and add it to the Arduino IDE.
1. Adafruit SSD1306 Library: Download
2. Adafruit GFX Library: Download
Here is the complete source code. Compile the code & upload it to the Arduino Nano Board.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define RE 8 #define DE 7 const byte ec[] = {0x01, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE}; const byte salinity[] = {0x01, 0x03, 0x00, 0x14, 0x00, 0x01, 0xC4, 0x0E}; byte values[8]; SoftwareSerial mod(2, 3); #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(9600); mod.begin(9600); pinMode(RE, OUTPUT); pinMode(DE, OUTPUT); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.display(); delay(100); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(20, 30); display.print("Soil Analysis"); display.display(); delay(2000); } void loop() { /**************Soil EC Reading*******************/ digitalWrite(DE, HIGH); digitalWrite(RE, HIGH); delay(10); if (mod.write(ec, sizeof(ec)) == 8) { digitalWrite(DE, LOW); digitalWrite(RE, LOW); for (byte i = 0; i < 7; i++) { values[i] = mod.read(); Serial.print(values[i], HEX); } Serial.println(); } int soil_ec = int(values[3]<<8|values[4]); delay(1000); /**************Soil Salinity Reading*******************/ digitalWrite(DE, HIGH); digitalWrite(RE, HIGH); delay(10); if (mod.write(salinity, sizeof(salinity)) == 8) { digitalWrite(DE, LOW); digitalWrite(RE, LOW); for (byte i = 0; i < 7; i++) { values[i] = mod.read(); Serial.print(values[i], HEX); } Serial.println(); } int soil_salinity = int(values[4]); delay(1000); Serial.print("Soil EC: "); Serial.println(soil_ec); Serial.print("Soil Salinity: "); Serial.println(soil_salinity); display.clearDisplay(); display.setTextSize(2); display.setCursor(0,10); display.print("EC:"); display.print(soil_ec); display.setTextSize(1); display.print(" us/cm"); display.setTextSize(2); display.setCursor(0,40); display.print("SL:"); display.print(soil_salinity); display.setTextSize(1); display.print(" mg/L"); display.display(); delay(2000); } |
Monitoring Soil EC & Salinity Data on OLED Display
Once you upload the code to the Arduino Nano Board, the OLED will initialize along with the sensor. The sensor will take some time to get stabilized and the reading may be incorrect for few seconds.
Once the sensor gets stabilized, you can dip the sensor in the soil to get the Soil EC & Salinity Reading. The OLED Display will display the EC Value in micro Simens per centimeter (us/cm) & Salinity value in milligram per kilogram (mg/kg).
So this is how you interface Soil EC Salinity Sensor with Arduino & get the Soil EC Salinity Readings. Similarly, put the sensor in different samples of soil. You will see a variation in the value of EC/Salinity depending upon the type of soil.
Video Tutorial & Guide
Follow the following video to learn about the entire project & code information. The video will properly guide to make your own Soil EC Salinity Meter using Arduino.
























16 Comments
just did it and it worked perfectly, any way to calibrate or to test if its working ok? I mean, any value of reference?
Hello can you please provide an explanation for this line?
int soil_ec = int(values[3]<<8|values[4]);
thanks, BR
This is a bit shifting operation implemented using Bitwise Operator. This is done to read 16-bit data.
Hi sir: may I contact you by email?
Actually, my ec meter project did not work well.
So could you give me a help?
#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 8
#define DE 7
const byte ec[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x03, 0x05, 0xCB};
byte values[8];
SoftwareSerial mod(2, 3);
void setup()
{
Serial.begin(9600);
mod.begin(9600);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
delay(1000);
}
void loop()
{
/**************Soil EC Reading*******************/
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(1000);
if (mod.write(ec, sizeof(ec)) == 8)
{
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
for (byte i = 0; i < 7; i++)
{
values[i] = mod.read();
Serial.print(values[i], HEX);
}
Serial.println();
}
int soil_ec = int(values[3]<<8|values[4]);
delay(1000);
Serial.print(” Soil EC: “);
Serial.print(soil_ec);
delay(2000);
}
My ecMeter is 3 in one , soil ec, soil temperature, and soil moisture.
Inquire frame is : {0x01, 0x03, 0x00, 0x00, 0x00, 0x03, 0x05, 0xCB}
response frame is : 0x01, 0x03, 0x06, 0x02 0x92, 0xFF 0x9B, 0x03 0xE8, 0xD8, 0X0F
moisture, temperature, EC meter, CRCL ,CRCH
Hello. I followed your video exactly, but when testing the project out the EC_Value stays the same at -1 and Soil Salinity at 255. I tried changing plants, soil, adding water, and much more but there is no change in the value of the soil. Any reason this is happening?
Check the frame request address.
Sir, I am having the same problem. Can you please elaborate on what you mean by frame request address?
Change int soil_ec = int(values[3]
Can I use this code for Arduino Uno?
Yes you can.
I ran exactly the same circuit and program but no output. What is the current consumed by the sensor? When I connect the sensor directly to 12 volts, the sensor consumes only 10 mA. this is correct?
Hi. I am using bh-485-do sensor (a dissolve oxygen sensor) which is using RS485 modbus too. I followed your wiring and coding exactly, but I don’t get the expected result. The current results are all in FFFFFFFFFFFFFF.
This is my coding:
#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 8
#define DE 7
const byte oxygen[] = {0x03, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD4, 0x28};
const byte temperature[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
byte values[7];
SoftwareSerial mod(2, 3);
void setup()
{
Serial.begin(9600);
mod.begin(9600);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
delay(2000);
}
void loop()
{
/**************water oxygen Reading*******************/
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
if (mod.write(oxygen, sizeof(oxygen)) == 8)
{
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
for (byte i = 0; i < 7; i++)
{
values[i] = mod.read();
Serial.print(values[i], HEX);
}
Serial.println();
}
// int water_oxygen = int(values[3] << 8 | values[4]);
int water_oxygen = int(values[3]);
delay(1000);
/**************water temperature Reading*******************/
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
if (mod.write(temperature, sizeof(temperature)) == 8)
{
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
for (byte i = 0; i < 7; i++)
{
values[i] = mod.read();
Serial.print(values[i], HEX);
}
Serial.println();
}
int water_temperature = int(values[4]);
delay(1000);
Serial.print(“water oxygen: “);
Serial.print(water_oxygen * 0.01);
Serial.println(” mg/L”);
Serial.print(“water temperature: “);
Serial.print(water_temperature * 0.1);
Serial.println(” C”);
delay(5000);
}
According to the manual:
https://img80002958.weyesimg.com/uploads/www.boquinstrument.com/addon/16078430671354.pdf
DO data reading instruction:
Addr. + Func. + Register start Addr. + Number of registers read + CRC check code(Hex)
e.g. Tx:03 03 00 01 00 01 D4 28
DO data return instruction:
Addr. + Func. + data length + data + CRC check code(Hex)
e.g. Rx:03 03 02 00 DF 80 1C
Temp data reading instruction:
Addr. + Func. + Register start Addr. + Number of registers read + CRC check code(Hex)
e.g. Tx:01 03 00 00 00 01 84 0A
Temp data return instruction:
Addr. + Func. + data length + data + CRC check code(Hex)
e.g. Rx:01 03 02 00 DF F9 DC
2145125612562356236
Hi. I am having the same problem with you. Do you solve it?
Check the power supply given to the max485 TTL, in my case it worked at below 5V (4.94V to be precise).
Is there a way to contact you directly ?