Cwt-soil npk sensor in nodemcu not work

I am developing a project for soil monitoring for plants.
I'm using NodeMCU, RS485 expansion base for MAX495, below is the assembly diagram
image

I asked the sensor manufacturer if they had a code to send me for the 7 in 1 sensor, this code was given to me:

#include <SoftwareSerial.h>

// RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 4
#define DE 3

// const byte temp[] = {0x02,0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xcf};//
const byte temp[] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA};//
// const byte mois[]  = {0x02,0x03,0x00,0x12,0x00,0x01,0x24,0x0F};
const byte mois[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
// const byte econ[] = {0x02,0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xce};
const byte econ[] = {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA};
// const byte ph[] = {0x02,0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};//0x0B64
const byte ph[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};//0x0B64

const byte nitro[] = {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB};
const byte phos[] = {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B};
const byte pota[] = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B};

byte values[11];
SoftwareSerial mod(6,5);

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;

unsigned long delayOneK = 1000;
unsigned long pastTime = millis();
int state = 0;

void setup() {

  Serial.begin(9600);
  mod.begin(9600);

  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  // put RS-485 into receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(3000);
}


void loop() {

switch ( state )
  {
    case 0:
      if ( (millis() - pastTime ) >= delayOneK )
      {
        val1 = moisture();
        soil_mois = val1 / 10.0;
        state = 1;
        Serial.print("Moisture: "); Serial.print(soil_mois); Serial.println(" %");
        pastTime = millis();
      }
      break;
    case 1:
      if ( (millis() - pastTime) >= delayOneK )
      {
        soil_temp = temperature() / 10.0;
        Serial.print("Temperature: "); Serial.print(soil_temp); Serial.println(" C");
        pastTime = millis();
        state = 2;
      }
      break;
    case 2:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val3 = econduc();
        Serial.print("EC: "); Serial.print(val3); Serial.println(" us/cm");
        pastTime = millis();
        state = 3;
      }
      break;
    case 3:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val4 = phydrogen() / 10;
        soil_ph = val4;
        Serial.print("ph: "); Serial.print(soil_ph); Serial.println(" ph");
        pastTime = millis();
        state = 4;
      }
      break;
    case 4:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val5 = nitrogen();
        Serial.print("Nitrogen: "); Serial.print(val5); Serial.println(" mg/kg");
        pastTime = millis();
        state = 5;
      }
      break;
    case 5:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val6 = phosphorous();
        Serial.print("Phosphorous: "); Serial.print(val6); Serial.println(" mg/kg");
        state = 6;
        pastTime = millis();
      }
      break;
    case 6:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val7 = potassium();
        Serial.print("Potassium: "); Serial.print(val7); Serial.println(" mg/kg");
        state = 7;
        pastTime = millis();
      }
      break;
    default:
      // state = 0;
      break;
  }

  // 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(" %");
  // Serial.print("Temperature: ");Serial.print(soil_temp);Serial.println(" C");
  // Serial.print("EC: ");Serial.print(val3);Serial.println(" us/cm");
  // Serial.print("ph: ");Serial.print(soil_ph);Serial.println(" ph");
  // Serial.print("Nitrogen: "); Serial.print(val5);Serial.println(" mg/kg");
  // Serial.print("Phosphorous: ");Serial.print(val6);Serial.println(" mg/kg");
  // 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(1000);

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

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

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

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

  // 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(1000);
  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(1000);
  for (byte i = 0; i < 7; i++) {
    values[i] = mod.read();
    // Serial.print(values[i], HEX);
    // Serial.print(' ');
  }
  return values[4];
}

However, it is giving 255 in all variables, someone help me
image

This is a 3.3v device, is your converter compatible??

and yeah, this code is not proper either..

~q

Thanks for properly posting the code but sorry, that picture is not readable.
Please translate it using pen and paper showing all pin names. Links to the datasheet of the boards, please.
There's no powering in the picture. Reading 255 is then magic. USB?

try this..

#include <SoftwareSerial.h>

// RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 4
#define DE 3
/*
  // const byte temp[] = {0x02,0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xcf};//
  const byte temp[] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA};//
  // const byte mois[]  = {0x02,0x03,0x00,0x12,0x00,0x01,0x24,0x0F};
  const byte mois[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
  // const byte econ[] = {0x02,0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xce};
  const byte econ[] = {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA};
  // const byte ph[] = {0x02,0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};//0x0B64
  const byte ph[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};//0x0B64

  const byte nitro[] = {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB};
  const byte phos[] = {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B};
  const byte pota[] = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B};
*/


const uint32_t TIMEOUT = 500UL;

const byte sensorVals[7][8] = {
  {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A},//moist
  {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA},//temp
  {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA},//econ
  {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A},//ph
  {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB},//nitro
  {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B},//phos
  {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B}//pota
};

//byte values[11];
SoftwareSerial mod(6, 5);

float envhumidity = 0.0, envtemperature = 0.0, soil_ph = 0.0, soil_mois = 0.0, soil_temp = 0.0;
uint16_t val1 = 0, val2 = 0, val3 = 0, val4 = 0, val5 = 0, val6 = 0, val7 = 0;

unsigned long delayOneK = 1000;
unsigned long pastTime = millis();
int state = 0;

void setup() {

  Serial.begin(9600);
  mod.begin(9600);

  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  // put RS-485 into receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay(3000);
}


void loop() {

  switch ( state )
  {
    case 0:
      if ( (millis() - pastTime ) >= delayOneK )
      {
        val1 = GetValue(state);
        soil_mois = val1 / 10.0;
        state = 1;
        Serial.print("Moisture: "); Serial.print(soil_mois); Serial.println(" %");
        pastTime = millis();
      }
      break;
    case 1:
      if ( (millis() - pastTime) >= delayOneK )
      {
        soil_temp = GetValue(state) / 10.0;
        Serial.print("Temperature: "); Serial.print(soil_temp); Serial.println(" C");
        pastTime = millis();
        state = 2;
      }
      break;
    case 2:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val3 = GetValue(state);
        Serial.print("EC: "); Serial.print(val3); Serial.println(" us/cm");
        pastTime = millis();
        state = 3;
      }
      break;
    case 3:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val4 = GetValue(state) / 10;
        soil_ph = val4;
        Serial.print("ph: "); Serial.print(soil_ph); Serial.println(" ph");
        pastTime = millis();
        state = 4;
      }
      break;
    case 4:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val5 = GetValue(state);
        Serial.print("Nitrogen: "); Serial.print(val5); Serial.println(" mg/kg");
        pastTime = millis();
        state = 5;
      }
      break;
    case 5:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val6 = GetValue(state);
        Serial.print("Phosphorous: "); Serial.print(val6); Serial.println(" mg/kg");
        state = 6;
        pastTime = millis();
      }
      break;
    case 6:
      if ( (millis() - pastTime) >= delayOneK )
      {
        val7 = GetValue(state);
        Serial.print("Potassium: "); Serial.print(val7); Serial.println(" mg/kg");
        state = 0;
        pastTime = millis();
      }
      break;
    default:
      // state = 0;
      break;
  }

}


uint16_t GetValue(byte val) {
  if (val > 6) return 0;
  uint32_t startTime = 0;
  uint8_t  byteCount = 0;
  byte buff[20];

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  mod.write(sensorVals[val], sizeof(sensorVals[val]));
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  startTime = millis();
  while (millis() - startTime <= TIMEOUT) {
    if (mod.available() && byteCount < sizeof(buff)) {
      buff[byteCount++] = mod.read();
      Serial.print(buff[byteCount - 1], HEX); Serial.print(":");
    }
  }
  Serial.println();
  return (int16_t)(buff[3] << 8 | buff[4]);
}

a link to the adapter your using might be needed..

good luck.. ~q

the nodemcu expander board, is 5V.
I used this video as a reference: https://www.youtube.com/watch?v=09hvB-y_rJw&t=136s

I used this video as a reference for assembling and purchasing components: https://www.youtube.com/watch?v=09hvB-y_rJw&t=136s
but I don't use the display

image

The results obtained were different, but they remain static and not real

ok, add 1 line to GetValue like this please..


uint16_t GetValue(byte val) {
  if (val > 6) return 0;
  uint32_t startTime = 0;
  uint8_t  byteCount = 0;
  byte buff[20];

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  mod.write(sensorVals[val], sizeof(sensorVals[val]));
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  startTime = millis();
  while (millis() - startTime <= TIMEOUT) {
    if (mod.available() && byteCount < sizeof(buff)) {
      buff[byteCount++] = mod.read();
      Serial.print(buff[byteCount - 1], HEX); Serial.print(":");
    }
  }
  Serial.println();
  Serial.print("Bytes Revcd: ");Serial.println(byteCount);
  return (int16_t)(buff[3] << 8 | buff[4]);
}

right above the return..

~q

was that all that was printed??

~q

one more change you can make is to sensorVals..
like this..


const byte sensorVals[7][8] = {
  {0xFF, 0x03, 0x00, 0x00, 0x00, 0x01, 0x91, 0xD4},//moist
  {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA},//temp
  {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA},//econ
  {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A},//ph
  {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB},//nitro
  {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B},//phos
  {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B}//pota
};

this will switch moisture to use the broadcast address, maybe your ID is not 1??

~q

image

you're getting no response at all..
could be incorrect id, did you try broadcast??

~q

according to the manual the id is 0x01


Unfortunately I can't upload the manual because I'm a new user.

lol, last one i help with was on id 2 from the factory, tricked us up for a bit..

change the 3 bytes in the moist array and try again..
if it's on wrong id will see it..

~q

{0xFF, 0x03, 0x00, 0x00, 0x00, 0x01, 0x91, 0xD4}//moist

like this?

yes..
the FF is ID 255 broadcast..
last 2 bytes are the checksum, which i've recalculated for you..
all sensors respond to address 255 but replace the 255 with their own when replying..
give it a go..
assuming you only have one sensor connected.. :slight_smile:
~q

image

#include <SoftwareSerial.h>

#define RE 4
#define DE 3

const uint32_t TIMEOUT = 500UL;

const byte sensorVals[7][8] = {
  {0xFF, 0x03, 0x00, 0x00, 0x00, 0x01, 0x91, 0xD4},//moist
  {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA},//temp
  {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA},//econ
  {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A},//ph
  {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB},//nitro
  {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B},//phos
  {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B}//pota
};

SoftwareSerial mod(6, 5);

float envhumidity = 0.0, envtemperature = 0.0, soil_ph = 0.0, soil_mois = 0.0, soil_temp = 0.0;
uint16_t val1 = 0, val2 = 0, val3 = 0, val4 = 0, val5 = 0, val6 = 0, val7 = 0;

unsigned long delayOneK = 1000;
unsigned long pastTime = millis();
int state = 0;

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

void loop() {
  switch (state) {
    case 0:
      if ((millis() - pastTime) >= delayOneK) {
        val1 = GetValue(state);
        soil_mois = val1 / 10.0;
        state = 1;
        Serial.print("Moisture: "); Serial.print(soil_mois); Serial.println(" %");
        pastTime = millis();
      }
      break;
    case 1:
      if ((millis() - pastTime) >= delayOneK) {
        soil_temp = GetValue(state) / 10.0;
        Serial.print("Temperature: "); Serial.print(soil_temp); Serial.println(" C");
        pastTime = millis();
        state = 2;
      }
      break;
    case 2:
      if ((millis() - pastTime) >= delayOneK) {
        val3 = GetValue(state);
        Serial.print("EC: "); Serial.print(val3); Serial.println(" us/cm");
        pastTime = millis();
        state = 3;
      }
      break;
    case 3:
      if ((millis() - pastTime) >= delayOneK) {
        val4 = GetValue(state) / 10;
        soil_ph = val4;
        Serial.print("ph: "); Serial.print(soil_ph); Serial.println(" ph");
        pastTime = millis();
        state = 4;
      }
      break;
    case 4:
      if ((millis() - pastTime) >= delayOneK) {
        val5 = GetValue(state);
        Serial.print("Nitrogen: "); Serial.print(val5); Serial.println(" mg/kg");
        pastTime = millis();
        state = 5;
      }
      break;
    case 5:
      if ((millis() - pastTime) >= delayOneK) {
        val6 = GetValue(state);
        Serial.print("Phosphorous: "); Serial.print(val6); Serial.println(" mg/kg");
        state = 6;
        pastTime = millis();
      }
      break;
    case 6:
      if ((millis() - pastTime) >= delayOneK) {
        val7 = GetValue(state);
        Serial.print("Potassium: "); Serial.print(val7); Serial.println(" mg/kg");
        state = 0;
        pastTime = millis();
      }
      break;
    default:
      break;
  }
}

uint16_t GetValue(byte val) {
  if (val > 6) return 0;
  uint32_t startTime = 0;
  uint8_t byteCount = 0;
  byte buff[20];

  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  mod.write(sensorVals[val], sizeof(sensorVals[val]));
  mod.flush();
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  startTime = millis();
  while (millis() - startTime <= TIMEOUT) {
    if (mod.available() && byteCount < sizeof(buff)) {
      buff[byteCount++] = mod.read();
      Serial.print(buff[byteCount - 1], HEX); Serial.print(":");
    }
  }
  Serial.println();
  Serial.print("Bytes Revcd: "); Serial.println(byteCount);

  // Add the following line
  Serial.println("Received Value: " + String((int16_t)(buff[3] << 8 | buff[4])));

  return (int16_t)(buff[3] << 8 | buff[4]);
}

stayed the same

still no response, it's not the code..
gonna make me watch that vid?? :frowning:

the pic you posted above looks wrong for sensor power..
your mcu is not a power source, use separate power source for sensor..
maybe wires A and B are backwards, flip em..

a usb adapter for your pc would be handy to test sensor and mcu comms..

~q

Did you verify sensor voltage??
Some are 5-30 and some are 9-30..
Which do you have??
~q

mine is 5 to 30v DC