Skip to content

Commit e0c9b6c

Browse files
authored
Merge pull request #158 from arduino-libraries/feature/rtu-pre-post-delay
Feature: class ModbusRTUDelay allows for calculation of minimum inter-frame breaks.
2 parents 5afa436 + f6f9127 commit e0c9b6c

File tree

5 files changed

+63
-12
lines changed

5 files changed

+63
-12
lines changed

Diff for: examples/RTU/ModbusRTUClientParameters/ModbusRTUClientParameters.ino

-12
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,12 @@
1616

1717
constexpr auto baudrate { 19200 };
1818

19-
// Calculate preDelay and postDelay in microseconds as per Modbus RTU Specification
20-
//
21-
// MODBUS over serial line specification and implementation guide V1.02
22-
// Paragraph 2.5.1.1 MODBUS Message RTU Framing
23-
// https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
24-
constexpr auto bitduration { 1.f / baudrate };
25-
constexpr auto wordlen { 9.6f }; // try also with 10.0f
26-
constexpr auto preDelayBR { bitduration * wordlen * 3.5f * 1e6 };
27-
constexpr auto postDelayBR { bitduration * wordlen * 3.5f * 1e6 };
28-
2919
void setup() {
3020
Serial.begin(9600);
3121
while (!Serial);
3222

3323
Serial.println("Modbus RTU Client Toggle w/ Parameters");
3424

35-
RS485.setDelays(preDelayBR, postDelayBR);
36-
3725
// start the Modbus RTU client in 8E1 mode
3826
if (!ModbusRTUClient.begin(baudrate, SERIAL_8E1)) {
3927
Serial.println("Failed to start Modbus RTU Client!");

Diff for: keywords.txt

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#######################################
88

99
ArduinoModbus KEYWORD1
10+
ModbusRTUDelay KEYWORD1
1011
ModbusRTUClient KEYWORD1
1112
ModbusRTUServer KEYWORD1
1213
ModbusRTUClient KEYWORD1
@@ -21,6 +22,9 @@ poll KEYWORD2
2122
end KEYWORD2
2223
setTimeout KEYWORD2
2324

25+
preDelay KEYWORD2
26+
postDelay KEYWORD2
27+
2428
beginTransmission KEYWORD2
2529
write KEYWORD2
2630
endTransmission KEYWORD2

Diff for: src/ModbusRTUClient.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ extern "C" {
2626

2727
#include "ModbusRTUClient.h"
2828

29+
#include "ModbusRTUDelay.h"
30+
2931
ModbusRTUClientClass::ModbusRTUClientClass() :
3032
ModbusClient(1000)
3133
{
@@ -42,6 +44,8 @@ ModbusRTUClientClass::~ModbusRTUClientClass()
4244

4345
int ModbusRTUClientClass::begin(unsigned long baudrate, uint16_t config)
4446
{
47+
_rs485->setDelays(ModbusRTUDelay::preDelay(baudrate), ModbusRTUDelay::postDelay(baudrate));
48+
4549
modbus_t* mb = modbus_new_rtu(_rs485, baudrate, config);
4650

4751
if (!ModbusClient::begin(mb, 0x00)) {

Diff for: src/ModbusRTUDelay.h

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
This file is part of the ArduinoModbus library.
3+
Copyright (c) 2018 Arduino SA. All rights reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#ifndef _MODBUS_RTU_DELAY_H_INCLUDED
21+
#define _MODBUS_RTU_DELAY_H_INCLUDED
22+
23+
class ModbusRTUDelay
24+
{
25+
public:
26+
/* Do not allow construction or copying. */
27+
ModbusRTUDelay() = delete;
28+
ModbusRTUDelay(ModbusRTUDelay const &) = delete;
29+
30+
/* Calculate __minimum__ preDelay and postDelay in
31+
* microseconds as per Modbus RTU Specification.
32+
*
33+
* MODBUS over serial line specification and implementation guide V1.02
34+
* Paragraph 2.5.1.1 MODBUS Message RTU Framing
35+
* https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
36+
*/
37+
static unsigned long const preDelay(unsigned long const baudrate)
38+
{
39+
double const bit_duration = 1. / baudrate;
40+
double const word_len = 9.6f; // try also with 10.0f
41+
double const pre_delay_us = bit_duration * word_len * 3.5f * 1e6;
42+
return static_cast<unsigned long>(pre_delay_us);
43+
}
44+
static unsigned long const postDelay(unsigned long const baudrate)
45+
{
46+
return preDelay(baudrate);
47+
}
48+
};
49+
50+
#endif /* _MODBUS_RTU_DELAY_H_INCLUDED */

Diff for: src/ModbusRTUServer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ extern "C" {
2626

2727
#include "ModbusRTUServer.h"
2828

29+
#include "ModbusRTUDelay.h"
30+
31+
2932
ModbusRTUServerClass::ModbusRTUServerClass()
3033
{
3134
}
@@ -40,6 +43,8 @@ ModbusRTUServerClass::~ModbusRTUServerClass()
4043

4144
int ModbusRTUServerClass::begin(int id, unsigned long baudrate, uint16_t config)
4245
{
46+
_rs485->setDelays(ModbusRTUDelay::preDelay(baudrate), ModbusRTUDelay::postDelay(baudrate));
47+
4348
modbus_t* mb = modbus_new_rtu(_rs485, baudrate, config);
4449

4550
if (!ModbusServer::begin(mb, id)) {

0 commit comments

Comments
 (0)