pythonmodbusminimalmodbusmodbus-tk

Minimalmodbus, randomly generates wrong crc


I am currently working on a project of data acquisition with a RaspberryPi. When i launch my request script, sometimes (rare but too often) my slave (computer) detects a CRC error or invalid length. I'm guessing the error could come from the fact that, as my script is fast and asks for hundreds of register in a few seconds, sometimes the message is incomplete and my slaves detects it as a wrong message. I wanted to know if it was possible that minimalmodbus isn't timed right and sometimes will send a wrong or part of a request (incomplete).

Error returned on the slave:

invalid request: Invalid CRC in request

This is a typical error i get on my master when the slave doesn't know what to answer:

  error = SLAVE_ERRORS[str(e)]
KeyError: "Checksum error in rtu mode: '\\x8aÿ' instead of '\\x8fF' . The response is: '4ÿ\\x07$Ê\\x8aÿ' (plain response: '4ÿ\\x07$Ê\\x8aÿ')"**

I use modbus_tk on the slave to emulate a modbus slave. And next is typically a part of my code that requests values from the slave that depends on a type of value.

    try:
        try:
            var_register = file_var[i]['varRegister']
            var_type = file_var[i]['varType']
            var_use = file_var[i]["varUse"]
            var_name = file_var[i]["varName"].strip()

            if '#' in var_register:
                continue
            elif var_type=='U16' or var_type=='I16' or var_type=='S16':

                value = inst.read_register(
                    int(var_register),
                    0,
                    3, 
                    not bool(file_var[i]['varSigned'])
                ) 

            elif var_type=='U32' or var_type=='I32' or var_type=='S32':

                value = inst.read_long(
                    int(var_register),
                    3, 
                    not bool(file_var[i]['varSigned'])
                ) 

As my first guess was a problem of timing i randomly inserted "time.sleep" to time my requests but the errors are still coming up. And it's completely random, sometimes it'll work for 5 mins and sometimes just a few seconds before my first CRC error. Do you have any idea on where I should look into? Thanks in advance for your help!

EDIT: My PC acts as a slave with a modbus_tk script emulating multiple slaves. The RPI is the master asking for registers and their values. the slaves are all configured to have values in those specific register in order to avoid an IllegalAddress error. The physical connection is a USB to RS485 converter, the RPI is equipped with a HAT handling RS485 input/output. So it is in fact a ModBus RTU communication. The slave loops and sends an answer when a request comes in.

EDIT2: So I have investigated a bit further and found something interesting. I received an error (this time on the master) the slave apparently sent the wrong Checksum... while looking into it, i found that the checksum generated by modbus_tk was fine, but the answer received by the master wasn't the same. It looks like some bytes are changed on the road which is weird. Where could that come from? Hardware issue? Only does this error when polling multiple registers though (more than 2 at once). all other requests are fine if the number of registers asked for, is 1 or 2.


Solution

  • No, it is not weird, it is probably noise or another hardware issue indeed.

    This is precisely why the CRC is there, to make sure you receive on the master the same values the slave is sending.

    You most likely have:

    1. not connected the GNDs together
    2. a very bad power supply
    3. very messed up wires
    4. an environment where you have big electric motors or any other source or noise

    My bet is 1: you thought RS485 is two-wire (you have those A and B or + and - connections only, right?).

    I'm not going to go into the details here because you should be able to find thousands if not millions of references and posts where this particular war has been going on since the beginning of time. Suffice to say that if you are having trouble on your bus with just two wires you will probably solve the problem by adding a third joining the GNDs on both devices together. This is often the case when one or both devices are running on battery or have an isolated power supply.

    If you want to know more you can read this document. Some particularly juicy paragraphs with regards to your question:

    Running RS-422/485 a few dozen feet over quality cable with good shielding and ground can be virtually error-free. However, that’s not what people use RS-422/485 for. Any electrical signal running over 1000 m of wire (such as 3300+ ft of antenna) will pick up noise. The differential twisted-pair nature of RS-422/485 helps reduce the impact of this noise, but you must assume a few communications errors occur every day. This means running long RS-422/485 lines is only suitable for protocols that include proper error-detect (a CRC or block-checksum).

    and:

    Unfortunately, grounding for RS-422/485 is one of the most misunderstood aspects of serial communications. Many people believe that RS-422/485 does not require a ground. One myth is that the plus (+) and minus (-) signals act like a current loop and complete the electrical circuit by themselves. Another myth is that a differential signal just compares two voltages without reference to common ground. But the biggest culprit is the fact that RS-422/485 wired without proper grounding appears to work.