The Modbus over Serial protocol doc has a clear, simple set of instructions on how to decode. You just have to know that two of the steps are in a reverse order, but it actually makes sense.
The Modbus protocol is used by the Daybetter LED light Bluetooth protocol. It's arguably a terrible fit for this: the protocol includes a bunch of stuff that isn't even slightly relevant with Bluetooth (like the CRC), but doesn't leverage any of the Bluetooth strengths (like the ability to split "color" from "on/off")
Modbus CRC Calculations explained
Here's the official explanation of the CRC calculations from page 14+15 of , modified into a numbered list. Absolutely no changes were made except to make it a list -- that's why there's still weird commas and periods. It's substantially the same as the steps in page 39 to 41 in section 6.2.2 AKA Appendix B.
During generation of the CRC,
- each 8–bit character is exclusive ORed with the register contents.
- Then the result is shifted in the direction of the least significant bit (LSB), with a zero filled into the most significant bit (MSB) position.
- The LSB is extracted and examined.
- If the LSB was a 1, the register is then exclusive ORed with a preset, fixed value. If the LSB was a 0, no exclusive OR takes place.
Note that clear ordering: first you do a shift, then you look at the LSB and do the XOR. BTW, the "preset, fixed value" is 0xA001 (decimal 40961 or binary 1010 0000 0000 0001)
But when you look at the commonly-available Modbus CRC calculations from random Github repositories, the code always switches steps 2 and 3! The LSB is grabbed first! What the heck! why are the clear and unambiguous steps in the official docs not what everyone implements?
Everyone is right because of Microcontrollers!
When you look at high-level languages, a right-shift is just a right shift, possibly with the ability to decide what gets shifted into the MSB (either duplicating the old bit, so a negative number stays negative, or filling it with zeros). But that's not what microcontrollers programmed in assembly do!
A typical microcontroller will do the shift (often with lots more control over the bits) and will also set the carry flag. The next instruction you do can then be a conditional jump based on the carry bit and therefore based on the original LSB.
And indeed, the flowchart diagram from the Modbus protocol doc, appendix B, page 40, labels the item 4 "if" statement as "Carry over" yes/no. They are expecting implementors to use the carry flag or the overflow flag depending on the microcontroller being programmed!
The Modbus flowchart is reproduced below.
Microcontroller assembly
Helpful Links:
Modbus over Serial Line specification and implementation guide