ESP32 WROOM 32, NPK sensor and TTL to RS485 Program issue

Hello, I got FFFFFFFFFFF 255 error in serial monitor. Is there anybody face this problem before? and can anyone know what's the problem? I've no idea what was the problem ? but first time got output while run the program but that wasn't accurate and stable output. can anyone help me to solve this problem?

This is my code

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

// RE and DE Pins set the RS485 module
// to Receiver or Transmitter mode
#define RE 18
#define DE 19

// Modbus RTU requests for reading NPK 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};

// Define software serial for RS485 communication
SoftwareSerial mod(16, 17);  // RX = 16, TX = 17 (Change pins as needed)

void setup() {
    Serial.begin(9600);  // Start Serial Monitor
    mod.begin(4800);     // Start Modbus communication

    // Define pin modes for RS485 control
    pinMode(RE, OUTPUT);
    pinMode(DE, OUTPUT);
    
    delay(500);
}

byte read_npk(const byte* command) {
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(10);

    mod.write(command, 8);  // Send request
    delay(10);

    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);

    // Wait for response (7 bytes expected)
    long timeout = millis();
    while (mod.available() < 7) {
        if (millis() - timeout > 2000) {  // 2 sec timeout
            Serial.println("Timeout! No data received.");
            return 255;  // Error value
        }
        delay(10);
    }

    // Read response
    byte response[7];
    for (byte i = 0; i < 7; i++) {
        response[i] = mod.read();
    }

    // Print received data
    Serial.print("Response: ");
    for (byte i = 0; i < 7; i++) {
        Serial.print(response[i], HEX);
        Serial.print(" ");
    }
    Serial.println();

    // Extract NPK value (bytes 3 & 4)
    int value = (response[3] << 8) | response[4];  // Combine High + Low byte

    return value;  // Return proper data
}

void loop() {
    Serial.println("\nReading NPK values...");

    byte nitrogen = read_npk(nitro);
    byte phosphorous = read_npk(phos);
    byte potassium = read_npk(pota);

    Serial.print("Nitrogen: ");
    Serial.print(nitrogen);
    Serial.println(" mg/kg");

    Serial.print("Phosphorous: ");
    Serial.print(phosphorous);
    Serial.println(" mg/kg");

    Serial.print("Potassium: ");
    Serial.print(potassium);
    Serial.println(" mg/kg");

    delay(2000);
}

circuit diagram:

The data type you try and return from read_npk is an int but the function declares the return data type as byte.

The code has several serial print statements - what do you see on the serial monitor?

Also, your 12v supply, sensor, RS485 module and ESP32 should share a common ground.

1 Like

the ESP32 has two spare hardware serial ports? why are you using SoftwareSerial?

ok, I've connected supply ground in common ground but I didn't show properly in the circuit diagram. And I don't know the program that much.

Also, power the RS485 from 3.3V pin if you care about your Esp.
Or even better, use level shifters if you have.

1 Like

Do you mean whether I should change the pin or switch from SoftwareSerial to HardwareSerial in the program?

Sure definitely I'll give 3.3V after proper setup of program. Now I've given supply for esp32 through USB connected with laptop.

if you have hardware serial don't use Softwareserial
I have used 3.3V to power the RS485 modules

1 Like

Ok I'll use hardware serial. so I don't need to use 5V thank you

Nothing wrong with that.
But Rs485 shouldn't be connected to 5V pin of Esp. Use 3.3V pin instead.

1 Like

Ok you meant esp32 3.3V pin right, I got it thank you.

Also your wiring between RS485 and Esp has to be rock solid, not some flimsy connections, daisy chained jumper wires and breadboards.

1 Like

Got it! I'll make sure to use solid connections instead of flimsy jumper wires or breadboards. Thanks for the advice!

Are you sure your RS485 module supports 3.3V operation?

I believe the one shown in your image does not (it's based on MAX485 ic).

I'm not sure that support 3.3V, but I also tried RS485 with 5V even though same problem was occurred.

Max485 is 5V chip, but for my experience with many modules like this it works reliably at 3.3V.
Better option than 5V without level shifters.

1 Like

Did you manage to get it working , because i'm having similar troubles trying to get mine working.

These are the results i was getting :
Humidity: = 6553.5 %

Temperature: = 6553.5 deg.C

Conductivity: = 65535.00 uS/cm

pH: = 6553.5

Nitrogen: = 65535.00 mg/L

Phosphorus: = 65535.00 mg/L

Potassium: = 65535.00 mg/L

yes now my NPK sensor working without FFFF 255 issues.

Could you please share your code and connections for the NPK sensor , RS485 Module and ESP 32

Did you check your sensor baud rate? because some sensors have fixed baud rate

This my program

#include <HardwareSerial.h>

#define RE 22
#define DE 23

// Modbus RTU requests for reading NPK 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};

byte values[11];

HardwareSerial mod(2);  // Use HardwareSerial on UART2 (TX2 = 17, RX2 = 16)

void setup() {
  Serial.begin(115200);
  mod.begin(4800, SERIAL_8N1, 16, 17);  // Try 9600 first, if not working try 4800

  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  
  digitalWrite(RE, LOW);
  digitalWrite(DE, LOW);
  
  delay(500);
}

void loop() {
  byte val1 = nitrogen();
  delay(250);
  byte val2 = phosphorous();
  delay(250);
  byte val3 = potassium();
  delay(250);

  Serial.print("Nitrogen: ");
  Serial.print(val1);
  Serial.println(" mg/kg");
  Serial.print("Phosphorous: ");
  Serial.print(val2);
  Serial.println(" mg/kg");
  Serial.print("Potassium: ");
  Serial.print(val3);
  Serial.println(" mg/kg");
  
  delay(2000);
}

byte nitrogen(){
  Serial.println("Requesting Nitrogen...");

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  
  mod.write(nitro, sizeof(nitro));
  mod.flush();
  
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  long timeout = millis();
  while (mod.available() < 7) {
    if (millis() - timeout > 2000) {  
      Serial.println("Timeout! No response.");
      return 255;
    }
    delay(10);
  }

  Serial.print("Response: ");
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    Serial.print(values[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  return values[4];
}

byte phosphorous(){
  Serial.println("Requesting Phosphorous...");

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  
  mod.write(phos, sizeof(phos));
  mod.flush();
  
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  long timeout = millis();
  while (mod.available() < 7) {
    if (millis() - timeout > 2000) {  
      Serial.println("Timeout! No response.");
      return 255;
    }
    delay(10);
  }

  Serial.print("Response: ");
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    Serial.print(values[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  return values[4];
}

byte potassium(){
  Serial.println("Requesting Potassium...");

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  
  mod.write(pota, sizeof(pota));
  mod.flush();
  
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  long timeout = millis();
  while (mod.available() < 7) {
    if (millis() - timeout > 2000) {  
      Serial.println("Timeout! No response.");
      return 255;
    }
    delay(10);
  }

  Serial.print("Response: ");
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    Serial.print(values[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  return values[4];
}