Hi there, I have three NPK sensors from DFRobot and I am attempting to get them all working on one RS485 MAX module. With testing I have found one sensor works fine, but when I use two sensors the result shift down by one position, and will add together as seen below. All three sensors are powered on the same benchtop power supply at 20V with current fluctuating between 30-60mA.
I need some help figuring out if its the code that’s an issue, or the way I have setup my circuit.
Typical Results:
Sensor 1
FF FF FF FF FF FF FF
383838080FC66
132017F98E
Nitrogen: 255 mg/kg
Phosphorous: 128 mg/kg
Potassium: 23 mg/kg
Sensor 2
11 37 26 4 E4 BC 22
FFFFFFFFFFFFFF
FFFFFFFFFFFFFF
Nitrogen: 228 mg/kg
Phosphorous: 255 mg/kg
Potassium: 255 mg/kg
Here is the code I am using:
#include <SoftwareSerial.h>// for RS485 MAX module
//Define pins for RS485
#define DI 2 // RX Pin
#define DE 3 //Drive enable
#define RE 4 //Recieve enable
#define R0 5 // TX Pin
//Software serial object to communicate with MAX485
SoftwareSerial mod(R0,DI);
/* |CRC16 / IBM MODBUS check sum split in two 8 bit portions|
Address | Function | Return the | temporary | Low bit of | High bit |
code | code | number of valid bytes | storage value | check code | of check code |
*/
//const byte code[]= {0x01, 0x03, 0x00, 0x1e, 0x00, 0x03, 0x65, 0xCD};
/*https://crccalc.com/?crc=0x03,0x03,%200x00,%200x1f,%200x00,%200x01&method=CRC-16/MODBUS&datatype=hex&outtype=hex
the link above checks cycle redundancy check sum for the first 6 numbers in the arrays below
*/
//sensor 1
const byte nitro1[] = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos1[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc}; //CRC-16 modbus HEX shows 0xCCB5 or 0xb5, 0xcc
const byte pota1[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
//sensor 2
const byte nitro2[] = {0x02,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x3f};
const byte phos2[] = {0x02,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xff};
const byte pota2[] = {0x02,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xf3};
//sensor 3
const byte nitro3[] = {0x03,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe5, 0xee};
const byte phos3[] = {0x03,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb4, 0x2e};
const byte pota3[] = {0x03,0x03, 0x00, 0x20, 0x00, 0x01, 0x84, 0x22};
byte values[11];
void setup() {
// put your setup code here, to run once:
//initialse serial communication
Serial.begin(9600);
mod.begin(9600);
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
int num=5;
while(num > 0){
Serial.println(num);
delay(1000);
num--;
}
}
void loop() {
byte val1,val2,val3;
Serial.println("Sensor 1");
val1 = nitrogen(nitro1, sizeof(nitro1));
delay(250);
val2 = phosphorous(phos1, sizeof(phos1));
delay(250);
val3 = potassium(pota1, sizeof(pota1));
delay(250);
printNPK(val1, val2, val3);
Serial.println("Sensor 2");
val1 = nitrogen(nitro2, sizeof(nitro2));
delay(250);
val2 = phosphorous(phos2, sizeof(phos2));
delay(250);
val3 = potassium(pota2, sizeof(pota2));
delay(250);
printNPK(val1, val2, val3);
/*
Serial.println("Sensor 3");
val1 = nitrogen(nitro3, sizeof(nitro3));
delay(250);
val2 = phosphorous(phos3, sizeof(phos3));
delay(250);
val3 = potassium(pota3, sizeof(pota3));
delay(250);
printNPK(val1, val2, val3);
*/
}
byte nitrogen(const byte *nitro, byte len) {
memset(values, 0, sizeof(values)); // Clear the buffer first
digitalWrite(DE, HIGH); // send signal
digitalWrite(RE, HIGH); // recieve signal
delay(10);
if (mod.write(nitro, len) == 8) { //checking for 8-byte data return
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// Print all received bytes
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(" ");
}
Serial.println();
}
return values[4]; // This assumes the NPK value is always at this position, check this
}
byte phosphorous(const byte *phos, byte len){
memset(values, 0, sizeof(values)); // Clear the buffer first
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(phos,len)==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[4];
}
byte potassium(const byte *pota, byte len){
memset(values, 0, sizeof(values)); // Clear the buffer first
digitalWrite(DE,HIGH); //drive enabled
digitalWrite(RE,HIGH); //recieve enabled
delay(10); //stabilisation
if(mod.write(pota,len)==8){ //sends pota array modbus request 8 bytes
digitalWrite(DE,LOW); //drive disabled
digitalWrite(RE,LOW); //recieve disabled
for(byte i=0;i<7;i++){ //reads 8 byte array from sensor
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
void printNPK(byte val1, byte val2, byte val3){
Serial.print("Nitrogen: ");
Serial.print(val1);
Serial.println(" mg/kg");
Serial.print("Phosphorous: ");
Serial.print(val2);
Serial.println(" mg/kg");
Serial.print("Potassium: ");
Serial.print(val3);
Serial.println(" mg/kg");
delay(200);
}
Circuit setup:
any help would be appreciated (>'-'<).


