1

I having following modbus polling query but i am unable find the correct crc method,crc position and crc value please guide me to find correct crc method,crc position and crc value for the following query

01 37 37 1D 31 31 31 1D 30 1D 31 03 32 35 30 34 39 04
01 37 37 1D 31 31 31 1D 30 1D 32 03 32 35 30 34 33 04
01 37 37 1D 31 31 31 1D 30 1D 33 03 35 37 38 31 34 04
01 37 37 1D 31 31 31 1D 30 1D 34 03 32 35 30 33 31 04
01 37 37 1D 31 31 31 1D 30 1D 35 03 35 37 37 39 34 04

for the above modbus polling query i am not getting which one is crc value and what type of crc used. How it is came and 77 is id of the device. Please guide me..

I am getting following response from the device for polling

01 37 37 02 33 1D 30 39 33 31 39 30 39 34 38 32 30 30 37 31 31 42 20 30 30 30 
30 30 30 30 38 34 30 30 30 30 30 30 30 30 30 30 30 30 30 30 37 38 30 30 30 30 
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 33 35 31 30 30 30 30 30 
30 30 30 30 30 30 30 30 30 30 30 30 30 30 03 34 37 33 38 35 04
Sathish
  • 199
  • 1
  • 11

1 Answers1

1

First of all:

  • The MODBUS over Serial Line standard is available here. This completely specifies low-level interface to MODBUS.
  • The MODBUS Application Protocol Specification is available here. Higher-level MODBUS commands are specified here.
  • Both of these standards are fairly short, easy to read and understand, and contain nice diagrams, so I highly recommend you look at them for answers.

Your data doesn't appear to conform to these standards, which makes it hard to answer your questions!

The serial line standard describes two communication methods, RTU and ASCII, but only the RTU method uses a CRC. So you must be using the RTU communication method since you're asking about CRC.

Assuming the RTU communication method, then the slave address should be the first byte, and the function code should be the second byte. That would mean that the slave address is 01, and the function code is 37. But that's not right, because the Application Protocol Specification page 11 lists all the function codes, and 37 is not a valid function code. Also, the slave address 01 doesn't match the slave address 77 that you claim to be using.

But let's ignore that for the moment. Your specific questions are about CRC.

  • The RTU communication method is the only one which uses a CRC. The ASCII communication method uses a Longitudinal Redundancy Check (LRC), which is different.
  • The RTU communication method uses a CRC-16, meaning the CRC has 16 bits = 2 bytes. The details are contained in the serial line standard, and there is even some sample C code for computing the CRC there. There are also multiple implementations in various languages available if you google, but do be careful because there are several different CRC-16 definitions and you need to make sure that what you use matches the MODBUS standard.
  • The CRC position in a MODBUS frame is at the very end of the frame. The last two bytes (16 bits) are the CRC. The low-order byte of the CRC is appended first, followed by the high-order byte.
  • The MODBUS queries that you provide do NOT appear to have a CRC appended to them at all. But, as I mentioned earlier, the MODBUS queries that you provide don't even look like they use the RTU communication method, which is the only method that uses a CRC.

Since your data doesn't seem to follow the RTU communication method, perhaps it uses the ASCII communication method, which is described starting on page 16 of the serial line standard. The ASCII communication method always starts with an ASCII : character, which is 3A in hex. The ASCII communication method always ends with ASCII cr and lf characters, which are 0D and 0A in hex. All other characters between these must be 0-9 or A-F characters, which are 30 through 39 and 41 through 46 in hex. Your message does not obey any of these requirements - it doesn't start with 3A, it doesn't end with 0D 0A, and it contains other characters that are not 30 through 39 or 41 through 46.

If we ignore that and assume that your data follows the ASCII communication method, then:

  • The LRC field would be the last two bytes before the 0D 0A at the end.
  • Page 18 of the serial line standard describes how LRC is computed. It is very simple:
The LRC is calculated by adding together successive 8–bit bytes of
the message, discarding any carries, and then two’s complementing the
result.  It is performed on the bytes of the message, before the
encoding of each byte in the two ASCII characters corresponding to the
hexadecimal representation of each nibble.  The computation does not include
the 'colon' character that begins the message, and does not include the CRLF
pair at the end of the message.  The resulting LRC is ASCII encoded into two
bytes and placed at the end of the ASCII mode frame before the CRLF.
  • Page 38 of the serial line standard give example C code for generating the LRC. It is only 9 lines of code.

Your data does not follow either of the communication methods. We would need to know more about where your data came from to figure out what went wrong. Perhaps the data is somehow corrupted by multiple devices, or perhaps the sensor that measures the data has incorrect timing or voltage or something, causing it to mis-understand the values being sent. Perhaps there is some kind of parity mis-match, causing some bytes to be thrown away. But we just can't tell without more information.

Eric Backus
  • 1,614
  • 1
  • 12
  • 29