Need help in Reading and writing multiple queries and responses using RS485

Hello there!

I’m new to the Arduino community :slight_smile: . I have been working on a project where i have to retrieve information from a Multi-parameter Water Quality Analyzer. The system uses separate probes to get information like pH, Temperature, Dissolved Oxygen and display it on to a touch screen on its main control unit. This control unit also uses the RS485 communication protocol which allows it to be connected to an Arduino board. Thanks to the community i managed to write code to ask for information using an Arduino Mega (Master) requesting the required data from a single probe of the Sensor system (Slave). I used the register address data to successfully get pH information onto the Arduino board and tested the rest individually by varying the query. But when i changed my code to get information from more than one sensor probe the data read onto the serial monitor is having errors. Can you advise me regarding how to tackle this problem thank you very much in advance.

The code to retrieve the pH from the sensor and convert from HEX to decimal and display on the Serial monitor which worked without an issue:

#define dirPin   4

const byte getPH[10] ={0x02,0x03,0x00,0xDB,0x00,0x02,0xB4,0x03};
//const byte getall[10]={0x02,0x03,0x00,0xDB,0x00,0x0C,0x35,0xF4};

unsigned long currentMillis,interval = 1000;

/**************************************************************************/

void setup() {
  
  pinMode(dirPin,OUTPUT);
  digitalWrite(dirPin,LOW);
  Serial.begin(9600);
  Serial2.begin(9600);

  Serial.print("\r\npH Value =\t"); Serial.print(float(readPH()),3);
  currentMillis = millis();
}

/**************************************************************************/


void loop() {

  if(millis()>(currentMillis+interval))
  {
    Serial.print("\r\npH Value =\t"); Serial.print(float(readPH()),3);
    currentMillis = millis();
  }
}

/**************************************************************************/

float readPH(void)
{
    int pHinHEX[9];
    byte index;
    long fourByteHEX; 
    float pHvalue;

    // SEND //
    digitalWrite(dirPin,HIGH);
    delay(10);
    //Serial2.write(" Data");
    Serial2.write((byte)0x01);
    Serial2.write((byte)0x03);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0xDB);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0x02);
    Serial2.write((byte)0xB4);
    Serial2.write((byte)0x30);

    // TO Recieved //
    delay(10);
    digitalWrite(dirPin,LOW);

    index=0;
    while(Serial2.available()&&index<=9) {
    pHinHEX[index]=Serial2.read();
    index++;
    }

    Serial.print("\r\nData in HEX = \t");
    for(index=0;index<9;index++)
    {
       Serial.print(pHinHEX[index],HEX);
    }

    Serial.println();
  

  fourByteHEX = fourByteHEX | pHinHEX[5];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[6];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[3];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[4];

  pHvalue = convertToFloat(fourByteHEX);
  return pHvalue;
}

/**************************************************************************/
float convertToFloat(long Data)
{
  byte sign=0,exponent=0;
  unsigned long mantissa=0;
  float onlyFloatValue = 0;
  float returnFloat=0;
  
  exponent = ((Data & 0x7F800000) >> 23) - 127;
  mantissa = Data << 9 ;
  if(exponent>127){ returnFloat = 0.0; goto endConversion; }

  //Serial.print("\r\nexponent = \t"); Serial.print(exponent);
  //Serial.print("\r\nmantissa = \t"); Serial.print(mantissa);

  for(int q=1;q<24;q++)
  {
    if(mantissa & 0x80000000){ onlyFloatValue = onlyFloatValue + pow(2,-(q)); }
      mantissa = mantissa <<1;
  }

  //Serial.print("\r\onlyFloatValue = \t"); Serial.print(onlyFloatValue);

  onlyFloatValue = 1.0 + onlyFloatValue;

  returnFloat = float(pow(2,exponent)) * onlyFloatValue;
  //Serial.print("\r\return float = \t"); Serial.print(returnFloat);

  if(Data&0x80000000){ returnFloat = returnFloat * (-1); }
endConversion:
  return returnFloat;
  
}

Then i tried to obtained two parameters using an edited version of the same code.This is where i staarted to face problems

#define dirPin   4

const byte getPH[10] ={0x02,0x03,0x00,0xDB,0x00,0x02,0xB4,0x03};
//const byte getall[10]={0x02,0x03,0x00,0xDB,0x00,0x0C,0x35,0xF4};

unsigned long currentMillis,interval = 10000;

/**************************************************************************/

void setup() {
  
  pinMode(dirPin,OUTPUT);
  digitalWrite(dirPin,LOW);
  Serial.begin(9600);
  Serial2.begin(9600);

  Serial.print("\r\npH Value =\t"); Serial.print(float(readPH()),3);
  currentMillis = millis();
}

/**************************************************************************/


void loop() {

  if(millis()>(currentMillis+interval))
  {
    //Serial.print("\r\npH Value =\t"); Serial.print(float(readPH()),3);
    
    Serial.print("\r\nDO Value =\t"); Serial.print(float(readDO()),3);
    currentMillis = millis();
  }
}

/**************************************************************************/
float readDO(void)
{
    int DOinHEX[9]={0};
    byte index=0;
    long fourByteHEX=0; 
    float DOvalue=0;

    // SEND //
    digitalWrite(dirPin,HIGH);
    delay(10);
    //Serial2.write(" Data");
    Serial2.write((byte)0x01);
    Serial2.write((byte)0x03);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0xDF);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0x02);
    Serial2.write((byte)0xF5);
    Serial2.write((byte)0xF1);

    // TO Recieved //
    delay(10);
    digitalWrite(dirPin,LOW);

    index=0;
    while(Serial2.available()&&index<=9) {
    DOinHEX[index]=Serial2.read();
    index++;
    }

    Serial.print("\r\nData in HEX = \t");
    for(index=0;index<9;index++)
    {
       Serial.print(DOinHEX[index],HEX);
    }

    Serial.println();
  

  fourByteHEX = fourByteHEX | DOinHEX[5];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | DOinHEX[6];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | DOinHEX[3];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | DOinHEX[4];

  DOvalue = convertToFloat(fourByteHEX);
  return DOvalue;
}

/**************************************************************************/

float readPH(void)
{
    int pHinHEX[9]={0};
    byte index=0;
    long fourByteHEX=0; 
    float pHvalue=0;

    // SEND //
    digitalWrite(dirPin,HIGH);
    delay(10);
    //Serial2.write(" Data");
    Serial2.write((byte)0x01);
    Serial2.write((byte)0x03);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0xDB);
    Serial2.write((byte)0x00);
    Serial2.write((byte)0x02);
    Serial2.write((byte)0xB4);
    Serial2.write((byte)0x30);

    // TO Recieved //
    delay(10);
    digitalWrite(dirPin,LOW);

    index=0;
    while(Serial2.available()&&index<=9) {
    pHinHEX[index]=Serial2.read();
    index++;
    }

    Serial.print("\r\nData in HEX = \t");
    for(index=0;index<9;index++)
    {
       Serial.print(pHinHEX[index],HEX);
    }

    Serial.println();
  

  fourByteHEX = fourByteHEX | pHinHEX[5];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[6];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[3];
  fourByteHEX = fourByteHEX << 8;
  fourByteHEX = fourByteHEX | pHinHEX[4];

  pHvalue = convertToFloat(fourByteHEX);
  return pHvalue;
}

/**************************************************************************/
float convertToFloat(long Data)
{
  byte sign=0,exponent=0;
  unsigned long mantissa=0;
  float onlyFloatValue = 0;
  float returnFloat=0;
  
  exponent = ((Data & 0x7F800000) >> 23) - 127;
  mantissa = Data << 9 ;
  if(exponent>127){ returnFloat = 0.0; goto endConversion; }

  //Serial.print("\r\nexponent = \t"); Serial.print(exponent);
  //Serial.print("\r\nmantissa = \t"); Serial.print(mantissa);

  for(int q=1;q<24;q++)
  {
    if(mantissa & 0x80000000){ onlyFloatValue = onlyFloatValue + pow(2,-(q)); }
      mantissa = mantissa <<1;
  }

  //Serial.print("\r\onlyFloatValue = \t"); Serial.print(onlyFloatValue);

  onlyFloatValue = 1.0 + onlyFloatValue;

  returnFloat = float(pow(2,exponent)) * onlyFloatValue;
  //Serial.print("\r\return float = \t"); Serial.print(returnFloat);

  if(Data&0x80000000){ returnFloat = returnFloat * (-1); }
endConversion:
  return returnFloat;
  
}

These are the values i managed to get when i tried to retrieve information from a single sensor and when i used two different Queries respectively:

pH Value =	
Data in HEX = 	1BFE0FFFFCC00301800600284
0.000
pH Value =	
Data in HEX = 	13448DB41FEDFC
8.955
pH Value =	
Data in HEX = 	13448DB41FEDFC
8.955
pH Value =	
Data in HEX = 	13448DB41FEDFC
8.955
pH Value =	
Data in HEX = 	13448DB41FEDFC
8.955

When using for than One query the HEX data was mostly gibberish.

0.000
DO Value =	
Data in HEX = 	F100000000
0.000
pH Value =	
Data in HEX = 	2B430000000
0.000
DO Value =	
Data in HEX = 	72F5000000
0.000
pH Value =	
Data in HEX = 	4020DB02B4000
0.000
DO Value =	
Data in HEX = 	130DF02000
0.000

Thank you very much in advance.