Measure pH, conductivity, temperature, humidity, nitrogen, phosphorus, and potassium using the JXBS-3001-RS485- SOIL SENSOR

Hello, the code below allows you to measure pH, conductivity, temperature, humidity, nitrogen, phosphorus, and potassium using the JXBS-3001-RS485-SOIL SENSOR. On the serial monitor, all the values are null. I would need your help to display the real values, thank you.

#include <SoftwareSerial.h>

#define RE 7
#define DE 6

const uint32_t TIMEOUT = 1500UL;  // Timeout à 1.5s
const uint32_t INTERVAL = 10000UL; // Intervalle de 10s entre mesures

// Commandes Modbus
const byte MOISTURE[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
const byte TEMPERATURE[] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA};
const byte EC[] = {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA};
const byte PH[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};
const byte NITROGEN[] = {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB};
const byte PHOSPHORUS[] = {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B};
const byte POTASSIUM[] = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B};

SoftwareSerial mod(2, 3);  // RX=2, TX=3
uint8_t currentSensor = 0;  // 0:Humidité, 1:Temp, 2:EC, 3:pH, 4:N, 5:P, 6:K

// Déclaration anticipée des fonctions
int16_t readSensor(const byte *command, byte commandSize);
void printSensorData(const char* name, const byte* command, byte size, const char* unit, float factor, bool isSigned = false);

void setup() {
  Serial.begin(4800);
  mod.begin(4800);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  digitalWrite(RE, LOW);
  digitalWrite(DE, LOW);
  Serial.println("Système prêt. Début des mesures...");
}

void loop() {
  switch (currentSensor) {
    case 0: // Humidité
      printSensorData("Humidité", MOISTURE, sizeof(MOISTURE), "%", 0.1f);
      break;
    case 1: // Température
      printSensorData("Température", TEMPERATURE, sizeof(TEMPERATURE), "°C", 0.1f, true);
      break;
    case 2: // Conductivité
      printSensorData("Conductivité", EC, sizeof(EC), "µS/cm", 1.0f);
      break;
    case 3: // pH
      printSensorData("pH", PH, sizeof(PH), "", 0.1f);
      break;
    case 4: // Azote (N)
      printSensorData("Azote (N)", NITROGEN, sizeof(NITROGEN), "mg/kg", 1.0f);
      break;
    case 5: // Phosphore (P)
      printSensorData("Phosphore (P)", PHOSPHORUS, sizeof(PHOSPHORUS), "mg/kg", 1.0f);
      break;
    case 6: // Potassium (K)
      printSensorData("Potassium (K)", POTASSIUM, sizeof(POTASSIUM), "mg/kg", 1.0f);
      break;
  }

  currentSensor = (currentSensor + 1) % 7; // Cycle entre 0 et 6
  delay(INTERVAL);
}

// Fonction générique pour lire et afficher un capteur
void printSensorData(const char* name, const byte* command, byte size, const char* unit, float factor, bool isSigned) {
  Serial.print(name); Serial.print(": ");
  int16_t rawValue = readSensor(command, size);
  float value = isSigned ? (int16_t)rawValue * factor : rawValue * factor;
  Serial.print(value); Serial.println(unit);
  Serial.println("-----");
}

// Fonction de lecture générique
int16_t readSensor(const byte *command, byte commandSize) {
  uint8_t response[11];
  memset(response, 0, sizeof(response));

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  mod.write(command, commandSize);
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  uint32_t startTime = millis();
  uint8_t byteCount = 0;
  while (millis() - startTime <= TIMEOUT && byteCount < 11) {
    if (mod.available()) {
      response[byteCount++] = mod.read();
    }
  }

  if (byteCount >= 5) {
    return (int16_t)(response[3] << 8 | response[4]);
  }
  return 0;
}

As your topic does not relate directly to the installation or operation of the IDE it has been moved to the Programming category of the forum

Please do not double post (Mesurer le ph, la conductivité,la température, l'humidité, l'azote,le phosphore,le potatium a l'aide du JXBS-3001-RS485- SOIL SENSOR which was in the wrong category as well and moved/closed here)

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum. It will help you get the best out of the forum in the future.

Thank you.

Hello kossigan1999

Are you sure you're receiving anything from your sensor?

Add a Serial.println in readSensor

A part of readSensor:

while (millis() - startTime <= TIMEOUT && byteCount < 11) {
if (mod.available()) {
response[byteCount++] = mod.read();
}
}

Serial.println("Bytes received: " + String(byteCount));

if (byteCount >= 5) {
return (int16_t)(response[3] << 8 | response[4]);
}
return 0;
}

A+
Cordialement,
jpbbricole

Those sensors are misrepresented by the sellers, and don't measure nitrogen, phosphorus or potassium.

That is impossible with metal probes.

1 Like

Yep , I can’t see how they can work . Getting that info seems complex and doesn’t seem to have a method involving a probe

Soil etc

Bonjour je l’ai fais et voici ce que xa

affiche

@kossigan1999

Your other topics (was it 3 more? I lost count) on the same subject deleted.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

1 Like

please use English in the English speaking section.


You don't seem to get any data from your sensor, but as other have said, these sensors are crap and you won't get any precise information anyway. So you probably should not spend too much time trying to fix that...

One likely mistake is that the JXBS-3001-RS485-SOIL SENSOR is possibly using 9600 bauds and not 4800.

It is in principle possible to make an electrochemical probe using ion-selective electrodes, but most commercially available "NPK" probes for the consumer market do not use such technology, and likely just extrapolate nutrient concentrations based on nonspecific electrical conductivity readings:

https://www.mdpi.com/1424-8220/22/23/9288

Hi kossigan1999

Are you sure your sensor speed is 4800?
According to the documentation, the default speed is 9600.

Which is impossible job. And these sensors are not built to even try to sense NPK. Often they are sold for that though...

The instructions for these NPK kits include a statement paraphrasing,

... before using this device, conduct a full, scientific analysis of the soil under test, then use those results to calibrate the NPK...

It's a "service oil" indicator when changes occur to known soil content.