How to use ReadInputRegisters() in ModbusIpMaster class?

2,814 views
Skip to first unread message

Chang-Ping

unread,
Jul 9, 2009, 4:31:21 PM7/9/09
to NModbus
Hi:

I am able to use ModbusSerialMaster class to read input registers from
a device, but when I try to use ModbusIpMaster in TCP/IP mode, the
ReadInputRegisters() method just hangs (or awaits) without retrieving
data. Is there anything else I need to do in order to get response
from the device? It listens on port 8000 (and the IP address below
was changed for security purpose, sorry).

Am I missing anything? Thank you for your help and answers.

========= ModBusSerialMaster =========
using (SerialPort port = new SerialPort("COM18"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();

// create modbus master
IModbusSerialMaster master =
ModbusSerialMaster.CreateRtu(port);

byte slaveID = 1;
ushort startAddress = 0;
ushort numInputs = 45;

// read from Input Register
try
{
ushort[] inputs = master.ReadInputRegisters
(slaveID, startAddress, numInputs);

using (StreamWriter w = File.AppendText
("data.txt"))
{
Log(comPort + ", " + DateTime.Now.ToString
() + ",\t", false, w);
for (int i = 0; i < numInputs; i++)
{
Console.WriteLine(i + ": " + inputs
[i]);
if (i < numInputs - 1)
Log(inputs[i].ToString() + ", ",
false, w);
else
Log(inputs[i].ToString(), false,
w);
}
Log("", true, w);

// Close the writer and underlying file.
w.Close();
}
}
catch (Exception ex) { Console.WriteLine
(ex.Message); }
}
========= ModBusIpMaster =========
using (TcpClient client = new TcpClient
("192.168.0.111", 8000))
{
ModbusIpMaster master = ModbusIpMaster.CreateIp
(client);

// read input values
ushort startAddress = 1;
ushort numInputs = 10;
ushort[] inputs = master.ReadInputRegisters
(startAddress, numInputs); // <---- this is where it stops
string s = "";

for (int i = 0; i < numInputs; i++)
s += string.Format("Input {0} = {1}, ",
startAddress + i, inputs[i]);

if (s.EndsWith(", "))
s = s.Substring(0, s.Length - 2);
textBoxData.Text += s + Environment.NewLine;
}

Chang-Ping

unread,
Jul 10, 2009, 11:32:16 AM7/10/09
to NModbus
I found out the code stops at

public int Read(byte[] buffer, int offset, int size)
{
return _tcpClient.GetStream().Read(buffer, offset, size);
}

in TcpClientAdapter.cs class. This was called by

numBytesRead += streamResource.Read(mbapHeader,
numBytesRead, 6 - numBytesRead);

by ReadRequestResponse(IStreamResource streamResource) in
ModbusIpTransport.cs class. This was called by

return CreateMessageAndInitializeTransactionId<T>
(ReadRequestResponse(StreamResource));

by ReadResponse<T>() in ModbusIpTransport.cs. This was called by

response = ReadResponse<T>();

by UnicastMessage<T>(IModbusMessage message) where T : IModbusMessage,
new() in ModbusTransport.cs class. This was called by

ReadHoldingInputRegistersResponse response =
Transport.UnicastMessage<ReadHoldingInputRegistersResponse>(request);

by ReadRegisters(byte functionCode, byte slaveAddress, ushort
startAddress, ushort numberOfPoints) in ModbusMaster.cs.

tcpClient.GetStream() .DataAvailable == false and tcpClient.GetStream
() .ReadTimeout == -1.

Call stack is like this.

Modbus.dll!Modbus.IO.TcpClientAdapter.Read(byte[] buffer = {byte[6]},
int offset = 0, int size = 6) Line 47 C#
Modbus.dll!Modbus.IO.ModbusIpTransport.ReadRequestResponse
(Modbus.IO.IStreamResource streamResource =
{Modbus.IO.TcpClientAdapter}) Line 37 + 0x1e bytes C#
Modbus.dll!
Modbus.IO.ModbusIpTransport.ReadResponse<Modbus.Message.ReadHoldingInputRegistersResponse>
() Line 120 + 0x19 bytes C#
Modbus.dll!
Modbus.IO.ModbusTransport.UnicastMessage<Modbus.Message.ReadHoldingInputRegistersResponse>
(Modbus.Message.IModbusMessage message = {Read 10 input registers
starting at address 1.}) Line 136 + 0x4a bytes C#
Modbus.dll!Modbus.Device.ModbusMaster.ReadRegisters(byte
functionCode = 4, byte slaveAddress = 0, ushort startAddress = 1,
ushort numberOfPoints = 10) Line 190 + 0x29 bytes C#
Modbus.dll!Modbus.Device.ModbusMaster.ReadInputRegisters(byte
slaveAddress = 0, ushort startAddress = 1, ushort numberOfPoints = 10)
Line 75 + 0x1c bytes C#
Modbus.dll!Modbus.Device.ModbusIpMaster.ReadInputRegisters(ushort
startAddress = 1, ushort numberOfPoints = 10) Line 111 + 0x14 bytes C#

Chang-Ping

unread,
Jul 10, 2009, 4:35:51 PM7/10/09
to NModbus
When I use ReadINputRegisters() with port number 502, a Modbus/TCP
request is sent out, but no Modbus/TCP response back; only TCP packet
back. A coworker of mine using a program to send the same request to
the same server, and he gets a Modbus/TCP response back.

4 0.254292 192.168.2.123 10.0.85.11 Modbus/TCP query [ 1 pkt(s)]:
trans: 1; unit: 0, func: 4: Read input registers.
-----------------------------------------------------------------------------------
0000 00 00 0c 07 ac 69 00 1c 23 14 83 2d 08 00 45 00 .....i..
#..-..E.
0010 00 34 cd 97 40 00 80 06 0a fe c0 a8 02 7b 0a 00 .4..@... .....
{..
0020 55 0b 11 b9 01 f6 7b 3b d8 ac a8 bf 42 b5 50 18 U.....
{; ....B.P.
0030 ff ff 3a 6e 00 00 00 01 00 00 00 06 00 04 00
03 ..:n.... ........
0040 00
0a ..

5 0.496728 10.0.85.11 192.168.2.123 TCP asa-appl-proto > wssauthsvc
[ACK] Seq=1 Ack=13 Win=65523 Len=0
-----------------------------------------------------------------------------------
0000 00 1c 23 14 83 2d 00 10 db e0 a1 c0 08 00 45
00 ..#..-.. ......E.
0010 00 28 09 38 40 00 7d 06 d2 69 0a 00 55 0b c0 a8 .(.
8@.}. .i..U...
0020 02 7b 01 f6 11 b9 a8 bf 42 b5 7b 3b d8 b8 50 10 .{...... B.
{;..P.
0030 ff f3 3a 9a 00 00 00 00 00 00 00 00 ..:..... ....

Chang-Ping

unread,
Jul 13, 2009, 6:16:40 PM7/13/09
to NModbus
So far the only working MOSBUS TCP server (slave) is one that I wrote
and run using the code found in "Samples" (http://www.nmodbus.com/
Samples.aspx) on NMODBUS web site. The same code cannot get any
MODBUS TCP response from any other Modbus servers I try to connect.
Nonetheless, using some Modbus master simulators I am able to receive
responses from all Modbus server. This makes me wonder if NMODBUS is
not really working when using ModbusIpMaster.

Any help is appreciated.

Scott Alexander

unread,
Jul 14, 2009, 10:59:56 AM7/14/09
to NModbus...@googlegroups.com
The example code you posted in your first messages shows a Modbus RTU
slave and an IP master. They will not be able to exchange message
properly since the underlying modbus protocol is different. You should
use the ModbusSerialMaster.CreateRtu factory method passing it your
TcpClient.

Scott

Chang-Ping

unread,
Jul 14, 2009, 11:37:18 AM7/14/09
to NModbus
I am not using these two to communicate to each other.
I am using them to connect to a device. Both are masters, not slaves.

The device we are testing claims that it can be connected using Modbus
TCP, and we want to use TCP connection instead of RTU (because the
latter requires installing device driver on every single device and we
will have hundreds of them). The problem we are facing right now is
that using NMODBUS we can send out requests, but no matter which slave
we try to communicate, we cannot receive response back. Using some
Modbus master simulators we downloaded, we are able to receive
responses from Modbus slaves.

On Jul 14, 7:59 am, Scott Alexander <sja...@gmail.com> wrote:
> The example code you posted in your first messages shows a Modbus RTU
> slave and an IP master. They will not be able to exchange message
> properly since the underlying modbus protocol is different. You should
> use the ModbusSerialMaster.CreateRtu factory method passing it your
> TcpClient.
>
> Scott
>

Chang-Ping

unread,
Aug 31, 2009, 2:26:26 PM8/31/09
to NModbus
We figured out where the problem is.
Our code using NModbus is actually working fine if we set the baud
rate for two devices to be the same.
One of our devices claims "automatic baud rate detect", but it doesn't
work too well. According to the company that manufactures it, the
device will negotiate the baud rate with another device connecting to
it a few times, and if the negotiation is successful, it will save the
baud rate as the default until next negotiation is required. The
problem seems to be the time out between two devices so that the
automatically detecting device is never able to save the baud rate
from another device, hence our program trying to read data from the
device always fails.
Reply all
Reply to author
Forward
0 new messages