[modbus] Only apply turnaround delay after broadcasts (#17209)

This commit is contained in:
Jonathan Swoboda
2026-06-25 11:38:34 -04:00
committed by GitHub
parent 18c7f60410
commit 1d5490fd91
4 changed files with 93 additions and 5 deletions
+11 -5
View File
@@ -92,10 +92,14 @@ int32_t Modbus::tx_delay_remaining() {
int32_t ModbusClientHub::tx_delay_remaining() {
const uint32_t now = millis();
return std::max({(int32_t) 0,
(int32_t) (this->last_send_tx_offset_ + this->frame_delay_ms_ + this->turnaround_delay_ms_ -
(now - this->last_send_)),
(int32_t) (this->frame_delay_ms_ + this->turnaround_delay_ms_ - (now - this->last_modbus_byte_))});
// Turnaround delay only applies after a broadcast: no response is expected, so we must give listening devices
// quiet time to process it before the next request. For normal unicast request/response the received reply already
// provides the inter-frame timing, so adding turnaround there just throttles throughput.
const uint16_t turnaround = this->last_send_was_broadcast_ ? this->turnaround_delay_ms_ : 0;
return std::max(
{(int32_t) 0,
(int32_t) (this->last_send_tx_offset_ + this->frame_delay_ms_ + turnaround - (now - this->last_send_)),
(int32_t) (this->frame_delay_ms_ + turnaround - (now - this->last_modbus_byte_))});
}
bool Modbus::tx_blocked() {
@@ -396,6 +400,7 @@ bool Modbus::send_frame_(const ModbusFrame &frame) {
format_hex_pretty_to(hex_buf, frame.data.get(), frame.size), now - this->last_send_,
now - this->last_modbus_byte_);
this->last_send_ = now;
this->last_send_was_broadcast_ = frame.size > 0 && frame.data[0] == 0;
return true;
}
@@ -411,7 +416,8 @@ void ModbusClientHub::send_next_frame_() {
ModbusDeviceCommand &command = this->tx_buffer_.front();
if (this->send_frame_(command.frame)) {
this->waiting_for_response_ = std::move(command);
if (!this->last_send_was_broadcast_)
this->waiting_for_response_ = std::move(command);
} else {
if (command.device)
command.device->on_modbus_not_sent();