pyhys / minimalmodbus

Easy-to-use Modbus RTU and Modbus ASCII implementation for Python.
Apache License 2.0
302 stars 146 forks source link

Checksum error in rtu mode #102

Open MGGEL opened 1 year ago

MGGEL commented 1 year ago

Hi,

I've got an error when I try to select some bits or registers from a modbus slave.

#!/usr/bin/env python3

import serial
import minimalmodbus
from time import sleep

client1 = minimalmodbus.Instrument('/dev/ttyAMA0', 10, debug=True)  # port name, slave address (in decimal)
client1.serial.baudrate = 19200
client1.serial.bytesize = 8
client1.serial.parity   = serial.PARITY_EVEN
client1.serial.stopbits = 1
client1.serial.timeout  = 0.1
client1.mode = minimalmodbus.MODE_RTU

res = client1.read_register(1001, 1, 4)
print (res)

The Response

MinimalModbus debug mode. Create serial port /dev/ttyAMA0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 0A 04 03 E9 00 01 E1 01 (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyAMA0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1755610178.72 ms, minimum silent period: 2.01 ms.
MinimalModbus debug mode. Response from instrument: FB F8 7F 00 (4 bytes), roundtrip time: 0.1 ms. Timeout for reading: 100.0 ms.

Traceback (most recent call last):
  File "minimal.py", line 42, in <module>
    res = client1.read_register(1001, 1, 4)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 486, in read_register
    payloadformat=_Payloadformat.REGISTER,
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1245, in _generic_command
    payload_from_slave = self._perform_command(functioncode, payload_to_slave)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1330, in _perform_command
    response, self.address, self.mode, functioncode
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1867, in _extract_payload
    raise InvalidResponseError(text)
minimalmodbus.InvalidResponseError: Checksum error in rtu mode: '\x7f\x00' instead of 'C\x02' . The response is: 'ûø\x7f\x00' (plain response: 'ûø\x7f\x00')

Do you have any recomendations for analyzing the problem?

j123b567 commented 1 year ago

The expected response should be something like

Your response FB F8 7F 00

Roundtrip time seems to be too short, should be milliseconds, not hundreds of microseconds.

It seems to me that you are driving the DE signal of RS-485 incorrectly.

MGGEL commented 1 year ago

Ok, thanks for the quick answer! But I need a bit more help to solve this, this is my first modbus communication.

I've changed the timout, but there seems to be no difference. What ist the DE signal, and how can I change it?

MGGEL commented 1 year ago
MinimalModbus debug mode. Create serial port /dev/ttyAMA0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 0A 04 03 E9 00 01 E1 01 (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyAMA0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1816826420.41 ms, minimum silent period: 2.01 ms.
MinimalModbus debug mode. Response from instrument: FB F8 7F 00 25 A7 BE (7 bytes), roundtrip time: 2.2 ms. Timeout for reading: 0.0 ms.

Traceback (most recent call last):
  File "minimal.py", line 17, in <module>
    res = client1.read_register(1001, 1, 4)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 486, in read_register
    payloadformat=_Payloadformat.REGISTER,
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1245, in _generic_command
    payload_from_slave = self._perform_command(functioncode, payload_to_slave)
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1330, in _perform_command
    response, self.address, self.mode, functioncode
  File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1867, in _extract_payload
    raise InvalidResponseError(text)
minimalmodbus.InvalidResponseError: Checksum error in rtu mode: '§¾' instead of '\x00·' . The response is: 'ûø\x7f\x00%§¾' (plain response: 'ûø\x7f\x00%§¾')
j123b567 commented 1 year ago

It is probably out of the scope of this discussion. Everything highly depends on your hardware and your instrument and correct setup of RS-485 between them.

Please, try everything first with known good external USB/RS-485 converter and with known good modbus instrument. Later you can replace components one by one to find the culprit.

Learn something about RS-485 and how e.g. UART/RS-485 chips work may be also very beneficial.

ollie-campbell commented 1 year ago

Just a thought....@MGGEL but I never specify baudrate, parity etc. and just use the bult-in defaults. You could try this to see if it helps:

import serial
import minimalmodbus
from time import sleep

client1 = minimalmodbus.Instrument('/dev/ttyAMA0', 10, debug=True)  # port name, slave address (in decimal)
client1.mode = minimalmodbus.MODE_RTU

res = client1.read_register(1001, 1, 4)
print (res)
JuanPaEsAr commented 11 months ago

In my case I have the following errors and I can't undertand the reason, as you can apreciate sometime reading good and sometimes not, it is weird:

image

May you hel me with this?

j123b567 commented 11 months ago

You should first disable services using the /dev/ttyAMA0.

E.g.

please search yourself. It is out of the scope of this library.

khodepratik1 commented 9 months ago

i too got that error

import minimalmodbus
import time
import serial
from time import sleep
instrument = minimalmodbus.Instrument('/dev/ttyS0',1)
instrument.debug = True
instrument.serial.timeout = 0.2
instrument.close_port_after_each_call = True
instrument.serial.bytesize = 8
instrument.serial.baudrate = 9600
#instrument.handle_local_echo=True
instrument.serial.stopbits = 1
instrument.serial.rtscts = True
instrument.serial.parity = serial.PARITY_NONE
instrument.mode = minimalmodbus.MODE_RTU
print(instrument)
while True:
    try:
#       modbus_data = instrument.read_registers(registeraddress=305, functioncode=3,number_of_registers=4 )
        modbus_data = instrument.read_register(305,4)
        print('mod',modbus_data)
    except Exception as e:
        print('her',e)
    time.sleep(2)
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 01 31 00 01 D4 39 (8 bytes)
MinimalModbus debug mode. Opening port /dev/ttyS0
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyS0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 2032.35 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyS0
MinimalModbus debug mode. Response from instrument: 01 03 01 31 00 01 D4 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 200.0 ms.

her Checksum error in rtu mode: b'\x01\xd4' instead of b']\xd4' . The response is: b'\x01\x03\x011\x00\x01\xd4' (plain response: b'\x01\x03\x011\x00\x01\xd4')
JuanPaEsAr commented 7 months ago

khodepratik1 Hello, I have the same problem again, but if you change the variable timeout to 1 is better. In the other hand, sometimes when you setup the timeout to 1 in some simulation devices (as Modbus Slave with baudrate to 9600) the checksum error seemed again, this is my case, and for this reason you must try to read several times.

JuanPaEsAr commented 7 months ago

@j123b567

Hello again, l have the following system: raspberry pi zero 2W, Max485 and Huawei inverter. I try with minimalmodbus read a registers from inverter, but if I use the baudrate equal to 9600 and timeout equal to 1 the checksum error seems, but in Modbus Slave occurs but sometimes, Do you know why?. I appreciate your answer and help, if you need more information, I can provide.

This occurs with Modbus Slave:

Start Reading in a loop
MinimalModbus debug mode. Will write to instrument (expecting 205 bytes back): 01 03 7D 08 00 64 DD 8F (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyAMA0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 21432771.96 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument: FF 01 03 C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 B3 04 D4 11 E9 05 5E 12 EA 03 FD 15 19 03 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 DD 08 D2 08 D4 00 00 00 00 00 00 00 00 CB 66 00 00 C5 6C 00 00 C6 E8 00 00 00 00 00 AF 52 9E 05 43 7D 08 03 E5 17 71 00 00 02 4E 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 A8 7F (205 bytes), roundtrip time: 0.4 ms. Timeout for reading: 0.0 ms.

Error durante la comunicación Modbus: Checksum error in rtu mode: '¨\x7f' instead of '\x17\x80' . The response is: 'ÿ\x01\x03È\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12³\x04Ô\x11é\x05^\x12ê\x03ý\x15\x19\x03F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08Ý\x08Ò\x08Ô\x00\x00\x00\x00\x00\x00\x00\x00Ëf\x00\x00Ål\x00\x00Æè\x00\x00\x00\x00\x00¯R\x9e\x05C}\x08\x03å\x17q\x00\x00\x02N\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T¨\x7f' (plain response: 'ÿ\x01\x03È\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12³\x04Ô\x11é\x05^\x12ê\x03ý\x15\x19\x03F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08Ý\x08Ò\x08Ô\x00\x00\x00\x00\x00\x00\x00\x00Ëf\x00\x00Ål\x00\x00Æè\x00\x00\x00\x00\x00¯R\x9e\x05C}\x08\x03å\x17q\x00\x00\x02N\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T¨\x7f')
j123b567 commented 7 months ago

@TylerDurden997 can you provide additional info?

Why am I asking... Genuine MAX485 is 5V only.

Boards with automatic DE handling don't work in certain situations (swollow bits, artifical bytes)

Boards with manual DE handling are tricky to handle correctly in linux from python. It must be done by software.

We are using USB/RS485 in all our devices using linux now because of these problems. (USB chips have hardware TXDEN which is directly connected to the DE input of the RS485 transceiver. It is automatic, reliable and transparent to the software.)

JuanPaEsAr commented 7 months ago

@j123b567 of course, this is the configuration in the PCB of MAX 485:

image

In this picture, you can see that the power supply of MAX 485 is 5V, in my case, I am managing the pin with the python library RPi.GPIO, in the picture, the pin called PIN_CONTROL. If you need more information, for example the code, I can provide this. I apprciate your answer

j123b567 commented 7 months ago

Python is not good for precise timing. Do you have access to Osciloscope or logic analyzer so you can see real timing of request, PIN_CONTROL and response from your device?

See also the documentation https://minimalmodbus.readthedocs.io/en/stable/serialcommunication.html

See also https://minimalmodbus.readthedocs.io/en/stable/troubleshooting.html?highlight=RS485#empty-bytes-added-in-the-beginning-or-the-end-on-the-received-message

abhishek73magar commented 7 months ago

I also got like similar error but i just try to read multiple registers from 0, 20 using

sensy_boi.read_registers(startRange, totalregister)

but got error:

Checksum error in rtu mode: b'\x00<' instead of b'C\x1f' . The response is: b'\r\x03\x1e\xd7\x97\x00\x01\x1eM\x00\x06\xb7\xb9\x00\x02\xbe\xf0\x00\x04\x94\xf6\x00\r\n0\x00\x00<' (plain response: b'\r\x03\x1e\xd7\x97\x00\x01\x1eM\x00\x06\xb7\xb9\x00\x02\xbe\xf0\x00\x04\x94\xf6\x00\r\n0\x00\x00<')

but its only appear some time I just try to read registers every 1 seconds

j123b567 commented 7 months ago

@Coder73-avi As mentioned several times, the problem is outside of the minimalmodbus library. If you need help, read the documentation first (Serial communication, Troubleshooting). Make sure you check and fix everything mentioned here. Make sure you have a good RS-485 transceiver solution (also mentioned in the documentation).

If you have tried everything in the documentation and it still does not work, please describe your situation in detail.