Skip to content

Commit e4957ff

Browse files
committed
Update README
1 parent c878e53 commit e4957ff

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

README.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,39 @@ and [Modbus::Response](http://www.epsilonrt.fr/modbuspp/classModbus_1_1Response.
126126
classes (derived from the
127127
[Modbus::Message](http://www.epsilonrt.fr/modbuspp/classModbus_1_1Message.html) class).
128128

129+
The Server class is used to intercept received messages.
130+
The installation of the callback function is performed by Server::setMessageCallback().
131+
The function thus installed will be called if the slave address (unit identifier)
132+
does not correspond to any slave registered by Server::addSlave().
133+
This will make it possible to process MODBUS messages not supported by libmodbus
134+
or, to route the messages to links not supported by libmodbus.
135+
Here is an example of a callback function:
136+
137+
```cpp
138+
int messageHandler (Message * req, Device * dev) {
139+
cout << "Receive message, size : " << req->aduSize() << endl;
140+
if (req->function() == ReadInputRegisters) {
141+
// the dummy word will be the returned value, incremented after each reading
142+
static uint16_t dummy = 1;
143+
// get request parameters
144+
uint16_t N = req->quantity();
145+
uint16_t index = req->startingAddress();
146+
// build response, see page 16 of MODBUS Application Protocol Specification
147+
Response rsp (*req); // uses copy constructor to keep transaction id
148+
rsp.setSize(1); // keep until function code
149+
rsp.setByteCount (N * 2);
150+
for (uint16_t i = 0; i < N; i++) {
151+
rsp.setRegisterValue (index + i, dummy++);
152+
}
153+
return dev->sendRawMessage (rsp, true);
154+
}
155+
return 0;
156+
}
157+
```
158+
159+
The [virtual-server](https://github.com/epsilonrt/libmodbuspp/blob/slave/examples/server/virtual-server/main.cpp)
160+
example illustrates this functionality.
161+
129162
The [Modbus::Router](http://www.epsilonrt.fr/modbuspp/classModbus_1_1Router.html)
130163
class performs a MODBUS message routing using the additional
131164
address which is a byte which precedes the byte of the function code.
@@ -257,16 +290,15 @@ How beautiful is that ? :-)
257290
The source code of this program is searchable in the examples folder
258291
[router-json](https://github.com/epsilonrt/libmodbuspp/blob/master/examples/router/router-json/main.cpp).
259292
260-
**Note on routing libmodbus in RTU**
261-
---
293+
### Note on routing libmodbus in RTU
262294
263295
libmodbus does not support routing in RTU, in fact, only messages intended for a
264296
single slave (that of the context) or broadcast are processed.
265-
The author of libmodbus, Stéphane justifies this choice in his terms:
266-
_Filter on the Modbus unit identifier (slave) in RTU mode to avoid useless CRC computing._
297+
The author of libmodbus, Stéphane, justifies this choice in his terms:
298+
_"Filter on the Modbus unit identifier (slave) in RTU mode to avoid useless CRC computing."_
267299
To benefit from the routing capacity of the Router and Server classes in RTU,
268-
you must therefore use the modified version of libmodbus.
269-
In this version (3.1.4-3) released from the [piduino](http://apt.piduino.org)
300+
you must therefore use the fork of libmodbus named **libmodbusepsi**.
301+
In this fork released from the [piduino](http://apt.piduino.org)
270302
repository, filtering can be disabled (with _modbus_rtu_set_recv_filter()_).
271303
Thus, it is the Server class which performs this filtering (after checking the
272304
CRC therefore). Effectively, this has the effect of loading the microprocessor,

0 commit comments

Comments
 (0)