Arduino and RS485 communication

Hello everybody,

Currently in Vietnam for an intership I'm trying to communicate with a PLC from Ditel and my Arduino nano. here is the datasheet of the PLC : ftp://ftp.cmdl.noaa.gov/aerosol/ugr/etc/Ditel_PID_SZ48-SZ49_Modbus.pdf

I have to use an Half-duplex RS485 modbus protocol, so I'm using a MAX485 in order to adjust the voltage level of my frame.

I'm trying to send the frame on page 33 of the datasheet.

// Pin 2 of tharduino connected to pins RE&DE of MAX485
#include 


SoftwareSerial mySerial(10, 11); //RX, TX

#define switchPin 2

#define rxPin 10
#define txPin 11



byte req[]= {0x02, 0x04, 0x00, 0x00, 0x00, 0x01, 0x31, 0xCA}; // Frame to send in order to read the PV value of the PLC


byte RS485Byte = 0;

void setup() {

  // Communication at 9600 b/s 
  Serial.begin(9600);
// pin tx to send data
  pinMode(txPin, OUTPUT);
  // pin rx to receive data
  pinMode(rxPin, INPUT);
  
  
  pinMode(switchPin, OUTPUT);
  mySerial.begin(9600);
  digitalWrite(switchPin, HIGH); // Pin 2 High level in order to send data
  mySerial.write(req, sizeof(req));
  mySerial.flush();
  digitalWrite(switchPin, LOW);// Pin 2 Low level in order to receive data
   
   
    
  
  

}

void loop() {
  

     if( mySerial.available()>0)
     {
        RS485Byte = mySerial.read();
        Serial.print("incoming Bytes : "); Serial.println(byte(RS485Byte), HEX);
      }  
}

And the anwser I have on the monitor is incoming Bytes : 0.

I was wondering if I have to use the Modbus master library to send data or if anything was wrong in my code ...

( sorry for my bad english..)

Thanks for your help !

Have a nice day

You are sending an invalid CRC, the Slave device is rejecting the command message because of the CRC failure.

Read and Implement a CRC calculating function.

You copied the example command sequence from the reference manual, BUT changed one byte. This change of the Station ID from 0x01 to 0x02 invalidated the CRC value 0x31, 0xCA. The calculated CRC is 0x31 0xF9.

Since the command's CRC does not match the calculated CRC, the device discards the command because it thinks there was a data transmission error.

This is documented in the PDF as the response to a CRC failure.

Try sending one of the examples exactly as listed in the PDF.

byte req[]= {0x02, 0x04, 0x00, 0x00, 0x00, 0x01, 0x31, 0xCA}; // Frame to send in order to read the PV value of the PLC

Here is a CRC Function that matches the examples. I had to reverse the highByte, lowByte order to match the examples from the PDF. The Manual may be in error, or the implementation may have changed without updating the manual. If the device does not respond, reverse the order of my example, send the highByte first.

// Ditel Modbus CRC calculation
// Chuck Todd 


uint16_t CalcCRC(byte * data, uint8_t datlen){
uint16_t CRC=0xFFFF; // Init CRC
uint8_t xor_flag;
for(uint8_t n=0; n> 1;
    if (xor_flag) {
      CRC = CRC ^ 0xA001;
      }
    }
  }
return CRC;
}

void SendCmd( byte * data, uint8_t datlen){ // this is just a test routine to send results Serial Monitor.
uint16_t CRC=CalcCRC(data, datlen);
for(uint8_t i=0;i

Chuck.

check out my Kickstarter project. Memory Panes

Thanks you very much Chuck very helpful ! But I still have no answer from the PLC... I really don't uderstand why because I'm sending the right frame ... I should have a response !

Etienne1805: Thanks you very much Chuck very helpful ! But I still have no answer from the PLC... I really don't uderstand why because I'm sending the right frame ... I should have a response !

Have you added the correct CRC for your messages? Post your updated code, I'll look thru it.

Is the PLC configured correctly?

Can you just put your Arduino into receive mode (_T/R=R) and monitor communications on the RS485 net?

Have you verified the baud rate is correct?

Can you cause the PLC to transmit something on the RS485 net? Make it think it has a remote sensor It needs to query?

You are at square one: 1. Have you connected A-A, B-B, and Ground? 2. Are the Baud rates correct? Both Arduino and PLC. 3. Does the PLC know to monitor the RS485 net? 4. Have you verified the Terminal number (address) of the PLC? 5. Do you have a Scope to check that you have activity on the RS485 net?

Many, many questions. You need some answers.

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

I've checked every questions you tell me everything is ok , only the fact of the same ground. I thought that on a RS485 there was no need of same ground and the fact is that on the PLC there is no ground output... Also I don't have any scope to check the activity on the line...