steveohara / j2mod

Enhanced Modbus library implemented in the Java programming language
Apache License 2.0
262 stars 112 forks source link

Failed to read response! CRC Error in received frame #153

Open thomas-hutterer-tik opened 3 weeks ago

thomas-hutterer-tik commented 3 weeks ago

Expected Behavior

The Modbus Serial Listener is receiving a correct Request: 0B 03 07 D1 00 01 D5 ED as listed in the debug log on line 12. This request is expected to be processed and answered.

Actual Behavior

Actually the request is discarded because of a CRC error, although the CRC values are correct

Steps to Reproduce the Problem

  1. Connected a Huawei PV Inverter to a RaspberryPi via a WaveShare USB2rs485 adapter
  2. The inverter permanently sends request to Modbus id 11 like the one shown above
  3. All those requests are discarded due to CRC errors
  4. See the log attached for the full debug log from the testing session
  5. Find additional log messages which I have added to the code of ModbusRTUTransport.readRequestIn to understand the cause of the problem
  6. According to my analysis the inBuffer used for the CRC check contains different data than byteInputOutputStream.getBuffer() which holds correct request

Specifications

Code with additional log messages

                    if (logger.isDebugEnabled()) {
                        logger.debug("Request: {}", ModbusUtil.toHex(byteInputOutputStream.getBuffer(), 0, dlength + 2));
                        logger.debug("inBuffer: {}", ModbusUtil.toHex(inBuffer, 0, dlength + 2));
                    }

                    byteInputStream.reset(inBuffer, dlength);
                    if (logger.isDebugEnabled()) {
                        logger.debug("after reset: {}", ModbusUtil.toHex(inBuffer, 0, dlength + 2));
                    }

                    // check CRC
                    int[] crc = ModbusUtil.calculateCRC(inBuffer, 0, dlength); // does not include CRC
                    if (ModbusUtil.unsignedByteToInt(inBuffer[dlength]) != crc[0] || ModbusUtil.unsignedByteToInt(inBuffer[dlength + 1]) != crc[1]) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("CRC should be {}, {} inBuffer={}", Integer.toHexString(crc[0]), Integer.toHexString(crc[1]), 
                                    ModbusUtil.toHex(inBuffer, 0, dlength + 2));
                        }
thomas-hutterer-tik commented 3 weeks ago

Found the reason for changed inBuffer: In the first read operation, 311 bytes are read which causes an overflow of the 256 inBuffer size:

Jun 17 10:25:52 iWattControllerV3 java[17479]: [main] INFO J2ModLibrary - createRtuServer serialName:dev/ttyACM0 serialBaudRate: 9600 Jun 17 10:25:52 iWattControllerV3 java[17479]: [main] DEBUG com.ghgande.j2mod.modbus.slave.ModbusSlave - Creating SERIAL listener Jun 17 10:25:52 iWattControllerV3 java[17479]: [Modbus Serial Listener [port:dev/ttyACM0]] DEBUG com.ghgande.j2mod.modbus.io.ModbusRTUTransport - Waiting for 1041 microsec Jun 17 10:25:52 iWattControllerV3 java[17479]: [Modbus Serial Listener [port:dev/ttyACM0]] DEBUG com.ghgande.j2mod.modbus.io.ModbusRTUTransport - Waiting for 2083 microsec Jun 17 10:25:52 iWattControllerV3 java[17479]: [Modbus Serial Listener [port:dev/ttyACM0]] DEBUG com.ghgande.j2mod.modbus.io.ModbusRTUTransport - Read message not meant for us: 00 00 00 03 E8 00 00 00 05 06 BF 68 00 03 6C 47 05 06 9D 87 FF FF 16 7B 05 06 9D 87 FF FF 16 7B 05 10 9E 99 00 06 0C 00 00 00 00 00 00 13 88 18 24 16 DA 72 7F 05 10 9E 99 00 06 BE 48 05 03 9A 4C 00 21 6B 59 05 03 42 00 00 3A 98 00 00 3A 98 00 00 13 88 00 00 13 88 00 64 00 01 18 BC 00 01 00 00 00 30 00 01 00 2A 44 6E 00 29 2E AD 00 01 01 B3 00 00 00 00 00 00 03 E8 00 00 00 01 00 00 00 00 00 00 13 88 00 00 00 00 4E 6F 0B 03 08 36 00 50 A7 32 05 10 9E 99 00 06 0C 00 00 00 00 00 00 13 88 18 24 16 DA 72 7F 05 10 9E 99 00 06 BE 48 05 03 9A 4C 00 21 6B 59 05 03 42 00 00 3A 98 00 00 3A 98 00 00 13 88 00 00 13 88 00 64 00 01 18 BC 00 01 00 00 00 30 00 01 00 2A 44 6E 00 29 2E AD 00 01 01 B3 00 00 00 00 00 00 03 E8 00 00 00 01 00 00 00 00 00 00 13 88 00 00 00 00 4E 6F 05 03 7D 51 00 1B 4D F8 00 00 00 03 E8 00 00 00 01 00 00 00 00 00 00 13 88 00 00 00 00 5D 77 05 06 BF 68 00 03 6C 47 05 06 BF 68 00 03 6C 47 0B 03 07 D1 00 01 D5 ED