NPK_pH_T_H_C sensor with arduino Uno

t#include <AltSoftSerial.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#define BMP280_ADDRESS 0x76
Adafruit_BMP280 bmp;
int rs=2;
int en=3;
int D04=4;
int D05=5;
int D06=6;
int D07=7;
LiquidCrystal lcd(rs,en,D04,D05,D06,D07);

// RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 11
#define DE 10

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 soil_ph[] =        {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0a};
const byte soil_moist[] =     {0x01, 0x03, 0x00, 0x12, 0x00, 0x01, 0x24, 0x0f};
const byte temp_humid[] =     {0x01, 0x03, 0x00, 0x12, 0x00, 0x02, 0x64, 0x0e};

byte values[11];
AltSoftSerial mod;

void setup() {
  Serial.begin(4800);
  mod.begin(4800);
  lcd.begin(16,2);
  lcd.print("Initializing...");
  delay(1000);
  lcd.clear();
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  delay( 1000 );
  while ( !Serial ) delay(100);   // wait for native usb
  Serial.println(F("BMP280 test"));
  unsigned status;
  status = bmp.begin(BMP280_ADDRESS);
  if (!status) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
                      "try a different address!"));
    Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);
    Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
    Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
    Serial.print("        ID of 0x60 represents a BME 280.\n");
    Serial.print("        ID of 0x61 represents a BME 680.\n");
    while (1) delay(10);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
}

void loop() {
  lcd.clear();
  byte val1, val2, val3, val4, val5;
  Serial.print("   Nitrogen: ");
  val1 = nitrogen();
  Serial.print(" = ");
  Serial.print(val1);
  Serial.println(" mg/kg");
  
  Serial.print("Phosphorous: ");
  val2 = phosphorous();
  Serial.print(" = ");
  Serial.print(val2);
  Serial.println(" mg/kg");
  
  Serial.print("  Potassium: ");
  val3 = potassium();
  Serial.print(" = ");
  Serial.print(val3);
  Serial.println(" mg/kg");

  Serial.print("  PH: ");
  val4 = ph();
  Serial.print(" = ");
  Serial.print(val4);
  Serial.println();

  Serial.print("  Moisture: ");
  val5 = moisture();
  Serial.print(" = ");
  Serial.print(val5);
  Serial.println(" %");

  Serial.print(F("Temperature = "));
  Serial.print(bmp.readTemperature());
  Serial.println(" *C");

  Serial.print(F("Pressure = "));
  Serial.print(bmp.readPressure());
  Serial.println(" Pa");

  Serial.print(F("Approx altitude = "));
  Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
  Serial.println(" m");

  
  
  Serial.println();
  lcd.setCursor(0,0);
  lcd.print("N:");
  lcd.print(val1);
  lcd.setCursor(6,0);
  lcd.print("P:");
  lcd.print(val2);
  lcd.setCursor(11,0);
  lcd.print("K:");
  lcd.print(val3);
  lcd.setCursor(0,1);
  lcd.print("pH:");
  lcd.print(val4);
  lcd.setCursor(4,1);
  lcd.print(" M%:");
  lcd.print(val5);
  lcd.setCursor(10,1);
  lcd.print(" *C:");
  lcd.print(bmp.readTemperature());
  delay(2000);
}

byte moisture() {
  // clear the receive buffer
  mod.flushInput();

  // switch RS-485 to transmit mode
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);

  // write out the message
  for (uint8_t i = 0; i < sizeof(soil_moist); i++ ) mod.write( soil_moist[i] );

  // wait for the transmission to complete
  mod.flush();
  
  // switch RS-485 to receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  // crude delay to allow response bytes to be received!
  delay(100);

  // 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 ph() {
  // clear the receive buffer
  mod.flushInput();

  // switch RS-485 to transmit mode
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);

  // write out the message
  for (uint8_t i = 0; i < sizeof(soil_ph); i++ ) mod.write( soil_ph[i] );

  // wait for the transmission to complete
  mod.flush();
  
  // switch RS-485 to receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  // crude delay to allow response bytes to be received!
  delay(100);

  // 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(10);

  // 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();
  
  // switch RS-485 to receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  // crude delay to allow response bytes to be received!
  delay(100);

  // 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(10);
  for (uint8_t i = 0; i < sizeof(phos); i++ ) mod.write( phos[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(100);
  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(10);
  for (uint8_t i = 0; i < sizeof(pota); i++ ) mod.write( pota[i] );
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(100);
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    Serial.print(values[i], HEX);
    Serial.print(' ');
  }
  return values[4];
}ype or paste code here

so i have been trying to read values from my sensor and i have tried using the modbus request i have seen from this forum as well as from the manufacturer's manual but seems i am not getting solution

@markd833 have seen you being quite helpful on this one can you assist me?

image
these are the results obtained using this code ,

if i used the modbus request from the manual;

const byte phos[] =           {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0b};
const byte pota[] =           {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};

i get constant readings of 88 and 104 respectively

Can you post a link to your manual that shows the registers used and the scaling of the reported values?

As a first go, thinks are looking pretty good for you compared to the results from other forum members and their attempts with an NPK sensor.

It looks like you have the correct device address and the correct baud rate as you are getting valid responses back from the sensor. Whether those values are sensible or not is not something i'm not experienced enough to comment on.

As it stands, clearly the pH and moisture values are wrong.

Now, pH could be being reported to 1 decimal place which would mean that the pH is really 3.0 (instead of 30).

As for moisture, the value being reported back is actually 0x05E5 = 1509 decimal. Remember that the values coming back from the sensor are actually 16-bit values so you need to convert 2x 8-bit numbers into one 16-bit number. Maybe the moisture is being reported to 2 decimal places, so the sensor could be telling you that the moisture is 15.09%.

However, I wonder if the register you are requesting is actually the one that holds the moisture reading. The user manual should detail this.

Once you get the correct registers figured out, I would recommend you switch to a proper Modbus library as it will take care of all the data transmission, reception, validation and reporting for you.

seems i am a new comer here i cant send an attachment but here are the screenshots from the manual



but then i requested through the email and they gave me these registers

const byte pota[] =           {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};
const byte phos[] =           {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0b};


which gave the constant response

The canned Modbus message bytes they gave you look good. I'm somewhat surprised that when you ask for those 2 specific parameters, you get back exactly the same values that are shown in the example from page 5 of the manual.

You can calculate the required byte values to retrieve the register values individually using those arrays at the start of the code, or you can switch to a Modbus library and ask for all of them together like the example does on pages 4 & 5.

I wonder what the sensor is sending back when you use the other canned messages for nitrogen, phosphate, potassium and soil moisture (or temperature/humidity) as it would seem that those addresses are not used.

I can calculate the values for your byte arrays for each individual parameter if you wish to try and retrieve the readings individually.

i am not really good at calculating the bytes since i am kinda new to this

when used other canned messages, i either get zeros or specific constants or 255s

To ask your sensor for just temperature, then you need a byte array like this:

const byte tempC[] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA};

That should ask the sensor for the contents of register 1, which should hopefully be temperature looking at the documentation on pages 4 and 5.

Try that and see if it gives a sensible answer.

If it does, then maybe switch over to a proper Modbus library and let it do the hard work for you.

for the 5 parameters i can say its working quite well, the issue is only on the potasium and phosphorus

and about the modbus libray how does it work exactly, how do i do that?
(supposedly it extract the content of registers that i want?)

#include <ModbusMaster.h>
#include <AltSoftSerial.h>

#define NITROGEN_ADDR   0x1e
#define PHOSPHORUS_ADDR 0x1f
#define POTASSIUM_ADDR  0x20

#define MAX485_DE      10
#define MAX485_RE_NEG  11

AltSoftSerial swSerial;
ModbusMaster node;

// Put the MAX485 into transmit mode
void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

// Put the MAX485 into receive mode
void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

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

  // configure the MAX485 RE & DE control signals and enable receive mode
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Modbus communication runs at 9600 baud
  swSerial.begin(4800);

  // Modbus slave ID of NPK sensor is 1
  node.begin(1, swSerial);

  // Callbacks to allow us to set the RS485 Tx/Rx direction
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;

  // NITROGEN
  result = node.readHoldingRegisters(NITROGEN_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("   Nitrogen: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }

  // PHOSPHORUS
  result = node.readHoldingRegisters(PHOSPHORUS_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("Phosphorous: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }

  // POTASSIUM
  result = node.readHoldingRegisters(POTASSIUM_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("  Potassium: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }
  Serial.println();
  delay(2000);
}

// print out the error received from the Modbus library
void printModbusError( uint8_t errNum )
{
  switch ( errNum ) {
    case node.ku8MBSuccess:
      Serial.println(F("Success"));
      break;
    case node.ku8MBIllegalFunction:
      Serial.println(F("Illegal Function Exception"));
      break;
    case node.ku8MBIllegalDataAddress:
      Serial.println(F("Illegal Data Address Exception"));
      break;
    case node.ku8MBIllegalDataValue:
      Serial.println(F("Illegal Data Value Exception"));
      break;
    case node.ku8MBSlaveDeviceFailure:
      Serial.println(F("Slave Device Failure"));
      break;
    case node.ku8MBInvalidSlaveID:
      Serial.println(F("Invalid Slave ID"));
      break;
    case node.ku8MBInvalidFunction:
      Serial.println(F("Invalid Function"));
      break;
    case node.ku8MBResponseTimedOut:
      Serial.println(F("Response Timed Out"));
      break;
    case node.ku8MBInvalidCRC:
      Serial.println(F("Invalid CRC"));
      break;
    default:
      Serial.println(F("Unknown Error"));
      break;
  }
}

i as well used this code which i seen from another discussion you had, and its working perfectly except for P and K in this case it gives 0 mg/kg which if i changed to the one similar to that in manual i then get constants like i said
lets say for P if i use 0x05 i get 88mg/kg
k if i use 0x06 i get 104mg/kg
and even for nitrogen i then 0x04 i get 32mg/kg

That code should be a good starting point for your NPK project.

Looking at the user manual, your NPK parameter register addresses should be:

#define HUMIDITY_ADDR     0x00
#define TEMPERATURE_ADDR  0x01
#define CONDUCTIVITY_ADDR 0x02
#define PH_ADDR           0x03
#define NITROGEN_ADDR     0x04
#define PHOSPHORUS_ADDR   0x05
#define POTASSIUM_ADDR    0x06

Now you are using the Modbus library, you can ask for all the parameters at once if you wish. If you had a single readHoldingRegisters like this:

result = node.readHoldingRegisters(HUMIDITY_ADDR, 7);

That should generate the same Modbus query that is shown at the bottom of page 4.

To read the values returned by the sensor, you would have a bit of code like this:

humidity = node.getResponseBuffer(0x0));     // divide by 10 for actual value
temperature = node.getResponseBuffer(0x1));  // divide by 10 for actual value
conductivity = node.getResponseBuffer(0x2));
pH = node.getResponseBuffer(0x3));           // divide by 10 for actual value
nitrogen = node.getResponseBuffer(0x4));
phosphorus = node.getResponseBuffer(0x5));
potassium = node.getResponseBuffer(0x6));

this is what i am getting from the code above zhich seems to be the modbus request for those specific constant values

my question now is is there a way i can extract or calculate the modbus request address like this on right below

const byte nitro[] =          {0x01, 0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] =           {0x01, 0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};

because the only problem i am left with is for potasium and phosphorus , i guess for nitrogen i was lucky the one circulating seems to be a universal one
which extract readings from the sensor

Posting a screenshot of part of your code is not a good idea. Please post the actual code.

I'm not sure what you are asking. If you are wanting to query your sensor for registers 0x001E and 0x001F using the readHoldingRegister() function call, then the start register you would pass would be 0x001E and you would indicate that you wanted 2 registers.

What's wrong with the output you are currently getting on the serial monitor? Temperature and pH are obviously out by a factor of 10.

Are the N, P & K values not correct / what you expected?

Why do you think that accessing an undocumented register would give you the parameter you are looking for?

ok let me explain my problem quite clearly.

the problem i am having is i used the code in post #1 and then the readings i obtained for nitrogen, ph, conductivity and humidity are convincing correct but as for phosphorus and potassium are giving zeros
But then when i change the addresses to the ones in the manual, i then obtain constant values for every reading and supposingly the addresses are requesting for these constant responds

so now i am trying to figure out a way i could find registers for requesting the readings of potasium and phosphorus the actual values being read by the sensor

and about screenshot, it was to show only the results on the serial monitor using the same code you provided but ok here is the code

#include <ModbusMaster.h>
#include <AltSoftSerial.h>


#define HUMIDITY_ADDR     0x00
#define TEMPERATURE_ADDR  0x01
#define CONDUCTIVITY_ADDR 0x02
#define PH_ADDR           0x03
#define NITROGEN_ADDR     0x04
#define PHOSPHORUS_ADDR   0x05
#define POTASSIUM_ADDR    0x06

#define MAX485_DE      10
#define MAX485_RE_NEG  11

AltSoftSerial swSerial;
ModbusMaster node;

// Put the MAX485 into transmit mode
void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

// Put the MAX485 into receive mode
void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

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

  // configure the MAX485 RE & DE control signals and enable receive mode
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Modbus communication runs at 9600 baud
  swSerial.begin(4800);

  // Modbus slave ID of NPK sensor is 1
  node.begin(1, swSerial);

  // Callbacks to allow us to set the RS485 Tx/Rx direction
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;

  // NITROGEN
  result = node.readHoldingRegisters(NITROGEN_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("   Nitrogen: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }

  // PHOSPHORUS
  result = node.readHoldingRegisters(PHOSPHORUS_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("Phosphorous: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }

  // POTASSIUM
  result = node.readHoldingRegisters(POTASSIUM_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("  Potassium: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" mg/kg");
  } else {
    printModbusError( result );
  }
   result = node.readHoldingRegisters(HUMIDITY_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("   humidity: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" %");
  } else {
    printModbusError( result );
  }
   result = node.readHoldingRegisters(TEMPERATURE_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("   temperature: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println("*C");
  } else {
    printModbusError( result );
  }
   result = node.readHoldingRegisters(CONDUCTIVITY_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("  Conductivity: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" us/cm");
  } else {
    printModbusError( result );
  }
   result = node.readHoldingRegisters(PH_ADDR, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("   pH: ");
    Serial.print(node.getResponseBuffer(0x0));
    Serial.println(" ");
  } else {
    printModbusError( result );
  }
  Serial.println();
  delay(2000);
}

// print out the error received from the Modbus library
void printModbusError( uint8_t errNum )
{
  switch ( errNum ) {
    case node.ku8MBSuccess:
      Serial.println(F("Success"));
      break;
    case node.ku8MBIllegalFunction:
      Serial.println(F("Illegal Function Exception"));
      break;
    case node.ku8MBIllegalDataAddress:
      Serial.println(F("Illegal Data Address Exception"));
      break;
    case node.ku8MBIllegalDataValue:
      Serial.println(F("Illegal Data Value Exception"));
      break;
    case node.ku8MBSlaveDeviceFailure:
      Serial.println(F("Slave Device Failure"));
      break;
    case node.ku8MBInvalidSlaveID:
      Serial.println(F("Invalid Slave ID"));
      break;
    case node.ku8MBInvalidFunction:
      Serial.println(F("Invalid Function"));
      break;
    case node.ku8MBResponseTimedOut:
      Serial.println(F("Response Timed Out"));
      break;
    case node.ku8MBInvalidCRC:
      Serial.println(F("Invalid CRC"));
      break;
    default:
      Serial.println(F("Unknown Error"));
      break;
  }
}

image

Ah, right, so what you are saying - and apologies if i'm simply repeating your words, but i'm just trying to get it straight in my head:

You are getting what you believe to be sensible / correct readings when you use register addresses that are DIFFERENT to those supplied in the user manual.

But when you use the register addresses from the supplied manual you get fixed values. Presumably those fixed values bear no relation to the actual values you were expecting.

It does sound like you have been given the wrong user manual for the NPK sensor you have.

Some user manuals I have seen posted here have all the registers consecutively starting at register address 0. Some have N, P & K at register addresses 1E, 1F & 20.

Some NPK sensor user manuals detail the addresses for loading calibration values in, whilst others do not. It may be that all the sensors do support the updating of calibration values, but they don't want to disclose it as mucking about with those registers will result in incorrect readings being reported and sensors being returned.

Is there any way you can check that you really do have the correct user manual for your NPK sensor?

exactly , thats the issue now when i tried 1 f and 20 for P and K , i get zeros but for N its working well

let me send you the manual maybe you might understand way better
CWT soil sensor_2 manual.zip (4.7 MB)

i am using a 5pin sensor

I wouldn't normally download a zip file, but in this case I happened to have a virtual PC running. If you have the 5 pin sensor, then it's interesting that you are getting readings from an undocumented register address, but fixed values from the documented address.

The zip file also contains the PC program you can run. Assuming you have an RS485-USB dongle (a very useful and cheap bit of kit when playing with RS485), you could run that program and see what values it reports back.

If that PC program reports back sensible values, then we can figure out what registers it is querying. A quick look at the help guide for the program shows that it also displays the raw Modbus messages - which is very handy.

i am not sure how to use that one but surely i will try it out and show you some results because lately i tried using it while connected to the arduino but it gave me funny results as in it


this whats coming out after the NPK reset click...supposingly thats a request

and then


for potassium and phosphorus respectively

but i guess its getting distorted sincee i am not connecting directly to the pc

Well that's interesting.

Looking at the data bytes in the first image, the first 3 TX messages are writing FFFF to registers 0004, 0005 & 0006 - those are the N, P & K registers.

The 4th TX message that begins 01 10 .... is a Write Multiple Registers command and is writing to 4 consecutive registers starting with register 04E8. The datasheet says these registers are associated with the Nitrogen reading.

The 5th TX message is writing the value 0000 to register 04EA which is the Nitrogen offset.

The 6th TX message that begins 01 10 .... is a Write Multiple Registers command and is writing to 4 consecutive registers starting with register 04F2. The datasheet says these registers are associated with the Phosphorus reading.

There are more messages in the log window judging by the scroll bar.

I guess they are the sorts of message to be expected when the user clicks the Reset NPK button as it seems to setting some internal registers back to known default values.

What values do you see if you select the various parameters in the drop down list that says 1.Humidity and then click the Read button further down? I would expect the sensor to report back the selected reading as well as displaying the raw message in the log window.

well in the case if i tape read on either, it doesnt give back any value but the TX :............ like the ones i showed for phosphorus and potassium i sent int the above picture

so my assumption is maybe its because i wasn't connected directly to the rs485 , i dont know

I would query this with the place where you bought the sensor. If the code that was provided doesn't work with the sensor provided, then something is clearly amiss and it should be down to them to sort it out for you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.