debevv / nanoMODBUS

A compact MODBUS RTU/TCP C library for embedded/microcontrollers
MIT License
234 stars 47 forks source link

CRC appears to have the wrong byte order #6

Closed ryanshow closed 2 years ago

ryanshow commented 2 years ago

Thanks for the great library!

I was doing some tests and noticed that the CRC checksum on RTU packets seems to have the wrong endianness. I was beating my head against the wall trying to understand why my devices were not responding to requests, and decided to compare the packets emitted by nanomodbus on a raspberry pi pico to what mbpoll emits over a USB->RS485 adapter. The packets were identical, except for the last 2 bytes, which were swapped.

Manually swapping the bytes by modifying the return value of crc_calc seemed to fix the problem for me. ( I tried messing around by manually definining NMBS_BIG_ENDIAN but it swapped the body bytes as well....)

return (crc << 8) + (crc >> 8);

debevv commented 2 years ago

Ow, I'm sorry for the waste of time! I'll have a look at it. It's strange that tests weren't able to catch this, maybe the RTU code is validating the incoming CRCs in the wrong order, too

ryanshow commented 2 years ago

In doing some research, I came across this article which explains this oddity.

https://64k.space/the-modbus-crc-endianness-kerfuffle.html

debevv commented 2 years ago

Looks like I should have read the official RTU document (https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf), I never heard about this little-endian CRC thing. Thank you very much for the discovery. I pushed the fix on master, let me know if everything is ok now.

debevv commented 2 years ago

Solved in 3904a6c52f9a53b5366fd95cf4d6997da6976d40