Modbus TCP/IP

what bit are you having trouble with, sending data on Modbus or reading the analog value ?

If I had your challenge here’s how I would break it down. Create a simple program that reads an analog value and displays it using debug.print - change the input voltage over time and make sure my values change. Create a separate program that returns a changing value (increment a variable) every time a Modbus read occurs to your chosen device/register/whatever it’s called. When you get the changing results back on the PC, you know you’re done. Then, instead of just incrementing a value, use your analog read code to return the right value.

@ Brett - My problem is on sends data over Modbus.

It’s a bit near how I wanted to process, I’ve realized reading inputs by changing the voltage in the display with Debug.Print (). This has worked perfectly.

Then I want to achieve the same thing but with the Modbus slave module for ethernet connected to G120HDR. But the problem has to come from the gateway that is misconfigure but sellers of this gateway are not very present to provide assistance.

Thank you for your help, I can move forward in the project !

So I configure “MyModbusDevice” with what I wanted to get.

I want to know, so I deploy the configuration to the G120HDR. And it possible via Modbus read data with a windows forms C # application?

To read two analog Inputs (just as an example) Iwould extend the MyModbusDevice class like this:


public class MyModbusDevice : ModbusDevice
{
...

   private _analogInputs[] _analogIn = new AnalogInput[2]; // make sure These gets initialized somewhere

   protected override ModbusErrorCode OnReadInputRegisters(bool isBroadcast, ushort startAddress, ushort[] registers)
   {
      // check if address and Count is valid
      // this device supports 2 Input Registers at address 0 and 1 which maps two analog inputs

      if (registers.Length < 1 || startAddress + registers.Length > 2)
      {
         return ModbusErrorCode.IllegalDataAddress ;
      }

      for (int n = 0; n < registers.Length; ++n)
      {
         // supposing the analog Inputs provides Maximum a 16 bit unsigned raw value
         registers[n] = (ushort)_analogInputs[startAddress + n].ReadRaw();
      }

      return ModbusErrorCode.NoError;
   }

...
}


(the code was typed in directly in the Forum window, and is not syntax chcked)

To test from windows, you can create a simple test program and use my ModbusMaster class for it.
Or search the internet, there are some Modbus TCP tools out there for sure.

@ Reinhard Ostermeier - Firstly a big thank you for the time you take to help me.
But there will not be a problem because the MyModbusDevice is encoded Micro Framework 4.2 while the windows application is on NET framework 4 Client

My Codeshare project has two projects in the solution.
One for NETMF and one for Windows. Both use the same codebase.
On the windows side you don’t need your MyModbusDevice class.
Just create an instance of ModbusTcpInterface with the ip address of you device as host and a ModbusMaster object, which gets the interface as parameter.
Then call ReadInputRegisters(…) on the ModbusMaster object.

@ Reinhard Ostermeier - I get an error that appears but it comes from the gateway configuration or programming?

Do you get this error on the Windows test program I suggested to write, or on the NETMF device, which should be the Modbus device (where the MyModbusDevice is)?

On a device you should never get there, since it does not connect to anything.
On the device you use the listener stuff.

On the Modbus master side, this is where the connection to the device is established.
All I can read is that you get an SocketException.
Can you send a ping to the IP address from your computer?
no -> The network configuration does not work
yes -> The device does not answer/accept the connection. This can have various reasons

@ Reinhard Ostermeier - I obtien this error on the application windows where I configure the master :

 var tcpInterface = new ModbusTcpInterface("200.200.200.211");
            var master = new ModbusMaster(tcpInterface);

            master.ReadInputRegisters(1, 0, 3, 2000);

The MyModbusDevice NETMF is in the project, where I then deploy the G120HDR :


            var device = new MyModbusDevice(248);
            var listener = ModbusTcpInterface.StartDeviceListener(device);
            device.Start();

If the TCP connection fails, then there is most likely a networking problem.
Try if you get an answer when you type “ping 200.200.200.211” in a console window on your computer.

also:


would read 3 register, starting at address 0 from device with id 1
but since the TCP device has the address 248, you should write

```cs]master.ReadInputRegisters(248, 0, 3, 2000);[/code

@ Reinhard Ostermeier - I sent “ping 200.200.200.211” and I get a good response.

How strange, I still have the same problem. But Ip address I should put instead of Host :

 var tcpInterface = new ModbusTcpInterface(Host);
            var master = new ModbusMaster(tcpInterface);

            master.ReadInputRegisters(248, 0, 3, 2000);

it is the IP address of the master so my PC

I think I don’t understand fully :think:

The code above is the code from your windows application, which runs on your PC, right?
Then host should be a string containing the IP address of your NETMF device.

Is “200.200.200.211” the IP address of your PC or the NETMF device?

@ Reinhard Ostermeier - Ok ! 200.200.200.211 it’s the Ip adress of my PC ! I understand my error. Thank you for your help

@ Reinhard Ostermeier - Would it be possible to have an explanation of the line of code:

 buffer, int pos, ushort value)
      {
         buffer[pos] = (byte)((value & 0xff00) >> 8);
         buffer[pos + 1] = (byte)(value & 0x00ff);
      }

Modbus uses big endian coding for multi byte values.
The Utilities.InsertIntoArray (or similar) uses the C# typical little endian.
So I made me the InsertUShort end ExtractUShort methdos which copies an ushort to and from an byte array in big endian coding.

big endian means that the high value byte comes first in the array,
“value & 0xff00” masks out the low value byte, and only the high value byte stays.
" >> 8" shifts thihe high byte by 8 bits to the right, so it becomes the low byte, which is written 1st into the array.
“value & 0x00ff” mask out the high value byte, so only the low value byte stays, which is written 2nd into the array.
This is not the most performant way to do this I guess, but it works well and fast enough.

My implementation of the Modbus protocol takes fully care of this. You don’t have to handle anything on your own.

@ Reinhard Ostermeier - Yes I know but that’s how you did because this is still very interesting

I thought I did nothing very special here :think: