กลับหน้าหลัก
views
How to Read Soil EC, Temperature and Humidity with Arduino and PR-3000-ECTH-N01 Sensor
Last updated on

How to Read Soil EC, Temperature and Humidity with Arduino and PR-3000-ECTH-N01 Sensor


How to Read Soil EC, Temperature and Humidity with Arduino and PR-3000-ECTH-N01 Sensor

This guide covers how to use the PR-3000-ECTH-N01 soil sensor with an Arduino UNO. The sensor measures three values in a single probe: Electrical Conductivity (EC), temperature, and soil moisture. It communicates over RS485 using the Modbus RTU protocol, which is stable and well-suited for outdoor agricultural environments.

Key Features of the PR-3000-ECTH-N01

  • 3-in-1 measurement: Moisture, temperature, and EC from one probe
  • RS485 protocol: Supports up to 1,200 meters cable length, immune to noise in field conditions
  • Modbus RTU: Industrial standard, registers are straightforward to read
  • 12V DC power: Powers the entire probe without needing multiple voltage sources
PR-3000-ECTH-N01 sensor probe with 4 color-coded wires — brown (positive), black (negative), blue (B), yellow (A)

Why Measure EC Alongside Temperature

Electrical Conductivity (EC) in soil indicates the amount of dissolved salts or fertilizer concentration. However, EC is directly influenced by temperature. When temperature rises, EC rises too, even if the actual salt content in the soil has not changed. This sensor solves that problem by reporting temperature alongside EC, allowing you to correct EC values based on actual field conditions.

Required Components

ComponentQuantityNotes
Arduino UNO R31
MAX485 Module RS485 to TTL1Signal converter
PR-3000-ECTH-N01 Soil Sensor1Main probe
Power Adapter 12V DC1Sensor power supply
OLED 128x64 I2C Display1Optional readout
Breadboard MB-1021Circuit assembly
Jumper Wires Set-M-M, M-F, F-F

Wiring Diagram: Arduino with PR-3000-ECTH-N01

The circuit has three main sections: power supply, RS485 communication, and optional display output.

Part 1: MAX485 Connected to Arduino UNO

Arduino UNOMAX485 ModuleRole
5VVCCPower
GNDGNDGround
Pin 2 (RX)ROReceive Output
Pin 3 (TX)DIDriver Input
Pin 7DEDriver Enable
Pin 8REReceiver Enable
Wiring diagram showing Arduino UNO connected to MAX485 Module with pin numbers labeled

Part 2: PR-3000-ECTH-N01 Connected to MAX485 and Power

Sensor WireConnectionNotes
Blue Wire (B)MAX485 BRS485 B line
Yellow Wire (A)MAX485 ARS485 A line
Brown Wire12V DC (+)Positive power
Black Wire12V DC (-)Ground

Critical: The GND of Arduino, MAX485, and the 12V power supply must share a common ground. Without a shared ground, RS485 signals cannot be read correctly.

Part 3: OLED Display (Optional)

Arduino UNOOLED I2CNotes
5VVCC
GNDGND
A4SDA
A5SCL
Complete circuit diagram showing PR-3000-ECTH-N01, MAX485 Module and OLED display all wired to Arduino UNO

Modbus Registers of PR-3000-ECTH-N01

This sensor uses Modbus RTU Function Code 0x04 (Read Input Registers). Three registers are available:

RegisterDataUnit
0x0000Soil Moisture%
0x0001Temperature°C
0x0002Electrical Conductivity (EC)mS/cm

Installing Required Libraries

  1. Download the library bundle from MediaFire — OLED and SoftwareSerial Libraries
  2. Extract the archive with WinRAR or WinZip
  3. Copy the library folders into Documents/Arduino/libraries/
  4. Restart Arduino IDE

Arduino Code: Reading PR-3000-ECTH-N01 via Modbus RTU

#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SENSOR_SERIAL_RX 2
#define SENSOR_SERIAL_TX 3
#define MAX485_DE_RE 7
#define MAX485_RE 8

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

SoftwareSerial sensorSerial(SENSOR_SERIAL_RX, SENSOR_SERIAL_TX);

// Modbus RTU Function Code 0x04 (Read Input Registers)
byte readCommand[8] = {
  0x01,       // Slave Address
  0x04,       // Function Code: Read Input Registers
  0x00, 0x00, // Starting Address: 0x0000 (Moisture)
  0x00, 0x03, // Quantity: 3 registers (moisture, temp, EC)
  0x00, 0x00  // CRC (calculated below)
};

void setup() {
  Serial.begin(9600);
  sensorSerial.begin(9600);

  pinMode(MAX485_DE_RE, OUTPUT);
  pinMode(MAX485_RE, OUTPUT);
  digitalWrite(MAX485_DE_RE, LOW);   // Receive mode
  digitalWrite(MAX485_RE, LOW);

  // Calculate CRC16 for Modbus command
  unsigned int crc = modbusCrc16(readCommand, 6);
  readCommand[6] = lowByte(crc);
  readCommand[7] = highByte(crc);

  // Initialize OLED
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("OLED init failed"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.display();
}

void loop() {
  // Send read command to sensor
  digitalWrite(MAX485_DE_RE, HIGH);
  digitalWrite(MAX485_RE, HIGH);
  sensorSerial.write(readCommand, 8);
  sensorSerial.flush();
  digitalWrite(MAX485_DE_RE, LOW);
  digitalWrite(MAX485_RE, LOW);

  // Wait for response (expected: 11 bytes)
  delay(100);

  byte response[20];
  int bytesReceived = 0;
  unsigned long startTime = millis();

  while (sensorSerial.available() && bytesReceived < 20) {
    if (millis() - startTime > 1000) break;
    response[bytesReceived++] = sensorSerial.read();
  }

  if (bytesReceived >= 9) {
    // Response format: [addr][func][bytecount][reg1_H][reg1_L][reg2_H][reg2_L][reg3_H][reg3_L][CRC_L][CRC_H]
    int moisture = (response[3] << 8) | response[4];
    int temperature = (response[5] << 8) | response[6];
    int ecRaw = (response[7] << 8) | response[8];


    float tempC = temperature / 10.0;
    float ecValue = ecRaw / 1000.0;  // Convert to mS/cm

    // Print to Serial Monitor
    Serial.print("Moisture: ");
    Serial.print(moisture);
    Serial.print("% | Temp: ");
    Serial.print(tempC);
    Serial.print("C | EC: ");
    Serial.print(ecValue, 3);
    Serial.println(" mS/cm");

    // Display on OLED
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("Moisture: ");
    display.print(moisture);
    display.println("%");
    display.print("Temp: ");
    display.print(tempC, 1);
    display.println("C");
    display.print("EC: ");
    display.print(ecValue, 3);
    display.println(" mS/cm");
    display.display();
  }

  delay(1000);
}

// CRC16 calculation for Modbus RTU
unsigned int modbusCrc16(byte *data, int length) {
  unsigned int crc = 0xFFFF;
  for (int i = 0; i < length; i++) {
    crc ^= data[i];
    for (int j = 0; j < 8; j++) {
      if (crc & 0x0001) {
        crc = (crc >> 1) ^ 0xA001;
      } else {
        crc >>= 1;
      }
    }
  }
  return crc;
}

How to Use This Code

  1. Wire the circuit as shown in the diagram above
  2. Open Arduino IDE, paste the code, and select Board → Arduino UNO
  3. Select the correct Port and click Upload
  4. Open Serial Monitor and set Baud Rate to 9600
  5. Insert the probe into soil and observe the readings

Note: If readings show 0 or no response, check that GND is shared across Arduino, MAX485, and the 12V power supply. Also verify that the A (yellow) and B (blue) wires are connected to the correct terminals on the MAX485 module.

Reference Video

Soil EC Values and Practical Field Use

Soil EC is a critical indicator for crop management:

EC Value (mS/cm)InterpretationAction
0 – 1.0Nutrient-poor soilAdd fertilizer
1.0 – 3.0Normal for agricultureMaintain current condition
3.0 – 4.0Moderately highReduce fertilizer application
> 4.0Excessively high — salt riskCut fertilizer, increase irrigation

Summary

The PR-3000-ECTH-N01 is a practical sensor for smart agriculture systems, combining EC, temperature, and moisture in one probe. Communication happens over RS485 using standard Modbus RTU, making the code relatively straightforward to write. The most important wiring detail is establishing a common ground across the entire system and providing 12V DC power to the sensor separately from the 5V logic used by Arduino.

อยากทำโปรเจคแบบนี้?

รับทำโปรเจค Arduino / IoT จบงานไว ส่งงานครบ พร้อมสอน

If you need Arduino project service or urgent IoT development, see full service details on the home page

จ้างทำโปรเจคเลย

ความคิดเห็น