7 in 1 soil sensor is faulty

Hi everyone! I badly need help I've already tried every code I can possibly use with this sensor but it always failed to read the data/values it always give me an output of 255 in every property and another problem is that the seller didnt provide a manual so I'm not really sure if Im using the right address. Btw im using arduino uno

Those sensors (esp. for the pH) are a scam...

some come with RS485 output, other with a different interface.

➜ which one do you have, what circuit did you use, which code.... at the moment with the level of information you shared, we can't help...

#include <AltSoftSerial.h>


// RO to pin 8 & DI to pin 9 when using AltSoftSerial

#define RE 6

#define DE 7


const byte temp[] = {0x01,0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xCF};//

const byte mois[]  = {0x01,0x03,0x00,0x12,0x00,0x01,0x24,0x0F};

const byte econ[] = {0x01,0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xCE};

const byte ph[] = {0x01,0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B};//0x0B64


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];

AltSoftSerial mod;


float envhumidity = 0.0, envtemperature = 0.0, soil_ph = 0.0, soil_mois = 0.0, soil_temp = 0.0;

byte val1 = 0, val2 = 0, val3 = 0, val4 = 0,val5 = 0, val6 = 0, val7 = 0;


void setup() {

  Serial.begin(4800);

  mod.begin(4800);

  pinMode(RE, OUTPUT);

  pinMode(DE, OUTPUT);


  // put RS-485 into receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  delay(3000);

}


void loop() {

  val1 = moisture();

  soil_mois = val1/10.0;

  delay(1000);

  soil_temp = temperature()/10.0;

  delay(1000);

  val3 = econduc();

  delay(1000);

  val4 = phydrogen()/10;

  soil_ph = val4;

  delay(1000);

  val5 = nitrogen();

  delay(1000);

  val6 = phosphorous();

  delay(1000);

  val7 = potassium();

  delay(1000);


  Serial.print("Moisture: ");Serial.print(soil_mois);Serial.println(" %");

  delay(1000);

  Serial.print("Temperature: ");Serial.print(soil_temp);Serial.println(" C");

  delay(1000);

  Serial.print("EC: ");Serial.print(val3);Serial.println(" us/cm");

  delay(1000);

  Serial.print("ph: ");Serial.print(soil_ph);Serial.println(" ph");

  delay(1000);

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

  delay(1000);

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

  delay(1000);

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

  Serial.println();

  delay(3000);

}


byte moisture() {

  // clear the receive buffer

  mod.flushInput();


  // switch RS-485 to transmit mode

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);


  // write out the message

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


  // wait for the transmission to complete

  mod.flush();


  // switching RS485 to receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  // delay to allow response bytes to be received!

  delay(500);


  // read in the received bytes

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}


byte temperature() {

  // clear the receive buffer

  mod.flushInput();


  // switch RS-485 to transmit mode

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);


  // write out the message

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


  // wait for the transmission to complete

  mod.flush();


  // switching RS485 to receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  // delay to allow response bytes to be received!

  delay(500);


  // read in the received bytes

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[3]<<8|values[4];

}


byte econduc() {

  // clear the receive buffer

  mod.flushInput();


  // switch RS-485 to transmit mode

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);


  // write out the message

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


  // wait for the transmission to complete

  mod.flush();


  // switching RS485 to receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  // delay to allow response bytes to be received!

  delay(500);


  // read in the received bytes

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}


byte phydrogen() {

  // clear the receive buffer

  mod.flushInput();

  // switch RS-485 to transmit mode

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);


  // write out the message

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


  // wait for the transmission to complete

  mod.flush();


  // switching RS485 to receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  // delay to allow response bytes to be received!

  delay(500);


  // read in the received bytes

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}


byte nitrogen() {

  // clear the receive buffer

  mod.flushInput();


  // switch RS-485 to transmit mode

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);


  // write out the message

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


  // wait for the transmission to complete

  mod.flush();


  // switching RS485 to receive mode

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);


  // delay to allow response bytes to be received!

  delay(500);


  // read in the received bytes

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}


byte phosphorous() {

  mod.flushInput();

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);

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

  mod.flush();

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);

  // delay to allow response bytes to be received!

  delay(500);

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}


byte potassium() {

  mod.flushInput();

  digitalWrite(DE, HIGH);

  digitalWrite(RE, HIGH);

  delay(1);

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

  mod.flush();

  digitalWrite(DE, LOW);

  digitalWrite(RE, LOW);

  // delay to allow response bytes to be received!

  delay(500);

  for (byte i = 0; i < 7; i++) {

    values[i] = mod.read();

    // Serial.print(values[i], HEX);

    // Serial.print(' ');

  }

  return values[4];

}






Here is my diagram

Here is the box and I dont even understand and it also doesnt provide a manual so im having a hard time what to use

they seem to say it's indeed a RS485 model if we trust the black dot on the package

image

which MAX circuit are you using?

write a very simple code printing the bytes coming from the sensor to see if the circuit works

Unfortunately the code floating around for the sensor is rather poor, it does not detect errors, so you get back garbage. Since it is Modbus protocol, we should really use a Modbus library.

In principle, if you have an unknown Modbus slave it is possible to "auto-detect" by sending different combinations of message until a response is generated. However, the hardware comms setup still needs to be correct.

Given this is a common coursework problem, seems like we only need one tutorial for it which everyone can copy.

May I ask how?? I'm new to this and im still understanding how it works help and im using maxrs485

there is this tutorial that could be used for inspiration

but there are lots of similar devices on the market from the Far East... offering different interfaces

and quality....

I also tried coding my other sensor which is an npk sensor but it also gives me an output of 255 but im sure that Ive used the correct address because the seller provided a manual idk if the problem is the hardware itself because i tried using different codes but they still gave me the same output. What do you think is the problem for this?

And it's from a different brand

90% of problems with Modbus/485 are with the comms, e.g. RS485 polarity, termination, bias resistors, baud rate, data bits, parity, slave address.

Unfortunately until you get all those right you won't get any response at all. Clearly it is a lot harder without a manual, but I guess trial and error would get you there eventually.

Perhaps the coursework is not a simple test of coding ability, but resourcefulness in dealing with undocumented kit.

This is the output that im getting

received_782247207077458

You are getting no response, so all the data is 0xFF.

I tried coding with a different sensor and it came with a manual but still it is giving me an 255 output

Im suspecting that the hardware itself is not working properly but we already checked the arduino and even the maxrs485 so im suspecting it have problems with the wirings of the circuit. I also think the sensor itself have problems

Does it mean that the sensor isnt sending any data?

the code is poorly written, for example for moisture

you send a binary command over the Serial port

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

you wait an arbitrary time

  delay(500);

then you read the Serial port without even checking if there is something there to read

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

when there is nothing to read on a Serial port, the read() function returns -1 which will result in storing 0xFF into your values array.

➜ my opinion is that your sensor does not even send anything back

May I know how can I fix the code? I just found this code somewhere here in the forum and tested it out it worked for them

the code is not robust, it will kinda work if the sensor is communicating

your challenge at the moment is that it seems the sensor does not react to commands.

this could be an issue with your setup or with the sensor....

Did you check all your wires ? can you post a full picture of your setup?

try this code

// Connections
// - the RO pin to Arduino digital pin 2
// - the DI pin to digital pin 3
// - the DE pin to digital pin 7
// - the RE pin to digital pin 8

const byte ROPin = 2;
const byte DIPin = 3;
const byte DEPin = 7;
const byte REPin = 8;

#include <SoftwareSerial.h>
SoftwareSerial max485Serial(ROPin, DIPin);

// address code, function code, register start, register length, CRC_L, CRC_H
const byte nitro[] = {0x01, 0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c}; 
// expected answer: 
// address code,function code,effective number of bytes; Nitro value H, Nitro value L, CRC_L, CRC_H
// eg: 0x01 0x03 0x02 0x00 0x20 0xB9 0x9C ==> Nitro value = 0x0020 ==> 32 mg/Kg

void setup() {

  pinMode(REPin, OUTPUT);
  pinMode(DEPin, OUTPUT);
  Serial.begin(115200);
  max485Serial.begin(9600);
}

void loop() {

  // switch RS-485 to transmit mode
  digitalWrite(DEPin, HIGH);
  digitalWrite(REPin, HIGH);
  delay(1);

  // send the get nitro command
  max485Serial.write(nitro, sizeof nitro);
  max485Serial.flush();

  // switching RS485 to receive mode
  digitalWrite(DEPin, LOW);
  digitalWrite(REPin, LOW);

  byte index = 0;
  while (index <= 7) { // we will get stuck there if there is no anwser
    if (max485Serial.available()) {
      byte r = max485Serial.read();
      Serial.print("0x");
      Serial.print(r, HEX);
      Serial.print(' ');
      index++;
    }
  }
  Serial.println();
  delay(5000);
}

with this wiring

and from what I've seen on line (check that voltage is suitable for your module)