Skip to content

Commit c33bf3c

Browse files
NikolasK-gitNikolasK-source
authored andcommitted
modbus timeout as argument
1 parent c0e70f0 commit c33bf3c

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR)
44
# ======================================================================================================================
55

66
# project
7-
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.0.3)
7+
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.1.0)
88

99
# settings
1010
set(Target "Modbus_TCP_client_shm") # Executable name (without file extension!)

src/Modbus_TCP_Slave.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,41 @@ bool Slave::handle_request() {
8686
return false;
8787
}
8888

89+
struct timeout_t {
90+
uint32_t sec;
91+
uint32_t usec;
92+
};
93+
94+
static inline timeout_t double_to_timeout_t(double timeout) {
95+
timeout_t ret{};
96+
97+
ret.sec = static_cast<uint32_t>(timeout);
98+
99+
double fractional = timeout - static_cast<double>(ret.sec);
100+
ret.usec = static_cast<uint32_t>(fractional * 1000.0 * 1000.0);
101+
102+
return ret;
103+
}
104+
105+
void Slave::set_byte_timeout(double timeout) {
106+
const auto T = double_to_timeout_t(timeout);
107+
auto ret = modbus_set_byte_timeout(modbus, T.sec, T.usec);
108+
109+
if (ret != 0) {
110+
const std::string error_msg = modbus_strerror(errno);
111+
throw std::runtime_error("modbus_receive failed: " + error_msg + ' ' + std::to_string(errno));
112+
}
113+
}
114+
115+
void Slave::set_response_timeout(double timeout) {
116+
const auto T = double_to_timeout_t(timeout);
117+
auto ret = modbus_set_response_timeout(modbus, T.sec, T.usec);
118+
119+
if (ret != 0) {
120+
const std::string error_msg = modbus_strerror(errno);
121+
throw std::runtime_error("modbus_receive failed: " + error_msg + ' ' + std::to_string(errno));
122+
}
123+
}
124+
89125
} // namespace TCP
90126
} // namespace Modbus

src/Modbus_TCP_Slave.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ class Slave {
5252
*/
5353
bool handle_request();
5454

55+
/*!
56+
* \brief set byte timeout
57+
*
58+
* @details see https://libmodbus.org/docs/v3.1.7/modbus_set_byte_timeout.html
59+
*
60+
* @param timeout byte timeout in seconds
61+
*/
62+
void set_byte_timeout(double timeout);
63+
64+
/*!
65+
* \brief set byte timeout
66+
*
67+
* @details see https://libmodbus.org/docs/v3.1.7/modbus_set_response_timeout.html
68+
*
69+
* @param timeout byte response in seconds
70+
*/
71+
void set_response_timeout(double timeout);
72+
5573
/*! \brief get the modbus socket
5674
*
5775
* @return socket of the modbus connection

src/main.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ int main(int argc, char **argv) {
8686
"output all incoming and outgoing packets to stdout")
8787
("r,reconnect",
8888
"do not terminate if Master disconnects.")
89+
("byte-timeout",
90+
"timeout interval in seconds between two consecutive bytes of the same message. "
91+
"In most cases it is sufficient to set teh response timeout. "
92+
"Fractional values are possible.",
93+
cxxopts::value<double>())
94+
("t,response-timeout",
95+
"set the timeout interval in seconds used to wait for a response. "
96+
"When a byte timeout is set, if elapsed time for the first byte of response is longer than "
97+
"the given timeout, the a timeout is detected."
98+
"When byte timeout is disabled, the full confirmation response must be received before "
99+
"expiration of the response timeout."
100+
"Fractional values are possible.",
101+
cxxopts::value<double>())
89102
("h,help",
90103
"print usage")
91104
("version",
@@ -174,6 +187,20 @@ int main(int argc, char **argv) {
174187
}
175188
socket = slave->get_socket();
176189

190+
// set timeouts if required
191+
try {
192+
if (args.count("response-timeout")) {
193+
slave->set_response_timeout(args["response-timeout"].as<double>());
194+
}
195+
196+
if (args.count("byte-timeout")) {
197+
slave->set_response_timeout(args["byte-timeout"].as<double>());
198+
}
199+
} catch (const std::runtime_error &e) {
200+
std::cerr << e.what() << std::endl;
201+
exit(EX_SOFTWARE);
202+
}
203+
177204
// connection loop
178205
do {
179206
// connect client

0 commit comments

Comments
 (0)