From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Real-Time Measurement and Control

cancel
Showing results for 
Search instead for 
Did you mean: 

Modbus TCP protocol violation

Hello,

 

I am using the Real-Time Module's in-built Modbus Ethernet I/O server and I have found an issue with the Modbus implementation. Due to this issue, we are unable to talk to multiple sbRIO devices utilizing the serial/tcp gateway we are using as part of our overall solution.

 

TCP Modbus Spec says:

Unit Identifier – This field is used for intra-system routing purpose. It is typically used to communicate to a MODBUS+ or a MODBUS serial line slave through a gateway between an Ethernet TCP-IP network and a MODBUS serial line. This field is set by the MODBUS Client in the request and must be returned with the same value in the response by the server

 

What I have found is that the sbRIO-9606 will not respond at all if the unit id is anything but 1 (or the value assigned in the server settings). Typically the unit id will be "FF" or 255 in an all tcp solution as required by the spec, the sbRIO will not respond to this value either.

 

 

Also from spec:

 

Unit Identifier

This field is used for routing purpose when addressing a device on a MODBUS+ or MODBUS serial line sub-network. In that case, the “Unit Identifier” carries the MODBUS slave address of the remote device:

If the MODBUS server is connected to a MODBUS+ or MODBUS Serial Line sub-network and addressed through a bridge or a gateway, the MODBUS Unit identifier is necessary to identify the slave device connected on the sub-network behind the bridge or the gateway. The destination IP address identifies the bridge itself and the bridge uses the MODBUS Unit identifier to forward the request to the right slave device.

The MODBUS slave device addresses on serial line are assigned from 1 to 247 (decimal). Address 0 is used as broadcast address.

On TCP/IP, the MODBUS server is addressed using its IP address; therefore, the MODBUS Unit Identifier is useless. The value 0xFF has to be used.

When addressing a MODBUS server connected directly to a TCP/IP network, it’s recommended not using a significant MODBUS slave address in the “Unit Identifier” field. In the event of a re-allocation of the IP addresses within an automated system and if a IP address previously assigned to a MODBUS server is then assigned to a gateway, using a significant slave address may cause trouble because of a bad routing by the gateway. Using a non-significant slave address, the gateway will simply discard the MODBUS PDU with no trouble. 0xFF is recommended for the “Unit Identifier" as non-significant value.

Remark : The value 0 is also accepted to communicate directly to a MODBUS/TCP device.

 

Have any of you gentle folks looked into this? Any possible solutions? Could this be a bug in the Real-Time module?

 

The workaround I am using right now is pretty straightforward - assign unique slave addresses to each of the slaves. However, this is not a long term fix and may create issues years on when I am no longer associated with this product.

0 Kudos
Message 1 of 21
(7,769 Views)

It sounds like you're trying to create just one Modbus master in LabVIEW RT and have it talk to a number of different slaves. The way Modbus support is configured in LabVIEW requires you to create a unique Modbus master for each slave that you want to talk to. The address on both the master and the slave in a given master-slave pair should match to enable communication between that pair.

 

So, in summary, for each sbRIO that you want to talk to you'll need a unique address and a unique Modbus master created within LabVIEW with a matching address. It's not a bug; in LabVIEW, each Modbus I/O server can only talk to one slave device.

 

Regards,

Ryan K.
Product Manager, ATCA and BEEcube
National Instruments
0 Kudos
Message 2 of 21
(7,739 Views)

Thank you for your input. However, my problem is not with a master-slave pair within LabVIEW. I have two sbRIO machines, each acting as a slave. There is a third party controller that is to talk to these sbRIO's as a Modbus master.

 

Both of these slaves have a slave address of 1 which should not matter since this is a Modbus TCP implementation. The slaves should just respond with whatever slave address they are sent request at since the actual addressing is handled by the IP address. The more I think about it, the more I am convinced that the RT module's Modbus TCP implementation is broken.

 

 

0 Kudos
Message 3 of 21
(7,731 Views)

I'm sorry that I originally misunderstood the setup you were working with.

 

You're right that in LabVIEW RT, setting up a Modbus salve requires an address to be preconfigured, and that in order for a slave to process the message from the server, the server must send the message with an address that matches the slave's address (i.e. if the slave is configured with an address of 255, the server must send a message specifying an address of 255 for the slave to process the message). If a slave receives a message with a slave address that does not match its own, it will not process the message; this should be consistent with the Modbus protocol.

 

However, you should be able to configure slaves on two different devices with two different IP address to have the same slave address, and your system should still function properly. I just worked up a test where I set up two different RIO devices as slaves (different IP addresses obviously) and set the address field on both to 255, and I was able to communicate with both devices. Are you seeing different behavior with your system?

 

Regards,

Ryan K.
Product Manager, ATCA and BEEcube
National Instruments
0 Kudos
Message 4 of 21
(7,716 Views)

Ryan,

 

Thank you for the effort you have put into this.

 

Two things:

 

  1. You said: "If a slave receives a message with a slave address that does not match its own, it will not process the message; this should be consistent with the Modbus protocol." This may actually be incorrect. From my original post and the Modbus TCP spec: "On TCP/IP, the MODBUS server is addressed using its IP address; therefore, the MODBUS Unit Identifier is useless. The value 0xFF has to be used. When addressing a MODBUS server connected directly to a TCP/IP network, it’s recommended not using a significant MODBUS slave address in the “Unit Identifier” field. In the event of a re-allocation of the IP addresses within an automated system and if a IP address previously assigned to a MODBUS server is then assigned to a gateway, using a significant slave address may cause trouble because of a bad routing by the gateway." This means that the slave address in a Modbus TCP implementation should not be significant. My interpretation of this is that the slave should not be concerned with the slave address as long as its IP address is being addressed.
  2. I agree - setting up two slaves on a network with the same slave address and different IP addresses works fine on a purely ethernet based solution. In our case, however, we are using a serial gateway to talk to the sbRIO's due to a limitation of the third party controller. The third party controller does not have an ethernet port and so we are using the serial RS-232 port along with a serial to ethernet converter to talk to the two sbRIO slaves. This is breaking the Modbus implementation if both slaves have the same address.

 

Thank you again and I would appreciate any other pointers you may have on how to fix this. Our end customer is a bit unhappy with this and they would like a proper solution instead of the workaround I described earlier.

 

 

0 Kudos
Message 5 of 21
(7,695 Views)

Looking at the Modbus TCP spec again, it does look like I was misinterpreting it - sorry for that. You are correct: with Modbus TCP, the slave address should not be significant. I was also able to do some additional testing with some RIO hardware and I was able to verify (for a purely ethernet solution), the Modbus slave implementation in LabVIEW RT works properly: regardless of whether the addresses match or not, the slave should process to messages sent to its IP address.

 

At this point, it seems that the issue lies either with the 3rd party controller or serial/ethernet gateway that you're using. In this case, from LabVIEW RT's perspective, the sbRIO is just a part of an Modbus ethernet network; it will handle the ethernet packages the same regardless of whether the packages are coming directly from a controller over ethernet, or if they're coming through a serial/ethernet gateway first. All the sbRIO sees is a Modbus ethernet packet, so if the slave is able to handle the packet properly from an all ethernet solution (in other words, the LabVIEW RT implementation of Modbus is correct for an all ethernet solution) it should be able to handle any ethernet packet, assuming the packet itself is consistent with the Modbus TCP spec.

 

As such, I don't have much to offer in terms of additional steps/solutions. You could consider switching to an entirely serial implementation, but it sounds like that might not be an option in your case. Other than that, you may have to stick with the workaround that you're currently employing.

 

Regards,

Ryan K.
Product Manager, ATCA and BEEcube
National Instruments
0 Kudos
Message 6 of 21
(7,675 Views)

Ryan,

 

So to confirm... you were able to set a slave to say address 2 and send it Modbus TCP commands from a master that had the slave address configured to say 1 and able to receive a response assuming you were addressing the slave's IP address. I have not had success with this here. I will try it again. If you can confirm your test findings, it would be great.

 

Thanks

0 Kudos
Message 7 of 21
(7,669 Views)

Yes, that's correct. I was able to set up a system where the master and slave had different slave addresses and the two still communicated with each other.

Ryan K.
Product Manager, ATCA and BEEcube
National Instruments
0 Kudos
Message 8 of 21
(7,650 Views)

Ryan,

 

I was not able to reproduce this. I configured the slave to address 2. Then I used a couple of Modbus utilities to poll the slave at addresses 1 and 2. It would only respond to when addressed using address 2. Can you confirm that you are setting up the slave as described here: http://www.ni.com/white-paper/13911/en/

 

 

0 Kudos
Message 9 of 21
(7,643 Views)

It looks like that document details the process for creating a Modbus Master, not a slave. I am following a similar process to create the slave - I'm just selecting "Modbus Slave" instead of "Modbus" from the I/O server options. Other than that, everything else is the same. I'm setting the slave's address to 2, and the master's address to 1 and I'm able to establish communication.

 

Regards,

Ryan K.
Product Manager, ATCA and BEEcube
National Instruments
0 Kudos
Message 10 of 21
(7,626 Views)