OPTA RS485 MODBUS - Bad CRC calculated by ArduinoModbus library / update : issue w/ postdelay and CRC if value too low or too speed

Hi all,

Sorry to disturb the community.
But I am in trouble w/ my OPTA Wifi module and RS485 MODBUS :frowning:

Indeed, randomly, and following the request sent by through ModbusRTUClient.requestFrom function, the CRC calculated is bad (I add a sniffer into the technical chain in order to check all the RS485 data, reason why I can see it).

Of course, I use the lastest ArduinoRS485 (V1.1.0) & ArduinoModbus (V1.0.9).

To be clear, and for example, here is some requests (correct and bad) sent from OPTA module to add-on :

01 03 00 04 00 01 C5 CB => correct CRC
02 03 00 04 00 01 C5 F8 => correct CRC
03 03 00 04 00 01 C4 E9 => bad CRC ! Must be C4 29
04 03 00 04 00 01 C5 DE => bad CRC ! Must be C5 9E
05 03 00 04 00 01 C4 CF => bad CRC ! Must be C4 4F
06 03 00 04 00 01 C4 FC => bad CRC ! Must be C4 7C
07 03 00 04 00 01 C5 ED => bad CRC ! Must be C5 AD
08 03 00 04 00 01 C5 D2 => bad CRC ! Must be C5 52
09 03 00 04 00 01 C4 C3 => bad CRC ! Must be C4 83
0A 03 00 04 00 01 C4 F0 => bad CRC ! Must be C4 B0
0B 03 00 04 00 01 C5 E1 => bad CRC ! Must be C5 61
0C 03 00 04 00 01 C4 D6 => correct CRC
0D 03 00 04 00 01 C5 C7 => bad CRC ! Must be C5 07
0E 03 00 04 00 01 C5 F4 => bad CRC ! Must be C5 34
and so on...

Has anyone ever seen this case ?
Please, if someone can help me, it will be w/ pleasure :slight_smile:

Thanks for your help.

GitHub - 4-20ma/ModbusMaster: Enlighten your Arduino to be a Modbus master Use this library instead to compare CRC behavior. It uses a different core for Modbus RTU and may help you isolate if the issue is specific to ArduinoModbus.

What does "randomly" mean?

Are both good and bad CRCs returned with identical messages?

The posted pattern does not look like random errors to me, because the claimed correction is always in the high four bits of the second byte.

Actually only first two bits..

Thank you for your answer but not sure that this library is up to date. 9 years w/o any update.
Nevertheless, I check it.

Thanks for your message.
When I wrote randomly, I mean that CRC is well calculated for ID 0x01, 0x02 and 0x0C. And therefore, the add-ons answer correctly.
For the rest of ID, the CRC is not conform => no answer from add-ons.

Reason why I think that there is a pb w/ ArduinoModbus library and ModbusRTUClient.requestFrom function.

Maybe I do a mistake but where, I don’t know !

The modbusmaster library suggested above is valid even if not updated. Never tried with Opta though.

Thanks.
I will check it.

So, the CRC error is not random, but consistently incorrect with certain messages.
This calculator agrees with what you posted: Online CRC-8 CRC-16 CRC-32 Calculator

That suggests a problem with the library code, and you should post an issue on the Github site for the library.

Yes, I use this calculator in CRC-16/MODBUS (but not only) to check the CRC result.

Thanks for your advise. I will do that.
Nevertheless, it is very surprising that I didn’t find others topics w/ the same issue.
I imagine that I am not alone to use this library ! There is a lot of example using it.
To be frank I am perplex !

You learned about the problem because the peripheral actually checks the CRC code. It is possible that other peripherals do not perform that check, and no one has noticed.

Quite likely like @jremington said, CRC is not verified.
But did you serialprint the code what was sent? To confirm error in library...

Indeed, you are right. It is a possibility. I didn’t think about that !
Unfortunately, the sensors used for my project check the CRC.

Yes, you can see it w/ my initial post.
It is the data sent from
OPTA by throught ModbusRTUClient.requestFrom function recorded by the snifer.
And when the CRC is correct, the add ons / sensors answer well.

What library prints and what sniffer smells are not exactly the same thing.

Hi @manucast ,

Sorry for your troubles..

Very strange, quick check of the code..
Looks good to me, remember porting this to pascal few years ago..

Pretty much copied directly out of the modbus manual..

crc is added to aid in detecting errors in communications..
and I'm thinking that is what you are seeing..

looks like quite a few sensors, each address i take it as a different device..
how many nodes you got??

good luck.. ~q

Unfortunately, the ModbusRTUClient.requestFrom function doesn't allow to print the data sent. Only set the parameters :

ModbusRTUClient.requestFrom(0x0C, HOLDING_REGISTERS, 0x0004, 1)

Or maybe there is a way to do that but I dont't know how to do.

Thanks for your message.

Indeed, after quick compare, the tables of CRC values are the sames.

At the end of project, not a lot. Only 5x nodes.
But one of sensors was in address 0x04. And after few mn of debug, I saw that the CRC was not conform than expected => no response from it.

Reason why I did a testing w/ more ID to check if it was an isolated cas w/ ID 0x04 or a true issue. And the result ....

I just found the issue !
It is a pb w/ the delay from ArduinoRS485 library and not ArduinoModbus library in conjunction w/ OPTA hardware ! Sorry for the confusion !

To be clear, let's me to explain the postdelay value (see https://github.com/arduino-libraries/ArduinoRS485/blob/master/src/RS485.h :

  • If I keep the default value #define RS485_DEFAULT_POST_DELAY 50, no response from the sensors. I think that it is too quick for OPTA,

  • If I use the recommanded value from different examples, I mean :

    static unsigned int const MODBUS_BAUDRATE      = 9600;
    static float        const MODBUS_BIT_DURATION  = 1.f / MODBUS_BAUDRATE;
    static float        const MODBUS_PRE_DELAY_BR  = MODBUS_BIT_DURATION * 9.6f * 3.5f * 1e6; // == 3500.0
    static float        const MODBUS_POST_DELAY_BR = MODBUS_BIT_DURATION * 9.6f * 3.5f * 1e6; // == 3500.0
    ...
    ...
    RS485.setDelays(MODBUS_PRE_DELAY_BR, MODBUS_POST_DELAY_BR);

the responses of the sensors are truncatured => not conform. I think that it is too low,

  • Therefore, I adapted the delays to 500. I mean :
    RS485.setDelays(500, 500);

And the responses of the sensors were goods but not for all the ID as wrote in my initial post !

  • This morning, I redid a lot of testing. And I modified the delays to 1000. I mean :
    RS485.setDelays(1000, 1000);

And the responses for all the ID sensors are goods :sweat_smile:

Once again, sorry for the confusion.
But I think that we need to find a compromise between the hardware master and the sensors in order to all works well. It can be a little bit complicated for certain case !

Hope my explanation is clear.

FYI, I had this exact same problem and adjusting the Delays to 1000 worked perfectly for me also. Thankyou for your perseverance.