1

I try to communicate with 2 RS485 sensors (pH and EC), but I have some troubles with my code. First, I tried to get data from just one:

The function in charge of request sending:

String GET_probe(String probe){

if(probe == "pH"){
Serial.println("Sending request pH...");
digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
byte  RTUrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));
}

if(probe == "EC"){
Serial.println("Sending request EC...");          

digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
byte  RTUrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));  
}

RS485Serial.flush();
RS485Serial.listen();
}

The function in charge of reading sensor's answer:

void ReadRx() {
     digitalWrite(modbusModuleRE, RS485Receive);
     digitalWrite(modbusModuleDE, RS485Receive);
     if(RS485Serial.available()) {
     Serial.print("Answer: ");
      for(int i=0; i<7; i++){  
          String myByte = String(RS485Serial.read(), HEX);// Read the byte

          if (myByte.length() == 1)
          {
            myByte = "0"+myByte;
          }
          modbusHexBuffer[i] = myByte;

          Serial.print(myByte);
          Serial.print(" "); 
      }
      Serial.println();
    }
   }

And the loop, sending the request each 5s:

void loop(){

  static uint32_t ts = millis();

  if (millis() - ts >= 5000) {
      ts = millis();
      GET_probe("pH");
  }

ReadRx();
}

The loop runs fine once and fails the second time, as shown in terminal. Can you tell me why and help me to fix it?

Sending request pH...
Answer: 00 03 02 05 78 86 f6 
Sending request pH...
  • comments: wire DE and RE to one pin; you don't need to call listen if you have only one SoftwareSerial instance; don't use String; if at least 1 byte is available you read 7 – Juraj Mar 8 '19 at 13:41
  • Are you talking about this line?: String myByte = String(RS485Serial.read(), HEX); – Teddol Mar 8 '19 at 13:44
  • regarding String and reading blindly, yes. use RS485Serial.readBytes(RTUresponse, 7);. readBytes will wait for the next byte – Juraj Mar 8 '19 at 13:48
1

I have found why !!!

1st: buf[8] instead buf[7] in declaration 2nd: reinit byte buf[8] before EC request part.

So the code who works fine is:

byte buf[8];
void loop(){

      Serial.print("pH: ");   
      digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
      digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
      byte  pHrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB}; 
      RS485Serial.write(pHrequest, sizeof(pHrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
     Serial.print(buf[3], HEX);Serial.println(buf[4], HEX);

byte buf[8];

      Serial.print("EC: "); 
      digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
      digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
      byte  ECrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
      RS485Serial.write(ECrequest, sizeof(ECrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
      Serial.print(buf[3], HEX);Serial.print(buf[4], HEX);Serial.print(buf[5], HEX);Serial.println(buf[6], HEX);

Serial.println();

}
  • 1
    rewrite it please as standalone answer – Juraj Mar 8 '19 at 18:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.