Skip to content

Add ModbusRequest.toRawCRC() function#17

Open
dlugaz wants to merge 3 commits intoMazurel:masterfrom
dlugaz:master
Open

Add ModbusRequest.toRawCRC() function#17
dlugaz wants to merge 3 commits intoMazurel:masterfrom
dlugaz:master

Conversation

@dlugaz
Copy link

@dlugaz dlugaz commented Dec 23, 2024

Add convenience function to generate a complete RTU frame. It's also logical to have a complementary function to ::fromRawCRC()

@david-drinn
Copy link

david-drinn commented Mar 17, 2025

Are the CRC bytes appended in the right order?

// ie. unsigned short const auto crc = MB::utils::calculateCRC(result); result.push_back(reinterpret_cast<const uint8_t *>(&crc)[0]); result.push_back(reinterpret_cast<const uint8_t *>(&crc)[1]); 

It looks correct to me after testing and reviewing the spec and this code.

The Modbus implementation guide says the least-significant byte gets transmitted first.

image

The calculateCRC() function in this library doesn't preemptively try to reorder it for you, instead just giving you the 16-bit CRC value as-is, leaving it to you to serialize it as needed.

// modbusUtils.hpp inline uint16_t calculateCRC(const std::vector<uint8_t> &buffer) { return MB::CRC::calculateCRC(buffer); } // crc.hpp //! Calculate CRC based on the input vector of bytes inline uint16_t calculateCRC(const std::vector<uint8_t> &buffer, std::optional<std::size_t> len = std::nullopt) { std::size_t bufferLength = buffer.size(); if (len.has_value() && bufferLength >= *len) { bufferLength = *len; } return calculateCRC(static_cast<const uint8_t *>(&(*buffer.begin())), bufferLength); } // crc.cpp uint16_t MB::mbCRC::calculateCRC(const uint8_t *buff, std::size_t len) { constexpr uint16_t wCRCTable[] = { // snipped table 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040}; uint8_t nTemp; uint16_t wCRCWord = 0xFFFF; while (len--) { nTemp = *buff++ ^ wCRCWord; wCRCWord >>= 8; wCRCWord ^= wCRCTable[nTemp]; } return wCRCWord; } 

The above result.push_back() calls indeed put the least-significant byte first -- (&crc)[0] first, (&crc)[1] second -- in the serialized message.

@Mazurel
Copy link
Owner

Mazurel commented Oct 28, 2025

Hey, sorry for ignoring this for so long, I will try to look into this in upcoming days. Somehow I completely forgot about this PR :/

@Mazurel Mazurel self-requested a review October 28, 2025 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants