Hello comm I really need your help for my project. I am trying to test the readings of the soil sensor I bought for our software engineering project. I use this code to test the sensor for the data readings of it on the soil
#define DE 32 // DE connected to GPIO 32
#define RE 33 // RE connected to GPIO 33
#define MODBUS_RX 16 // RX2 for ESP32
#define MODBUS_TX 17 // TX2 for ESP32
void setup() {
Serial.begin(9600); // For serial monitor
Serial2.begin(4800, SERIAL_8N1, MODBUS_RX, MODBUS_TX); // RS485 communication with sensor
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(DE, LOW); // Start in receive mode
digitalWrite(RE, LOW); // Start in receive mode
}
void loop() {
// Query for multiple parameters
uint8_t query[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x07, 0x04, 0x08};
byte receivedData[20]; // Extended buffer for received data
// Print the sent query
Serial.print("Sent Query: ");
for (int i = 0; i < sizeof(query); i++) {
Serial.print(query[i], HEX);
Serial.print(" ");
}
Serial.println();
// Set to transmission mode
// Set to transmission mode
// Set to transmission mode
// Set to transmission mode
digitalWrite(DE, HIGH); // Enable Driver
digitalWrite(RE, HIGH); // Disable Receiver
delay(30); // Ensure mode switch is stable
// Send the query
Serial2.write(query, sizeof(query)); // Send the 8-byte query
delay(35); // Delay to allow time for the entire query to be transmitted
// Set to receive mode after sending
digitalWrite(DE, LOW); // Disable Driver
digitalWrite(RE, LOW); // Enable Receiver
delay(50); // Short delay to give the sensor time to respond
// Check and print the received data
int bytesAvailable = Serial2.available();
Serial.print("Bytes available: ");
Serial.println(bytesAvailable);
if (bytesAvailable > 0) {
Serial.print("Received Data: ");
for (int i = 0; i < bytesAvailable && i < 20; i++) { // Limit to 20 bytes
receivedData[i] = Serial2.read();
Serial.print(receivedData[i], HEX);
Serial.print(" ");
}
Serial.println();
} else {
Serial.println("No response or insufficient data received");
}
delay(5000); // Wait 10 seconds before sending the next query
}
now after uploading it this is the result I get
Sent Query: 1 3 0 0 0 7 4 8
Bytes available: 17
Received Data: E 0 0 1 B 0 0 0 3A 0 0 0 0 0 0 AD F1
Sent Query: 1 3 0 0 0 7 4 8
Bytes available: 15
Received Data: 80 1 B 0 0 0 3A 0 0 0 0 0 0 AD F1
Sent Query: 1 3 0 0 0 7 4 8
Bytes available: 15
Received Data: 4 1 B 0 0 0 3A 0 0 0 0 0 0 AD F1
so after that I try to convert the data using this codes
#include <Wire.h>
#define RE 33 // Receiver Enable
#define DE 32 // Driver Enable
#define DI 17 // TX2 for ESP32
#define RO 16 // RX2 for ESP32
const byte H[8] = {0x01, 0x03, 0x00, 0x12, 0x00, 0x01, 0x24, 0x0F}; // Soil Humidity
const byte T[8] = {0x01, 0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xCF}; // Soil Temperature
const byte CE[8] = {0x01, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE}; // Soil Conductivity
const byte PH[8] = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B}; // Soil PH
const byte N[8] = {0x01, 0x03, 0x00, 0x1E, 0x00, 0x01, 0xE4, 0x0C}; // Soil Nitrogen
const byte P[8] = {0x01, 0x03, 0x00, 0x1F, 0x00, 0x01, 0xB5, 0xCC}; // Soil Phosphorus
const byte K[8] = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xC0}; // Soil Potassium
byte values[9];
float temperature_val = 0.00;
float humidity_val = 0.00;
float PH_val = 0.00;
int CE_val;
byte N_val, P_val, K_val;
void setup() {
Serial.begin(9600);
Serial2.begin(4800, SERIAL_8N1, RO, DI); // Use Serial2 for RS485
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
}
void loop() {
humidity_val = Collect_Data(H, "Humidity");
temperature_val = Collect_Data(T, "Temperature");
CE_val = Collect_Data(CE, "Conductivity");
N_val = Collect_Data(N, "Nitrogen");
P_val = Collect_Data(P, "Phosphorus");
K_val = Collect_Data(K, "Potassium");
PH_val = Collect_Data(PH, "PH");
Serial.print("Humidity: "); Serial.println(humidity_val);
Serial.print("Temperature: "); Serial.println(temperature_val);
Serial.print("CE: "); Serial.println(CE_val);
Serial.print("PH: "); Serial.println(PH_val);
Serial.print("N: "); Serial.println(N_val);
Serial.print("P: "); Serial.println(P_val);
Serial.print("K: "); Serial.println(K_val);
Serial.println("----------------------");
delay(5000);
}
float Collect_Data(const byte *query, const char *dataLabel) {
float result = 0.0;
uint8_t i = 0;
uint32_t startTime;
while (Serial2.available()) Serial2.read(); // Clear buffer before new query
// Send the query
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
Serial2.write(query, 8);
delay(10);
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// Collect response
startTime = millis();
while (millis() - startTime <= 500) {
if (Serial2.available() && i < sizeof(values)) {
values[i++] = Serial2.read();
}
}
// Validate response
if (i >= 5 && values[0] == 0x01 && values[1] == 0x03) { // Ensure correct address and function code
result = (values[3] << 8 | values[4]) * 0.1; // Convert to proper scale
} else {
Serial.print("Invalid response for ");
Serial.println(dataLabel);
}
return result;
}
now I've got this result
Invalid response for Humidity
Invalid response for Temperature
Invalid response for Conductivity
Invalid response for Nitrogen
Invalid response for Phosphorus
Invalid response for Potassium
Invalid response for PH
Humidity: 0.00
Temperature: 0.00
CE: 0
PH: 0.00
N: 0
P: 0
K: 0
I really don't have an Idea what to do next, this is how my wirings looks like
ESP32 RS485 Module Soil Sensor
------------------------------------------------------------
17 (TX) ----> DI (Data In)
16 (RX) <---- RO (Receiver Out)
32 (DE) ----> DE (Direction Enable)
33 (RE) ----> RE (Receive Enable)
GND ----> GND Black (GND)
5V ----> VCC Brown (Power)
A <----> Yellow (RS485 A)
B <----> Blue (RS485 B)
I am stuck to this I just need the values for this then I can finally proceed from the rest of the project please help me I need your guidance I am so new to this, thanks for the future help