45using ModbusFunctionCode
ESPDEPRECATED(
"Use modbus::FunctionCode instead. Removed in 2027.2.0",
69using ModbusRegisterType
ESPDEPRECATED(
"Use modbus::EntityType instead. Removed in 2027.2.0",
"2026.8.0") =
EntityType;
88using ModbusExceptionCode
ESPDEPRECATED(
"Use modbus::ExceptionCode instead. Removed in 2027.2.0",
92static constexpr uint16_t MAX_NUM_OF_COILS_TO_WRITE = 1968;
95static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_WRITE = 123;
98static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_WRITE_RW = 121;
102static constexpr uint16_t MAX_NUM_OF_COILS_TO_READ = 2000;
103static constexpr uint16_t MAX_NUM_OF_DISCRETE_INPUTS_TO_READ = 2000;
107static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_READ = 125;
110static constexpr uint16_t MIN_FRAME_SIZE = 4;
111static constexpr uint16_t MIN_PDU_SIZE = 1;
112static constexpr uint16_t MAX_PDU_SIZE = 253;
113static constexpr uint16_t MAX_RAW_SIZE = 254;
115static constexpr uint16_t READ_PDU_SIZE = 5;
117static constexpr uint16_t WRITE_SINGLE_PDU_SIZE = 5;
118static constexpr uint16_t MAX_FRAME_SIZE = 256;
121static constexpr uint8_t BROADCAST_ADDRESS = 0;
126static_assert(MAX_PDU_SIZE + 3 == MAX_FRAME_SIZE,
"a framed client PDU must fill the RTU frame limit");
127static_assert(MAX_RAW_SIZE + 2 == MAX_FRAME_SIZE,
"a framed raw server payload must fill the RTU frame limit");
134static_assert(1 +
packed_bit_bytes(MAX_NUM_OF_COILS_TO_READ) <= MAX_RAW_SIZE,
135 "MAX_NUM_OF_COILS_TO_READ yields a read response larger than MAX_RAW_SIZE");
136static_assert(1 +
packed_bit_bytes(MAX_NUM_OF_DISCRETE_INPUTS_TO_READ) <= MAX_RAW_SIZE,
137 "MAX_NUM_OF_DISCRETE_INPUTS_TO_READ yields a read response larger than MAX_RAW_SIZE");
141static_assert(MAX_NUM_OF_COILS_TO_READ == MAX_NUM_OF_DISCRETE_INPUTS_TO_READ,
142 "the coil and discrete-input read ceilings must match");
153 PackedBits(std::span<const uint8_t> data, uint16_t count) : data_(data), count_(count) {}
155 bool operator[](
size_t bit)
const {
return (this->data_[bit / 8] & (1 << (bit % 8))) != 0; }
157 uint16_t
size()
const {
return this->count_; }
161 std::span<const uint8_t>
bytes()
const {
162 return this->data_.first(std::min<size_t>(
packed_bit_bytes(this->count_), this->data_.size()));
166 std::span<const uint8_t> data_;
176 bool operator[](
size_t bit)
const {
return (this->data_[bit / 8] & (1 << (bit % 8))) != 0; }
179 void set(
size_t bit,
bool value) {
180 if (bit >= this->count_ || bit / 8 >= this->data_.size())
183 this->data_[bit / 8] |= (1 << (bit % 8));
185 this->data_[bit / 8] &= ~(1 << (bit % 8));
188 uint16_t
size()
const {
return this->count_; }
192 std::span<uint8_t> data_;
Mutable counterpart of PackedBits: set() writes bits in place (deliberately no proxy operator[]=).
MutablePackedBits(std::span< uint8_t > data, uint16_t count)
void set(size_t bit, bool value)
Set or clear the given bit.
bool operator[](size_t bit) const
Read-only view of Modbus-packed bits: bit 0 of byte 0 is the first bit (LSB first),...
bool operator[](size_t bit) const
Value of the given bit; bit must be < size().
std::span< const uint8_t > bytes() const
The underlying packed bytes: exactly ceil(size() / 8) bytes, even when the view was constructed over ...
uint16_t size() const
Number of bits in the view.
PackedBits(std::span< const uint8_t > data, uint16_t count)
const uint8_t FUNCTION_CODE_MASK
const uint8_t FUNCTION_CODE_EXCEPTION_MASK
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_INIT
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_INIT
Modbus definitions from specs: https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3....
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_END
@ WRITE_MULTIPLE_REGISTERS
@ READ_WRITE_MULTIPLE_REGISTERS
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_END
bool operator!=(FunctionCode lhs, uint8_t rhs)
@ GATEWAY_PATH_UNAVAILABLE
@ GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND
bool operator==(FunctionCode lhs, uint8_t rhs)
constexpr size_t packed_bit_bytes(size_t bits)
Bits pack 8 per data byte, rounded up to whole bytes.