Modbus-RTU Soil Sensor problem get all values

Hi, i have problems to get 7 values in one Inquiry Frame. i have the Soil Multi-parameter sensor (7-in-1), This one ------>Soil Multi-parameter sensor

And this is the Register address.

image
I found a code in different topic in this Forum
" 0x01, 0x03, 0x00, 0x00, 0x00, 0x07, 0x04, 0x08" ,but it doesn´t fit in my Arduino code. I investigated ,and i think this is my real code.
"0x01,0x03,0x00,0x06,0x00,0x07,0xE4,0x09", But the only value that work is Ph.

Can some one can help me, i don´t know if the register address need change o is the Answer frame.

Code:

#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 19  //22
#define DE 18  //23
#define DI 4  //17 TX2  //1 TX0
#define RO 15  //16 RX2  //3 RX0

#define led_on 23
#define led_capture 27
#define led_Soilsensor 25
                    //{0x01,0x03,0x00,0x06,0x00,0x07,0xE4,0x09};
const byte test[8] = {0x01,0x03,0x00,0x06,0x00,0x07,0xE4,0x09};
byte values[23] = {};

int CE, N_val, P_val, K_val;
float temperature_val, PH_val, moisture_val;
String chain;

SoftwareSerial mod(RO,DI);

void setup() {
  Serial.begin(9600);
  mod.begin(9600);
  
  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  pinMode(led_on, OUTPUT);
  pinMode(led_capture, OUTPUT);
  pinMode(led_Soilsensor, OUTPUT);
  digitalWrite(led_on, HIGH);
}

void loop() {
  collect_data();
  
  PH_val = ((values[9]<<8) + values[10])* 0.01;
  moisture_val = ((values[3]<<8) + values[4])* 0.1;  
  temperature_val = (values[5]<<8 | values[6])* 0.1;
  CE = (values[7]<<8 | values[8])* 1;
  N_val = (values[11]<<8 | values[12]);
  P_val = (values[13]<<8 | values[14]);
  K_val = (values[15]<<8 | values[16]);


  Serial.print("Humidity: "); Serial.println(moisture_val);
  Serial.print("Temperature: "); Serial.println(temperature_val);
  Serial.print("CE: "); Serial.println(CE);
  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);
  delay(2000);

}

float collect_data(){
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  if(mod.write(test,sizeof(test))==8){
    //mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  for(byte i=0;i<23;i++){
    values[i] = mod.read();
    String responseString;
    responseString += values[i] < 0x10 ? " 0" : " ";
    responseString += String(values[i], HEX);
    responseString.toUpperCase();
    Serial.print(responseString);
  } 
  Serial.println("");
 }
}

Monitor Serie:
image

Use a Modbus library to send and receive those messages. I recommend ModbusMaster (available in the Library Manager).

It seems you don't use an Arduino UNO (as we always assume if one doesn't explicitly specify another board). Most probably it's much better to use a hardware serial in this case because the software emulation should only be used if there is no hardware interface available.

1 Like

What is the problem?

It's encouraging that at your first attempt, you are actually getting what looks like the correct response from your sensor to the canned Modbus message you have sent.

That canned message is asking for the data in 7 registers starting at address 6. That won't get you the data you need as the registers you want to read from are not consecutive - there are gaps. Look at your register addresses in the image you posted.

I suspected that before to publish this topic, but i tried to print the HEX code ,and try find the values in correct order. Do ypu have any idea for guess which is each value?

Thanks, i tried to download the library ,but i dont understand how it work. I use an ESP32S ,and what is the difference between SoftwareSerial ,and HardwareSerial.

Do you HAVE to get all 7 parameters in 1 enquiry?

You could get pH on its own. Then soil moisture, temperature & conductivity, and finally soil nitrogen, phosphorus & potassium.

If you try and ask for them all in one go, then you would need to ask for 27 registers (if my maths is right) to cover registers 0006H to 0020H. Each register value requires 2 bytes (so 54 bytes) + the modbus overhead of slave ID, function code, checksum etc.

The issue you may have is that your software serial buffer may not be big enough to hold all that data - assuming all the bytes arrive before you can read them out.

If the serial buffer can´t read all the bytes. Do i need use de HardwareSerial.h or ModbusMaster.h libraries?

If you use a hardware serial port, then I think it has a 64 byte buffer. You would need to look at the source code for the modbus library you are going to use to see what the author has set for the modbus buffer size.

Again, do you have to get all the data in 1 message?

Yes, i tried to use different inquiry frames for each value ,but when i compilate. Only works one value, then the values are combined with the next frame. No one value show the correct form. It's like no exist a dot ,and new paragraph.

Ok. Post the code you used for individual requests.

#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 19  //22
#define DE 18  //23
#define DI 4  //17 TX2  //1 TX0
#define RO 15  //16 RX2  //3 RX0

#define led_on 23
#define led_capture 27
#define led_Soilsensor 25

const byte H[8] = {0x01,0x03,0x00,0x12,0x00,0x01,0x25,0xCA};   //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,0x1F,0x00,0x01,0xB5,0xCC};  //Soil Phosphorus

byte values[11];

float temperature_val = 0.00;
float humidity_val = 0.00;
float PH_val = 0.00;
byte CE_val, N_val, P_val, K_val;

SoftwareSerial mod(RO,DI);

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

  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  pinMode(led_on, OUTPUT);
  pinMode(led_capture, OUTPUT);
  pinMode(led_Soilsensor, OUTPUT);
  digitalWrite(led_on, HIGH);
}

void loop() {
  humidity_val = Collect_Data_H();
  delay(250);
  temperature_val = Collect_Data_T();
  CE_val = Collect_Data_CE();
  delay(250);
  N_val = Collect_Data_N();
  delay(250);
  P_val = Collect_Data_P();
  delay(250);
  K_val = Collect_Data_K();
  delay(250);
  PH_val = Collect_Data_PH();
  delay(250);
  
  digitalWrite(led_capture, HIGH);
  delay(100);
  digitalWrite(led_capture, LOW);
  delay(100);

  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(2000);
}

float Collect_Data_H(){
  float humidity;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(H);i++)mod.write(H[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 humidity = (values[3]<<8 | values[4])* 0.1;  
 return humidity;
}

float Collect_Data_T(){
  float temperature;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(T);i++)mod.write(T[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 temperature = (values[3]<<8 | values[4])* 0.1;  
 return temperature;
}

byte Collect_Data_CE(){
  float ce;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(CE);i++)mod.write(CE[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 ce = (values[3]<<8 | values[4])* 0.1; 
 return ce; 
}

float Collect_Data_PH(){
  float ph;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(PH);i++)mod.write(PH[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 ph = (values[3]<<8 | values[4])*0.1;  
 return ph;
}

byte Collect_Data_N(){
  float nitrogen;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(N);i++)mod.write(N[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 nitrogen = (values[3]<<8 | values[4]);  
 return nitrogen;
}

byte Collect_Data_P(){
  float phosphorus;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(P);i++)mod.write(P[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
 phosphorus = (values[3]<<8 | values[4]); 
 return phosphorus; 
}

byte Collect_Data_K(){
  float potassium;
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(uint8_t i=0;i<sizeof(K);i++)mod.write(K[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for(byte i=0;i<7;i++){
      values[i] = mod.read();
    }  
  potassium = (values[3]<<8 | values[4]); 
 return potassium; 
}

Now stay the same values, but there's not the correct
image

The first thing that jumps out is that you do not check to see if any data is available before you do your mod.read().

As you are using softwareserial, I think it blocks until all the bytes have been transmitted. Normally you would wait until all the bytes have been transmitted before switching your RS485 module back to receive.

How could i change it? I change the

for(uint8_t i=0;i<sizeof(H);i++)mod.write(H[i]);

,and replace for the

if(mod.write(H,sizeof(H))==8){    }

And its the same:
image

I think this may work for you but I have not tested it:

float Collect_Data_H(){
  float humidity;
  uint32_t startTime;
  uint8_t i;

  // flush the receive buffer
  while (mod.available()) mod.read();

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(H);i++) mod.write(H[i]);
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  i = 0;
  startTime = millis();
  // wait for up to 2 seconds for a response - i.e. the 2000UL value
  while ( millis() - startTime <= 2000UL ) {
    if (mod.available() && i<sizeof(values) ) {
      values[i++] = mod.read();
    }
  }
  // you should check that you actually received a complete message
  // rather than assuming that values[3] & values[4] hold data.
  humidity = (values[3]<<8 | values[4])* 0.1;  
  return humidity;
}

I think it works. I change some parts ,and the serial show me this:
image
I think the Humidity, Temperature ,and PH. are correct. But i don´t know why the others don´t show nothing. Here's the the updated code.

#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 19  //22
#define DE 18  //23
#define DI 4  //17 TX2  //1 TX0
#define RO 15  //16 RX2  //3 RX0

#define led_on 23
#define led_capture 27
#define led_Soilsensor 25

const byte H[8] = {0x01,0x03,0x00,0x12,0x00,0x01,0x25,0xCA};   //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,0xB5,0xCC};  //Soil Nitrogen
const byte P[8] = {0x01,0x03,0x00,0x1F,0x00,0x01,0xE4,0x0C};  //Soil Phosphorus
const byte K[8] = {0x01,0x03,0x00,0x20,0x00,0x01,0x85,0xC0};  //Soil Phosphorus

byte values[11];

float temperature_val = 0.00;
float humidity_val = 0.00;
float PH_val = 0.00;
int CE_val, N_val, P_val, K_val;

SoftwareSerial mod(RO,DI);

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

 pinMode(DE, OUTPUT);
 pinMode(RE, OUTPUT);
 pinMode(led_on, OUTPUT);
 pinMode(led_capture, OUTPUT);
 pinMode(led_Soilsensor, OUTPUT);
 digitalWrite(led_on, HIGH);
}

void loop() {
 humidity_val = Collect_Data_H();
 humidity_val = humidity_val * 0.1;
 temperature_val = Collect_Data_T();
 CE_val = Collect_Data_CE();
 CE_val = CE_val * 0.1;
 N_val = Collect_Data_N();
 P_val = Collect_Data_P();
 K_val = Collect_Data_K();
 PH_val = Collect_Data_PH();
 
 digitalWrite(led_capture, HIGH);
 delay(100);
 digitalWrite(led_capture, LOW);
 delay(100);

 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(500);
}

float Collect_Data_H(){
 float humidity;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(H);i++)mod.write(H[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }
   }   
return values[4];
}

float Collect_Data_T(){
 float temperature;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(T);i++)mod.write(T[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }
   }
temperature = (values[3]<<8 | values[4])* 0.1;  
return temperature;
}

byte Collect_Data_CE(){
 float ce;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(CE);i++)mod.write(CE[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }  
 } 
return values[4]; 
}

float Collect_Data_PH(){
 float ph;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(PH);i++)mod.write(PH[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     } 
 }
ph = (values[3]<<8 | values[4])*0.01;  
return ph;
}

byte Collect_Data_N(){
 float nitrogen;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(N);i++)mod.write(N[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }  
} 
return values[4];
}

byte Collect_Data_P(){
 float phosphorus;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(P);i++)mod.write(P[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }   
}
return values[4]; 
}

byte Collect_Data_K(){
 float potassium;
 uint32_t startTime;
 uint8_t i;
 while(mod.available())mod.read();
 digitalWrite(DE, HIGH);
 digitalWrite(RE, HIGH);
 delay(10);
 for(i=0;i<sizeof(K);i++)mod.write(K[i]);
   digitalWrite(DE, LOW);
   digitalWrite(RE, LOW);
   i = 0;
   startTime = millis();
   while(millis() - startTime <= 2000UL){
     if(mod.available() && i<sizeof(values)){
       values[i++] = mod.read();
     }   
 } 
return values[4]; 
}

And question. It is necessary leave them 2 second for each value? what is the minimum time that i can give it?

startTime = millis();
    while(millis() - startTime <= 2000UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }

No. That's just a time I put in as a wild guess just to be sure that you get all the response message. You can add some debug prints to your code to determine how quickly your sensor responds and adjust the timeout accordingky.

Remember, you are using canned modbus messages without all the usual modbus library code that would take care of timings etc.

For the values reported back as zero, I would add some debug printing to see if the sensor is actually responding to those requests.

Your latest code assumes that your sensor has responded and returns values from values array which may be from a previous message.

It's unfortunate that the basic NPK code that is seen most often in the forums is poorly written and causes the sorts of problems you are seeing.

I'm on a small screen at the moment, so can't easily read through all the posts. Which Arduino are you using?

I'm using an ESP32, I will test the missing inquiry frames separately.

I change some Inquiry frames, and its works.
image

But the CE change a lot. I tested on a individual code ,and this is the correct answer.

image

I check the codes ,but i don't find the error. Here's the updated code:

#include <SoftwareSerial.h>
#include <Wire.h>
#define RE 19  //22
#define DE 18  //23
#define DI 4  //17 TX2  //1 TX0
#define RO 15  //16 RX2  //3 RX0

#define led_on 23
#define led_capture 27
#define led_Soilsensor 25

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 Phosphorus

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;

SoftwareSerial mod(RO,DI);

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

  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  pinMode(led_on, OUTPUT);
  pinMode(led_capture, OUTPUT);
  pinMode(led_Soilsensor, OUTPUT);
  digitalWrite(led_on, HIGH);
}

void loop() {
  humidity_val = Collect_Data_H();
  temperature_val = Collect_Data_T();
  CE_val = Collect_Data_CE();
  N_val = Collect_Data_N();
  P_val = Collect_Data_P();
  K_val = Collect_Data_K();
  PH_val = Collect_Data_PH();
  
  digitalWrite(led_capture, HIGH);
  delay(100);
  digitalWrite(led_capture, LOW);
  delay(100);

  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(500);
}

float Collect_Data_H(){
  float humidity;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(H);i++)mod.write(H[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){  //2000UL
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }   
    }
    humidity = (values[3]<<8 | values[4])* 0.1;   
    return humidity;
}

float Collect_Data_T(){
  float temperature;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(T);i++)mod.write(T[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }
    }
 temperature = (values[3]<<8 | values[4])* 0.1;  
 return temperature;
}

byte Collect_Data_CE(){
  float ce;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(CE);i++)mod.write(CE[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 750UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }  
  } 
 ce = (values[3]<<8 | values[4]);
 return ce; 
}

float Collect_Data_PH(){
  float ph;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(PH);i++)mod.write(PH[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      } 
  }
 ph = (values[3]<<8 | values[4])*0.01;  
 return ph;
}

byte Collect_Data_N(){
  float nitrogen;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(N);i++)mod.write(N[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }  
 } 
 return values[4];
}

byte Collect_Data_P(){
  float phosphorus;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(P);i++)mod.write(P[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }   
 }
 return values[4]; 
}

byte Collect_Data_K(){
  float potassium;
  uint32_t startTime;
  uint8_t i;
  while(mod.available())mod.read();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  for(i=0;i<sizeof(K);i++)mod.write(K[i]);
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    i = 0;
    startTime = millis();
    while(millis() - startTime <= 500UL){
      if(mod.available() && i<sizeof(values)){
        values[i++] = mod.read();
      }   
  } 
 return values[4]; 
}

Are you saying that the correct CE value is supposed to be around 1600-1700? But when you run the complete code you uploaded, it only reports back 178?

I would print out the response frame from your sensor to see what the actual bytes received were - like you did for the individual code.


It´s missing the 01 but a think it's ok.

Second change