Hello @markd833 Please I need help with this. I am working with a 6-in-1 soil sensor and I keep on getting this error "Sensor timeout or incomplete frame". Below is the code I have been using.
#include <SoftwareSerial.h>
// Define the pins for RS485 communication
#define RE 8
#define DE 7
// Modbus RTU requests for reading NPK, temperature, moisture, and conductivity values
const byte nitro[] = {0x01, 0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] = {0x01, 0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte pota[] = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
const byte temperature[] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xd4, 0x0b};
const byte moisture[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0a};
const byte conductivity[] = {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xca};
byte soilSensorResponse[7]; // Response length for single register read
SoftwareSerial mod(2, 3); // Software serial for RS485 communication
void setup() {
Serial.begin(9600); // Initialize serial communication for debugging
mod.begin(4800); // Initialize software serial communication at 4800 baud rate (adjust if necessary)
pinMode(RE, OUTPUT); // Set RE pin as output
pinMode(DE, OUTPUT); // Set DE pin as output
// Ensure RE and DE are low to start in receive mode
digitalWrite(RE, LOW);
digitalWrite(DE, LOW);
}
void sendRequest(const byte request[], size_t requestSize) {
// Start the transmission mode for RS485
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
// Send the request frame to the soil sensor
mod.write(request, requestSize);
// End the transmission mode and set to receive mode for RS485
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay(10);
}
bool receiveResponse(byte response[], size_t responseSize) {
unsigned long startTime = millis();
while (mod.available() < responseSize && millis() - startTime < 1000) {
delay(1);
}
if (mod.available() >= responseSize) {
for (size_t i = 0; i < responseSize; i++) {
response[i] = mod.read();
Serial.print(response[i], HEX);
Serial.print(" ");
}
Serial.println();
return true;
} else {
Serial.println("Sensor timeout or incomplete frame");
return false;
}
}
void loop() {
sendRequest(nitro, sizeof(nitro));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int Nitrogen_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
Serial.print("Nitrogen: ");
Serial.print(Nitrogen_Int);
Serial.println(" mg/kg");
}
delay(2000);
sendRequest(phos, sizeof(phos));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int Phosphorus_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
Serial.print("Phosphorus: ");
Serial.print(Phosphorus_Int);
Serial.println(" mg/kg");
}
delay(2000);
sendRequest(pota, sizeof(pota));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int Potassium_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
Serial.print("Potassium: ");
Serial.print(Potassium_Int);
Serial.println(" mg/kg");
}
delay(2000);
sendRequest(temperature, sizeof(temperature));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int Temperature_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
float Temperature_Celsius = Temperature_Int / 10.0;
if (Temperature_Int > 0x7FFF) { // Check if temperature is negative
Temperature_Celsius = 0x10000 - Temperature_Int;
Temperature_Celsius = -Temperature_Celsius / 10.0;
}
Serial.print("Temperature: ");
Serial.print(Temperature_Celsius);
Serial.println(" °C");
}
delay(2000);
sendRequest(moisture, sizeof(moisture));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int Moisture_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
float Moisture_Percent = Moisture_Int / 10.0;
Serial.print("Moisture: ");
Serial.print(Moisture_Percent);
Serial.println(" %RH");
}
delay(2000);
sendRequest(conductivity, sizeof(conductivity));
if (receiveResponse(soilSensorResponse, sizeof(soilSensorResponse))) {
int EC_Int = int(soilSensorResponse[3] << 8 | soilSensorResponse[4]);
float EC = EC_Int / 100.0;
Serial.print("EC: ");
Serial.print(EC);
Serial.println(" mS/cm");
}
delay(2000);
}