In your case, I would suggest a simpler solution - using Modbus TCP over Serial Gateway. This will allow you to send Modbus TCP requests to your router, which will then translate TCP to RTU and redirect the request to your serial Modbus Slave. Essentially, this would allow you to access Modbus RTU slave via Modbus TCP. You can find more information on this functionality on our wiki page here.
I have several Modbus RTU devices attached to a RS485 bus, so I need to read from several slaves and serve these data as Modbus/TCP. The router RUT955 should work as a gateway in this case.
I’m open to different solutions: mqtt, Modbus/TCP, … anything that allows to concentrate data from several slaves.
Well, with serial gateway the device acts as a gateway. It receives Modbus TCP requests sent to the router, interprets these requests, and then communicates with the Modbus RTU slaves to retrieve the requested data. Once it has the data, it sends this information back in response to the original Modbus TCP request. So in both cases, you send Modbus TCP requests to the router.
If you are looking to concentrate all the data from different slaves, then I assume you need to collect this data (no need to set registers). Correct?
If so, what about the data to server functionality? You can collect all the data from your Modbus slave devices and send it to the server over HTTP or MQTT in JSON format. This would probably be the best option.
MQTT Gateway can also be used, but this would be similar to Serial Gateway with the main difference that MQTT is used instead of Modbus. So you will need to send MQTT messages that will be translated to Modbus RTU and sent to the Modbus slaves.
In fact, I’m using Mosquitto on a RBPi and it works (I’m publishing values from another device), but I have configured a RUT955 as Publisher but nothing appears on Mosquitto.
How can I publish the read Modbus data on Mosquitto ?
There no need to configure MQTT publisher in this case. Simply configure ‘Data to Server’. Select Modbus as the data source, MQTT as the protocol, enter the JSON format, and fill in the rest of the settings according to your needs. Though, you need to have Modbus Serial Master configured with the requests on the device. Data from these requests is stored in the database and is periodically sent by ‘Data to Server’.
RUT955 configured as Modbus/TCP slave and master. The router is reading registers 42 (name) and 2 (uptime) every 10 seconds. I’m using “TEST” button to check that these values are read.
Data to Server:
Enable: On
Name: test
Data source: Modbus data
Protocol: MQTT
JSON format: {“ID”:“%i”,“TS”:“%t”,“ST”:“%s”,“VR”:%a}
Segment count: 1
Send as object: off
URL / Host / Connection string: Mosquitto_server_IP → also tested with local RUT955 MQTT broker, but same result
Port: 1883
Keepalive: 60
Topic: /router
Client ID:
Period: 10
QoS: 0
Data filtering: All data
Unfortunately, MQTT explorer is not showing the topic “/router”, where is the problem?
I think it would be much easier to map the collected Modbus data to the custom register block, avoiding external protocols as MQTT, but it’s not currently possible.
Edit:
ssh on RUT955:
root@RUT955:~# netstat -ptan | grep 204
tcp 0 0 192.168.9.137:55350 192.168.9.204:1883 ESTABLISHED 6452/modbus_data_se
/var/log/mosquitto/mosquitto.log on RBPi
…
1689104184: New client connected from 192.168.9.137:36806 as auto-5AB8F07C-880F-7C71-F946-2566DB8901A4 (p2, c1, k60).
1689104247: Client mqtt-explorer-6a4a20db disconnected.
1689104248: New connection from 192.168.9.20:36748 on port 1883.
1689104248: New client connected from 192.168.9.20:36748 as mqtt-explorer-6a4a20db (p2, c1, k60).
1689104346: Client auto-5AB8F07C-880F-7C71-F946-2566DB8901A4 closed its connection.
1689104347: New connection from 192.168.9.137:60968 on port 1883.
1689104347: New client connected from 192.168.9.137:60968 as auto-11A6DD36-3326-B0C1-FDD3-F681850BCCB2 (p2, c1, k60).
1689104438: Client auto-11A6DD36-3326-B0C1-FDD3-F681850BCCB2 has exceeded timeout, disconnecting.
1689104551: New connection from 192.168.9.137:55350 on port 1883.
1689104551: New client connected from 192.168.9.137:55350 as auto-179ED496-8F77-0F97-626D-04A48F22EF95 (p2, c1, k60).
When I first read your reply, I entered to the router’s web from my phone and the radio buttons displayed properly, they made sense. When I accessed from a laptop, they shown in a confusing way, now it works like a charm:
I am having similar kind of problem. I want to read modbus data from slave device and publsh data to MQTT server. I am facing issue of decoding/degrouping of modbus address values. Can you please help with the same?
i.e. actual flow = value of 400001 address
pressure = value of 400007 address
I am not able to configure the above. By default the router is giving values like [2345], [3567] values as per the data sender segment configuration. Can we specify the same?
Router is sending both addresses values to the server. i.e. By writing “%a” in the jason format we get [2345], [3456] (register data) sequentially.
Whereas requirement is
actual flow = value of 40001 address
pressure = value of 40007 address.
I want to dedicate specific register values against specific string as mentioned in above thread. Hope i am able to make you understand the issue.
How can i access root? what is ubus command? I am new to it. I have read in some threads that we can call specific address/bit values using root and ubus command. How can i do that?
i am not facing any issue in data sending. Just want to extract register values as against specific string/texts.
Modbus registers are 2 bytes long (16 bit). In the Modbus Master configuration, when you configure requests, you can specify the data type of how that register is presented. For this, you would need to refer to the modbus documentation of your Modbus Slave device to find out what data type to use (Byte order). This is applicable for each individual request.
Now for the format of the message as a whole, if you want to receive data as follows:
"request_name":"value"
Then, in Data to Server configuration, use the following JSON format:
{"%r":"%a"}
“%r” will be the request name from Modbus Master request configuration, and “%a” will be the modbus register value in a format that you set in the request configuration as well. You can either keep or remove quotes and brackets (square brackets for each request can be removed in Modbus Master configuration by enabling the ‘brackets’ option for requests).
{
“version” : “1.0”,
“onlinetag” : “06171422010486”,
“time” : %t,
“payload” : [ {
“subDeviceId” : “ttyCOM1_2”,
“deviceType” : “Modbus_2”,
“status” : {
“ActualFlow” : “Value of respective Modbus register address to be displayed here”,
“TotalFlow” : “Value of respective Modbus register address to be displayed here”,
“InsDiagnostic” : “Value of respective Modbus register address to be displayer here”,
“timestamp” : %t
}
} ]
}
i want to display user defined register values against actual flow/totalflow/InstDiagnostic strings…
Due to limitation of replies
AndzejJ,
Thank you for your prompt response. I have checked by changing all segment count to ‘all’, ‘1’, ‘2’ also but it is giving the values alternatively as mentioned above.
Router by default taking “strings+value of first register”, “strings+value of second register”, strings+value of third register" like that…if selected segment count “all”.
I want “strings+value of first register+value of second register+value of third register” like that.
I want to get values in following format.
{
“version” : “1.0”,
“onlinetag” : “06171422010486”,
“time” : %t,
“payload” : [ {
“subDeviceId” : “ttyCOM1_2”,
“deviceType” : “Modbus_2”,
“status” : {
“Request_ActualFlow” : “Value”, Value of 1st register
“Request_TotalFlow” : “Value”, Value of 2nd register
“Request_InsDiagnostic” : “Value”, Value of 3rd register
“timestamp” : %t
}
} ]
}