Issue
Getting modbus devices to communicate to Continuum may require some trial and error.
Product Line
Andover Continuum
Environment
- Continuum
- Modbus RTU, ModbusRTU
- Windows XP
- Windows Vista
- Windows 7
- Windows Server 2003
- Windows Server 2008
Cause
Manufacturers of modbus devices may have an offset for their register values and addressing these values requires trial an error.
Resolution
This article was created as a starting point. There are a lot of tools and methods to get values from modbus devices communicating. This resolution discusses some important concepts as well methods for trying to bring values in.
- The Modbus RTU protocol is a Master/Slave style of protocol. The Andover Controls CX will be the master on the Modbus RTU network. There can be only one (1) master at a time on the Network.
- The Slave number is always set in the third party device. This could be either a hardware setting such as dip switches or a software setting. Modbus-IDA (also known as Modbus.org) has set the limit that the slave address can be between 1 and 247. Address 0 is allocated as a broadcast message. The Andover Controls x-driver can support addresses in the range of 0-255.
- The third party manufacturer should be able to tell you what the expected function codes are for the points that you are interested in. Modbus.org has defined the function codes in a very loose manner and leaves it up to individual interpretation. Andover controls supports the following standard function codes: 1-8 15,16. Since when you request information from a Modbus RTU device you receive the exact value that is in the register Andover Controls has provided some special function codes that will help to convert some of the common engineering values into usable values. The listing in the x-driver documentation shows the special function code, what is expected from the third party and the equivalent function code that is truly sent to the device. For instance if a point is a Intel float and resides in the 40,000 range then function code 245 would be used in the Andover Controls x-driver. This will still send out a function code 3 in the Modbus message but the x-driver will take the value sent in from the third party device and convert it into a usable float.
- Most confusion occurs when talking about the data registers, (also known as addresses or channels). Modbus.org has the following statements about the addresses in the protocol document.
All data addresses in Modbus messages are referenced to zero. The first occurrence of a data item is addressed as item number zero. For example: The coil known as ‘coil 1’ in a programmable controller is addressed as coil 0000 in the data address field of a Modbus message. Coil 127 decimal is addressed as coil 007E hex (126 decimal). Holding register 40001 is addressed as register 0000 in the data address field of the message. The function code field already specifies a ‘holding register’ operation. Therefore the ‘4XXXX’ reference is implicit. Holding register 40108 is addressed as register 006B hex (107 decimal). Register number also known as address.
When setting the start channel number parameter on the x-driver tab the x-driver is expecting the exact decimal address that you are looking to obtain. For instance: if a device shows a listing for the first point to occur at 40,001 then the start channel number is typically 0. This can be confusing since some manufacturers have decided to have 40,001 as being 1 and not zero while others manufacturer have decided that 40,001 is 0. There are two ways of determining how the manufacturer has started the numbering system for the device if it is not documented:- Method 1 is a trial and error method. Where you set the value to minus 1 of the register address, the actual register address and plus 1 of the register address and see which one you a response from.
- Method 2 uses a third party software to poll all the points to see what addresses are populated. There are many shareware Modbus RTU software packages on the Web. One such program is called ModScan32 by Win-Tech. www.win-tech.com
- Number of channels. The least amount of channels that will be requested is 1 so number of channels should always be 1 or greater. If the data is stored in multiple channels then you will need to set the number of channels equal to the number of registers. If you are not using a special function code you will need to set up a separate numeric with a manual log with the number of entries equal to the number of channels. When you poll for the value of the channels the data will then be stored in the manual log of this second numeric. The first element of the log will be the first channel that is requested. For instance if a value is stored in registers 40,000 through 40,003 then the start channel number will be set to 0 and the number of channels would be 4. Another numeric with a manual log of 4 would be created and linked in the x-driver numeric by placing the name of the new numeric in the annex point parameter. Once the x-driver point is polled the returning information will be stored in the annex point. The manual log of the annex point will contain the data for the 40,000 register in location 1. The data for each subsequent register location will be in the next manual log location. I.E. annexpoint[4] will contain the data for register 40,003
- The Modbus RTU x-driver is a poll on demand x-driver. What this means to the user is that either a Plain English (PE) program, graphic or editing the x-driver numeric will cause a poll to occur. It is best to mirror the x-driver point and use PE to poll the x-driver points. A simple program would loop through and perform a simple line of mirroredpoint = x-driverpoint. This will avoid multiple polls to the same point tying up more CX resources then necessary. Then you can use the mirrored point in programs and graphics.
- If you try to get values from a slave device that is offline (not responding) the x-driver will poll each point three times before it moves on to the next point. This will cause the CX scan time to rise to seconds instead of tenths of a second. It is helpful to have a single x-driver point in the third party slave device that will return a known value, (Product ID or serial number for example). This can be used to avoid running the scan time of the CX up if the slave device can not communicate. Inside of the polling program try to poll for the value of this point. If the value does not come back then skip the polling for the rest of the points for this slave device. This point can also be used as an alarm for the offline device as well.
For example:
1: If ProductID1 = 15 then Mirroredpoint1 = x-driverpoint1 Goto 2 else Goto 2 endif 2: If ProductID2 = 15 then Mirroredpoint2 = x-driverpoint2 Goto 1 else Goto 1 endif
- Some data may come back as a value when you need only a bit of information. In this case you will need to use the Bitand operator in PE to extract the exact bit that you are looking for. As seen below the PE code will take an alarm point from a Liebert AC unit and break out the individual bits of information.
AC9_Alarm1 = x_ac9alarm1 'setting the mirrored point AC9_CommFail = AC9_Alarm1 bitand 1 'extracting bit 1 AC9_LocalOff = AC9_Alarm1 bitand 2 'extracting bit 2 AC9_RemoteOff = AC9_Alarm1 bitand 4 'extracting bit 3 AC9_HiHeadPrs1 = AC9_Alarm1 bitand 8 'extracting bit 4 AC9_HiHeadPrs2 = AC9_Alarm1 bitand 16 'extracting bit 5 AC9_LossAirFlow = AC9_Alarm1 bitand 32 'extracting bit 6 AC9_StbyGlycolOn = AC9_Alarm1 bitand 64 'extracting bit 7 AC9_LiquidDet = AC9_Alarm1 bitand 128 'extracting bit 8 AC9_ChangeFltr = AC9_Alarm1 bitand 256 'extracting bit 9 AC9_HighTemp = AC9_Alarm1 bitand 512 'extracting bit 10 AC9_LowTemp = AC9_Alarm1 bitand 1024 'extracting bit 11