5

I am using NModbus in a C# project, to read & write Modbus data from/to a number of I/O devices. I am using the Modbus TCP/IP protocol (ModbusIpMaster etc..) in the program.

I have successfully communicated with the devices (through a Modbus gateway) and can use the default methods (e.g. common Modbus functions such as ReadHoldingRegisters, WriteCoils ), to access the data from the devices, and can write back to them. At the moment, all I can do are the default NModbus methods which expose commonly used Modbus codes (1, 2, 3, 4 etc..).

I have two difficulties:

1) The I/O devices' settings and extra information can be accessed under the Modbus code of 70 (0x46), and there are sub functions which I will need to use in order to read and/or write the settings.

For example, Func 07 (0x46), Sub func 6 (0x06), can be used to set the communications settings of a module. In this example there are 7 bytes of information to be sent which carry the settings (e.g. baud rate etc...)

NModbus does not have a specific method for this 'custom' function code (70). So, from what I understand, one needs to use the CustomMessage feature of NModbus. I have tried executing CustomMessage, and when using the common Modbus function codes (e.g. 1 or 2) I can achieve the same result as if I were using the default methods of NModbus (i.e. the CustomMessage is working so far).

When I try function codes other than the general ones (e.g. 1, 2, 3...) I do get all sorts of exceptions. Furthermore, I do not know how I should send the sub-function with the message!

When I added the subfunction just after the function code (e.g. 70 followed by 06), and the data is send through I get, exceptions. I really need help from experts in this field, please.

Here is a more obvious exception:

" Exception of type 'Modbus.SlaveException' was thrown. Function Code: 198 Exception Code: 3 - A value contained in the query data field is not an allowable value for server (or slave). This indicates a fault in the structure of the remainder of a complex request, such as that the implied length is incorrect. It specifically does NOT mean that a data item submitted for storage in a register has a value outside the expectation of the application program, since the MODBUS protocol is unaware of the significance of any particular value of any particular register."

2) The second problem is sending ASCII RS-232 messages through Modbus, in order to control an RS-232 device which is connected to COM1 of a module which has the ability to convert Modbus messages. In other words, I am planning to communicate with the Modbus gateway, to send ASCII data to its COM1, which in turn translates data to RS-232 and then communicates with the RS-232 device. The translation is meant to occur internal to the gateway, so all I need to know is how on Earth I can send these messages through, which vary in length. I have no idea how that is possible, and where to start from.

Elrond_EGLDer
  • 47,430
  • 25
  • 189
  • 180
user1938908
  • 51
  • 1
  • 2

1 Answers1

0

Part 2 - NModbus allows you to create an ASCII master over a TCP or UDP client.

using (TcpClient client = new TcpClient("127.0.0.1", 502))
{
    ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(client);

    // Use the master here
}

With regard to the first part of the question, NModbus is great for the basics, but it lacks a layer of abstraction that would allow it to be extended arbitrarily. My own experience of it ended when I found that it would require significant modification to add and make the GetServerId function to work, even though this is part of the specification for Modbus RTU. My solution was to re-implement it from the ground up, (which took me less time than getting the NModbus source to compile and run in the first place, due to it's dependency on third part libraries for logging, etc & missing extensions for IEnumerable classes).

Evil Dog Pie
  • 2,182
  • 1
  • 17
  • 43