Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
21.02.2021, 13:07
(This post was last modified: 21.02.2021, 13:56 by m.j.sorokin.)
Good day!
There is an unclear problem with the Modbus TCP connection. The controller has restrictions on the number of registers requested at a time (no more than 16), and the controller can only process group requests for reading registers, the function read single registers is not supported. in this regard, I use the program code and not the modbus profiles.
Faced a very strange problem. Initially, I checked by reading the modbus pull program, when using it, I can open and close the connection many times in a row and the controller works it out correctly, but when using a fairly standard code for the logic machine, the datakom controller stops responding after several requests and even to connect the modus pull program as well does not connect. What could be the reason, did anyone come across a similar one?
description of the modus protocol for the datakom d-200 mk2 controller: http://datakom.com.tr/upload/Files/500_MODBUS.pdf
example of code i am using:
Code: require('luamodbus')
mb = luamodbus.tcp()
mb:open('10.36.0.25', 502)
--mb:setresponsetimeout(5)
if mb:connect() then
log('connect')
reg10240, reg10241, reg10242, reg10243, reg10244, reg10245, reg10246 = mb:readregisters(10240,7)
if (reg10240 ~= nil) then log('Mains phase L1 voltage: '..reg10240) end
if (reg10242 ~= nil) then log('Mains phase L2 voltage: '..reg10242) end
if (reg10244 ~= nil) then log('Mains phase L3 voltage: '..reg10244) end
if (reg10246 ~= nil) then log('Genset phase L1 voltage: '..reg10246) end
os.sleep(0.5)
reg10338, reg10339, reg10340, reg10341 = mb:readregisters(10338,4)
if (reg10338 ~= nil) then log('Mains frequency: '..reg10338) end
if (reg10339 ~= nil) then log('Genset frequency: '..reg10339) end
if (reg10341 ~= nil) then log('Battery voltage: '..reg10341) end
mb:close()
else
log('read error reg10240...reg10246')
end
mb:close()
To restore communication with the controller, only its power restart helps, reconnecting the etnernet line does not remove the problem
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
There's no "read single register" function in modbus, this only applies to writing where there are two different commands for single/multiple registers.
Keep in mind that voltage registers are 32-bit so each value consists of 2 registers. This might be why profile was not working for you.
Another thing is that you should not close the connection after each run. Profiles also support this by enabling "persistent" connection mode.
See if this works for you:
Code: if not mb then
require('luamodbus')
mb = luamodbus.tcp()
mb:open('10.36.0.25', 502)
mb:setresponsetimeout(5)
res, err = mb:connect()
if not res then
log('modbus connect failed ' .. tostring(err))
mb:close()
mb = nil
end
end
if mb then
reg10240, reg10241, reg10242, reg10243, reg10244, reg10245, reg10246, reg10247 = mb:readregisters(10240, 8)
if reg10240 then
mains_l1_voltage = reg10240 * 0x10000 + reg10241
mains_l2_voltage = reg10242 * 0x10000 + reg10243
mains_l3_voltage = reg10244 * 0x10000 + reg10245
genset_l1_voltage = reg10246 * 0x10000 + reg10247
log('voltage values', mains_l1_voltage, mains_l2_voltage, mains_l3_voltage, genset_l1_voltage)
else
log('modbus read failed ' .. tostring(reg10241))
mb:close()
mb = nil
end
end
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
Unfortunately, this did not help. Log after restarting the controller:
DGU_modbus_tcp 22.02.2021 20:47:47
* arg: 1
* string: voltage values
* arg: 2
* number: 157089792
* arg: 3
* number: 154992640
* arg: 4
* number: 154075136
* arg: 5
* number: 0
DGU_modbus_tcp 22.02.2021 20:47:57
* string: modbus read failed Invalid data
DGU_modbus_tcp 22.02.2021 20:48:07
* arg: 1
* string: voltage values
* arg: 2
* number: 155320320
* arg: 3
* number: 154992640
* arg: 4
* number: 155844608
* arg: 5
* number: 0
DGU_modbus_tcp 22.02.2021 20:48:18
* string: modbus read failed Invalid data
DGU_modbus_tcp 22.02.2021 20:48:28
* arg: 1
* string: voltage values
* arg: 2
* number: 154796032
* arg: 3
* number: 154599424
* arg: 4
* number: 156958720
* arg: 5
* number: 0
DGU_modbus_tcp 22.02.2021 20:48:38
* string: modbus read failed Invalid data
DGU_modbus_tcp 22.02.2021 20:48:48
* arg: 1
* string: voltage values
* arg: 2
* number: 155451392
* arg: 3
* number: 154337280
* arg: 4
* number: 155910144
* arg: 5
* number: 0
DGU_modbus_tcp 22.02.2021 20:48:58
* string: modbus read failed Invalid data
DGU_modbus_tcp 22.02.2021 20:49:13
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 22.02.2021 20:49:28
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 22.02.2021 20:49:43
* string: modbus connect failed Operation in progress
(Then the controller stops responding, and restarting the script also does not help, only restarting the controller.)
I do not understand the moment why when using the modbus pull, even with several connections and subsequent disconnections, the connection is restored, and when connecting to the logic machine, the controller completely stops responding?
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
Seems to be a networking issue of some kind. Try running the same script with debug mode enabled and post what you get in Logs tab.
Code: if not mb then
require('luamodbus')
mb = luamodbus.tcp()
mb:setresponsetimeout(5)
mb:open('10.36.0.25', 502)
res, err = mb:connect()
if res then
buffer = {}
mb:setdebug(function(msg)
buffer[ #buffer + 1 ] = msg
end)
else
log('modbus connect failed ' .. tostring(err))
mb:close()
mb = nil
end
end
if mb then
reg10240, reg10241, reg10242, reg10243, reg10244, reg10245, reg10246, reg10247 = mb:readregisters(10240, 8)
if reg10240 then
mains_l1_voltage = reg10240 / 10
mains_l2_voltage = reg10242 / 10
mains_l3_voltage = reg10244 / 10
genset_l1_voltage = reg10246 / 10
log('voltage values', mains_l1_voltage, mains_l2_voltage, mains_l3_voltage, genset_l1_voltage)
log(table.concat(buffer))
buffer = {}
else
log('modbus read failed ' .. tostring(reg10241))
mb:close()
mb = nil
end
end
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
24.02.2021, 20:25
(This post was last modified: 24.02.2021, 20:54 by m.j.sorokin.)
I checked with the debug code, previously I tried several times to connect and disconnect the modbus pull application (all timeouts by default), everything worked correctly, and I also ran the 'ping 10.36.0.25 -t' command on the laptop to track the network connection. I ran the script on logic machine, the script gave the following log:
DGU_modbus_tcp 24.02.2021 22:56:59
* arg: 1
* string: voltage values
* arg: 2
* number: 242.7
* arg: 3
* number: 242.8
* arg: 4
* number: 241.8
* arg: 5
* number: 0
DGU_modbus_tcp 24.02.2021 22:56:59
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><7B><00><00><09><7C><00><00><09><72><00><00><00><00><00><00>
DGU_modbus_tcp 24.02.2021 22:57:10
* string: modbus read failed Invalid data
DGU_modbus_tcp 24.02.2021 22:57:20
* arg: 1
* string: voltage values
* arg: 2
* number: 244.1
* arg: 3
* number: 241.1
* arg: 4
* number: 242.2
* arg: 5
* number: 0
DGU_modbus_tcp 24.02.2021 22:57:20
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><89><00><00><09><6B><00><00><09><76><00><00><00><00><00><00>
DGU_modbus_tcp 24.02.2021 22:57:30
* string: modbus read failed Invalid data
DGU_modbus_tcp 24.02.2021 22:57:41
* string: modbus read failed Operation timed out
DGU_modbus_tcp 24.02.2021 22:57:51
* arg: 1
* string: voltage values
* arg: 2
* number: 243.7
* arg: 3
* number: 243
* arg: 4
* number: 241.2
* arg: 5
* number: 0
DGU_modbus_tcp 24.02.2021 22:57:51
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><85><00><00><09><7E><00><00><09><6C><00><00><00><00><00><00>
DGU_modbus_tcp 24.02.2021 22:58:01
* string: modbus read failed Invalid data
DGU_modbus_tcp 24.02.2021 22:58:11
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:58:22
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:58:32
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:58:43
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:58:53
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:59:04
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 24.02.2021 22:59:14
* string: modbus connect failed Operation in progress
ping was without a single timeout. But after stopping the script, I was no longer able to connect through the modbus poll program, the following error is returned: "Modbus/TCP Connection Failed.Connect Timeout.Open Command Prompt and ping the slave/server to verify the connection"
There were no ping problems during the entire check
after running the script again, the connection was also not restored and the device stopped responding to the ping command.
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
It's strange that you get "invalid data" first. This might indicate that the device is faulty.
I've made a mistake in the previous test script so it does not log communication in case of an error. Run this and post what you get in Logs tab:
Code: if not mb then
require('luamodbus')
mb = luamodbus.tcp()
mb:setresponsetimeout(5)
mb:open('10.36.0.25', 502)
res, err = mb:connect()
if res then
buffer = {}
mb:setdebug(function(msg)
buffer[ #buffer + 1 ] = msg
end)
else
log('modbus connect failed ' .. tostring(err))
mb:close()
mb = nil
end
end
if mb then
reg10240, reg10241, reg10242, reg10243, reg10244, reg10245, reg10246, reg10247 = mb:readregisters(10240, 8)
if reg10240 then
mains_l1_voltage = reg10240 / 10
mains_l2_voltage = reg10242 / 10
mains_l3_voltage = reg10244 / 10
genset_l1_voltage = reg10246 / 10
log('voltage values', mains_l1_voltage, mains_l2_voltage, mains_l3_voltage, genset_l1_voltage)
else
log('modbus read failed ' .. tostring(reg10241))
mb:close()
mb = nil
end
log(table.concat(buffer))
buffer = {}
end
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
DGU_modbus_tcp 25.02.2021 18:11:00
* arg: 1
* string: voltage values
* arg: 2
* number: 243.5
* arg: 3
* number: 235.4
* arg: 4
* number: 235.8
* arg: 5
* number: 0
DGU_modbus_tcp 25.02.2021 18:11:00
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><83><00><00><09><32><00><00><09><36><00><00><00><00><00><00>
DGU_modbus_tcp 25.02.2021 18:11:10
* string: modbus read failed Invalid data
DGU_modbus_tcp 25.02.2021 18:11:10
* string: [00][02][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<1A><00><02><00><00><00><13><FF><03>
Invalid transaction ID received 0x1A00 (not 0x2)
DGU_modbus_tcp 25.02.2021 18:11:20
* arg: 1
* string: voltage values
* arg: 2
* number: 243.7
* arg: 3
* number: 236.5
* arg: 4
* number: 234.6
* arg: 5
* number: 0
DGU_modbus_tcp 25.02.2021 18:11:20
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><85><00><00><09><3D><00><00><09><2A><00><00><00><00><00><00>
DGU_modbus_tcp 25.02.2021 18:11:30
* string: modbus read failed Invalid data
DGU_modbus_tcp 25.02.2021 18:11:30
* string: [00][02][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<1A><00><02><00><00><00><13><FF><03>
Invalid transaction ID received 0x1A00 (not 0x2)
DGU_modbus_tcp 25.02.2021 18:11:40
* arg: 1
* string: voltage values
* arg: 2
* number: 244.3
* arg: 3
* number: 237.8
* arg: 4
* number: 231.3
* arg: 5
* number: 0
DGU_modbus_tcp 25.02.2021 18:11:40
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><8B><00><00><09><4A><00><00><09><09><00><00><00><00><00><00>
DGU_modbus_tcp 25.02.2021 18:11:51
* string: modbus read failed Invalid data
DGU_modbus_tcp 25.02.2021 18:11:51
* string: [00][02][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<1A><00><02><00><00><00><13><FF><03>
Invalid transaction ID received 0x1A00 (not 0x2)
DGU_modbus_tcp 25.02.2021 18:12:01
* arg: 1
* string: voltage values
* arg: 2
* number: 243.4
* arg: 3
* number: 237
* arg: 4
* number: 233.4
* arg: 5
* number: 0
DGU_modbus_tcp 25.02.2021 18:12:01
* string: [00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><82><00><00><09><42><00><00><09><1E><00><00><00><00><00><00>
DGU_modbus_tcp 25.02.2021 18:12:11
* string: modbus read failed Invalid data
DGU_modbus_tcp 25.02.2021 18:12:11
* string: [00][02][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<1A><00><02><00><00><00><13><FF><03>
Invalid transaction ID received 0x1A00 (not 0x2)
DGU_modbus_tcp 25.02.2021 18:12:21
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 25.02.2021 18:12:32
* string: modbus connect failed Operation in progress
DGU_modbus_tcp 25.02.2021 18:12:42
* string: modbus connect failed Operation in progress
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
The illegal data error seems to come from the device sending some extra byte when it should not. Unfortunately it's hard to tell why the connection stops working. Try this test script which discards any stale data before reading.
Code: if not mb then
require('luamodbus')
mb = luamodbus.tcp()
mb:setresponsetimeout(5)
mb:open('10.36.0.25', 502)
res, err = mb:connect()
if res then
buffer = {}
mb:setdebug(function(msg)
buffer[ #buffer + 1 ] = msg
end)
else
log('modbus connect failed ' .. tostring(err))
mb:close()
mb = nil
end
end
if mb then
mb:flush()
reg10240, reg10241, reg10242, reg10243, reg10244, reg10245, reg10246, reg10247 = mb:readregisters(10240, 8)
if reg10240 then
mains_l1_voltage = reg10240 / 10
mains_l2_voltage = reg10242 / 10
mains_l3_voltage = reg10244 / 10
genset_l1_voltage = reg10246 / 10
log('voltage values', mains_l1_voltage, mains_l2_voltage, mains_l3_voltage, genset_l1_voltage)
else
log('modbus read failed ' .. tostring(reg10241))
mb:close()
mb = nil
end
log(table.concat(buffer))
buffer = {}
end
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
it looks like the mb:flush() has solved the problem. I also tested stopping and running the script several times, everything works correctly. The controller does not hang.
DGU_modbus_tcp 01.03.2021 13:24:10
* arg: 1
* string: voltage values
* arg: 2
* number: 240.8
* arg: 3
* number: 241
* arg: 4
* number: 236.6
* arg: 5
* number: 0
DGU_modbus_tcp 01.03.2021 13:24:10
* string: Bytes flushed (0)
[00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><68><00><00><09><6A><00><00><09><3E><00><00><00><00><00><00>
DGU_modbus_tcp 01.03.2021 13:24:20
* arg: 1
* string: voltage values
* arg: 2
* number: 240.2
* arg: 3
* number: 240.9
* arg: 4
* number: 237.4
* arg: 5
* number: 0
DGU_modbus_tcp 01.03.2021 13:24:20
* string: Bytes flushed (1)
[00][02][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><02><00><00><00><13><FF><03><10><09><62><00><00><09><69><00><00><09><46><00><00><00><00><00><00>
DGU_modbus_tcp 01.03.2021 13:24:30
* string: modbus read failed Operation timed out
DGU_modbus_tcp 01.03.2021 13:24:30
* string: Bytes flushed (1)
[00][03][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
ERROR Operation timed out: select
DGU_modbus_tcp 01.03.2021 13:24:41
* arg: 1
* string: voltage values
* arg: 2
* number: 238.8
* arg: 3
* number: 241.2
* arg: 4
* number: 237.6
* arg: 5
* number: 0
DGU_modbus_tcp 01.03.2021 13:24:41
* string: Bytes flushed (0)
[00][01][00][00][00][06][FF][03][28][00][00][08]
Waiting for a confirmation...
<00><01><00><00><00><13><FF><03><10><09><54><00><00><09><6C><00><00><09><48><00><00><00><00><00><00>
DGU_modbus_tcp 01.03.2021 13:24:51
* arg: 1
* string: voltage values
* arg: 2
* number: 239.8
* arg: 3
* number: 239.4
* arg: 4
* number: 238.1
* arg: 5
* number: 0
Is there a complete description of the luamodbus library with all supported commands? On the web, I found only individual parts of the code without a detailed description of the functions...
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
Unfortunately there's no full documentation because the recommended approach is to use profiles.
There seems to be a problem in the Datakom controller. Flush is used when a the read request times out to remove any partial data from the buffer. Otherwise next read calls can fail dues to erroneous data that is already in the buffer. This is the first time that I've seen that flush is needed for TCP communication though.
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
It is very likely that the problem is in the controller after about 5 hours of operation a similar situation with the controller hanging...
Posts: 12
Threads: 2
Joined: Nov 2017
Reputation:
4
Is the setresponsetimeout parameter set in seconds or milliseconds? in the examples on the forum, there are both so and so... and what is it by default if it is not specifically set? In what place is it correct to specify it, before opening the port or after?
According to the manufacturer, it should be at least a second....
Posts: 7764
Threads: 42
Joined: Jun 2015
Reputation:
447
The timeout value is in seconds, it should be set before connect()
|