NPK sensor 7 in 1 and arduino

Hello, I'm following this tutorial Tutorial to interface a NPK sensor 7 in 1 with my Arduino, i pretty much sure that my wiring is correct, i follow the schematic in the tutorial and verify many time so i guess some issue on my code.

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

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

// Modbus RTU requests for reading NPK values
const byte nitro[] = {0x01,0x03, 0x00, 0x1E, 0x00, 0x01, 0xE4, 0x0C};


// A variable used to store NPK values
byte values[11];

// Sets up a new SoftwareSerial object
// Digital pins 10 and 11 should be used with a Mega or Mega 2560
SoftwareSerial mod(2, 3);
//SoftwareSerial mod(10, 11);
 
void setup() {
  // Set the baud rate for the Serial port
  Serial.begin(9600);

  // Set the baud rate for the SerialSoftware object
  mod.begin(9600);

  // Define pin modes for RE and DE
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  
  delay(500);
}
 
void loop() {
  // Read values
  byte val1;
  val1 = nitrogen();
  delay(250);
 

  // Print values to the serial monitor
  // Serial.print("Nitrogen: ");
  Serial.print(val1);
 
  
  delay(2000);
}
 
byte nitrogen(){
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(10);
  if(mod.write(nitro,sizeof(nitro))==8){
    digitalWrite(DE,LOW);
    digitalWrite(RE,LOW);
    for(byte i=0;i<7;i++){
    // Serial.print(mod.read(),HEX);
    values[i] = mod.read();
    Serial.print(values[i],HEX);
    }
    Serial.println();
  }
  return values[1];
}

I simplify the code in order to read only nitrogen, the value i get print out is always 255 .... something is wrong but cant find what.. any suggestion... i don't know where to start look into.


 

Can you describe "the issue", please?

My serial print out is 255FFFFFF and the value never change .. actually I really don’t know what is wrong.
I got the data sheet from the seller but very hard to understand.
威盟士五插针土壤四参数变送器(485型).pdf (833.0 KB)

I don’t know if I’m asking the correct byte to the 485.
Thanks a lot

Sounds like your sensor isn't responding at all. Can you provide a drawing of your connections between the Arduino, RS485 module and your sensor.

Note that is a flaw in the way the serial port comms with the sensor is handled.

I attach drawing of the connections, the difference from the tutorial is that i connect a 9V battery instead a 12v power supply.
But i guess that is not the reason of the fail...

thanks a lot

Arduino-Wiring-Soil-NPK-Sensor

9V batteries, as used in smoke alarms, are useless. Avoid them.

What does your sensor datasheet say about the DC supply range?

Actually say 5-30V so I guess my 9V should be ok.. sorry I’m not so expert in electronic.

Ok, let's try something really basic. Load the sketch below onto your UNO and run it.

// This attempt uses the SoftwareSerial & raw Modbus packets.
//
// RS485 module wired up as:
// RS485 DI signal to pin 3
// RS485 RO signal to pin 2
// RS485 RE signal to pin 8
// RS485 DE signal to pin 7
// RS485 VCC to 5V
// RS485 GND to GND
//
#include <SoftwareSerial.h>

#define RE 8
#define DE 7

const uint32_t TIMEOUT = 500UL;

// canned message to your RS485 device
// change this for any other canned modbus message you like
// remember to make sure that the checksum is correct!
uint8_t msg[] = {0x01, 0x03, 0x00, 0x1E, 0x00, 0x01, 0xE4, 0x0C};
uint8_t rxByte;

SoftwareSerial swSerial(2, 3); // Receive (data in) pin, Transmit (data out) pin

void setup() {
  Serial.begin(9600);
  swSerial.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay(1000);
}

void loop() {
  uint32_t startTime = 0;

  Serial.print("TX: ");
  printHexMessage( msg, sizeof(msg) );

  // send the command
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay( 10 );
  swSerial.write( msg, sizeof(msg) );
  swSerial.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  Serial.print("RX: ");
  
  // read any data received and print it out
  startTime = millis();
  while ( millis() - startTime <= TIMEOUT ) {
    if (swSerial.available()) {
      printHexByte(swSerial.read());
    }
  }
  Serial.println();
  delay(2000);
}

void printHexMessage( uint8_t values[], uint8_t sz ) {
  for (uint8_t i = 0; i < sz; i++) {
    printHexByte( values[i] );
  }
  Serial.println();
}

void printHexByte(byte b)
{
  Serial.print((b >> 4) & 0xF, HEX);
  Serial.print(b & 0xF, HEX);
  Serial.print(' ');
}

If you have wired up your sensor as you have shown in that picture in post #5, then you should see some numbers being printed out on the serial monitor. There should be numbers on the row marked "TX:". If the sensor is working and it is wired up as per that picture, then there should also be some numbers printed on the row marked "RX:".

You should be able to cut & paste a few lines of the Serial Monitor output into a reply so we can see what the response message is.

Thanks a lot, I’ll try in 1 days, I’m out for work.. appreciate your help..
let you know.

thanks :blush:

Hello, i tried your code, and here the printout:

RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 
RX: 
TX: 01 03 00 1E 00 01 E4 0C 

so my be the sensor or the power supply not working correct..

Check your connections to the sensor. If you are sure that they are correct, the look for an alternative power supply instead of that battery.

I did some trial and actually I change this code:

Serial.begin(4800);
// Set the baud rate for the SerialSoftware object
mod.begin(4800);

printOut:

13200B844
132667FAE
13200B844
Nitrogen: 0 mg/kg
Phosphorous: 103 mg/kg
Potassium: 0 mg/kg

at least print out some value...
i still don't know why Nitrogen and Potassium are always 0 ...but at least a step forward.

now i need to understand (since I'm a beginner why the bound rate is important)

The 1st and 3rd messages appear to be valid Modbus messages - i.e. the CRC16 checksum is correct. If I insert the missing leading zeros, I get

01 03 02 00 00 B8 44

I can't figure out the 2nd message.
It could be 01 03 02 06 06 7F AE, but the checksum in the last bytes should be 3B E6.
It could be 01 03 02 06 67 0F AE, but the checksum in the last bytes should be FA 0E.

Try printing out the received bytes as a 2 digit hex number (i.e. with leading zeros). See my printHexByte routine in post #8.

Changing the Serial.begin baud rate shouldn't change anything.

The mod.begin baud rate needs to match the expected baud rate of the sensor. The common one for the NPK sensor seems to by 9600, but I believe that on some versions of the sensor, you can change it.


I tried doing it but I am facing still the same issue, Can someone please help!

I can see from your screenshot that you are using what looks like my NPK demo/debug code and that the sensor isn't responding at all.

Let's start with some basic details:

  • Which Arduino are you using - maybe an UNO?
  • Which RS485 module are you using?
  • Which sensor (assuming it's an NPK variant) are you using?
  • How have you wired the various elements of your design together?
  • How are you powering your design?

And most importantly, do you have a user guide / manual for your sensor?

I am using 7 in1 sensor but was testing three parameters initially only.

this is my circuit diagram:

but i only get 255 for all parameters. Can you please help. Its urgent I will be grateful to you.

Do you have one? Can you provide a link to it?

If you don't have a guide / manual, then show us a photo of the label on your sensor as that may allow us to figure out which 7-in-1 sensor you have.

1618630499780472.pdf (514.9 KB)
I found this manual online

If you are sure that is the manual for your device, then let's have a look.

In your screenshot (yuk!) of your code, the canned modbus message you appear to be using is this:

uint8_t msg[] = {0x01, 0x03, 0x00, 0x87, 0x0E, 0x0E, 0x34, 0x37};

Where did you get that message from? There's a whole bunch wrong with it!

The main issue that will stop your sensor responding is that the CRC16 checksum in the last 2 bytes is wrong. Assuming all other parameters are correct (they aren't) , this alone will prevent your sensor from responding.

In order to gain some confidence in your NPK sensor, I would suggest trying to read the temperature as it's likely the only parameter you will be able to quickly see is making sense.

Assuming 9600 baud and a device address of 01 and the user manual you provided is correct, then the array should hold the values:

uint8_t msg[] = {0x01, 0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xCF};

Try that and see if you get a response from your sensor.

You should also have a connection between the GND of your Arduino and the GND of your sensor.

thank you so much for your response, will try this.