54 ESP_LOGVV(TAG,
"Modbus received Byte %d (0X%x)",
byte,
byte);
59 uint8_t function_code =
raw[1];
65 uint8_t data_len =
raw[2];
66 uint8_t data_offset = 3;
69 if (((function_code >= 65) && (function_code <= 72)) || ((function_code >= 100) && (function_code <= 110))) {
83 uint16_t computed_crc =
crc16(
raw, data_offset + data_len);
84 uint16_t remote_crc = uint16_t(
raw[data_offset + data_len]) | (uint16_t(
raw[data_offset + data_len + 1]) << 8);
86 if (computed_crc != remote_crc)
89 ESP_LOGD(TAG,
"Modbus user-defined function %02X found", function_code);
99 if (function_code == 0x5 || function_code == 0x06 || function_code == 0xF || function_code == 0x10) {
106 if ((function_code & 0x80) == 0x80) {
112 if (at < data_offset + data_len)
116 if (at == data_offset + data_len)
120 uint16_t computed_crc =
crc16(
raw, data_offset + data_len);
121 uint16_t remote_crc = uint16_t(
raw[data_offset + data_len]) | (uint16_t(
raw[data_offset + data_len + 1]) << 8);
122 if (computed_crc != remote_crc) {
124 ESP_LOGD(TAG,
"Modbus CRC Check failed, but ignored! %02X!=%02X", computed_crc, remote_crc);
126 ESP_LOGW(TAG,
"Modbus CRC Check failed! %02X!=%02X", computed_crc, remote_crc);
131 std::vector<uint8_t> data(this->
rx_buffer_.begin() + data_offset, this->rx_buffer_.begin() + data_offset + data_len);
133 for (
auto *device : this->
devices_) {
134 if (device->address_ ==
address) {
136 if ((function_code & 0x80) == 0x80) {
137 ESP_LOGD(TAG,
"Modbus error function code: 0x%X exception: %d", function_code,
raw[2]);
139 device->on_modbus_error(function_code & 0x7F,
raw[2]);
142 ESP_LOGD(TAG,
"Ignoring Modbus error - not expecting a response");
145 device->on_modbus_read_registers(function_code, uint16_t(data[1]) | (uint16_t(data[0]) << 8),
146 uint16_t(data[3]) | (uint16_t(data[2]) << 8));
148 device->on_modbus_data(data);
156 ESP_LOGW(TAG,
"Got Modbus frame from unknown address 0x%02X! ",
address);
160 ESP_LOGV(TAG,
"Clearing buffer of %d bytes - parse succeeded", at);
176void Modbus::send(uint8_t
address, uint8_t function_code, uint16_t start_address, uint16_t number_of_entities,
177 uint8_t payload_len,
const uint8_t *payload) {
178 static const size_t MAX_VALUES = 128;
182 if (number_of_entities > MAX_VALUES && function_code <= 0x10) {
183 ESP_LOGE(TAG,
"send too many values %d max=%zu", number_of_entities, MAX_VALUES);
187 std::vector<uint8_t> data;
189 data.push_back(function_code);
191 data.push_back(start_address >> 8);
192 data.push_back(start_address >> 0);
193 if (function_code != 0x5 && function_code != 0x6) {
194 data.push_back(number_of_entities >> 8);
195 data.push_back(number_of_entities >> 0);
199 if (payload !=
nullptr) {
201 data.push_back(payload_len);
205 for (
int i = 0; i < payload_len; i++) {
206 data.push_back(payload[i]);
210 auto crc =
crc16(data.data(), data.size());
211 data.push_back(crc >> 0);
212 data.push_back(crc >> 8);