News:

Calling all communications systems experts - please share your knowledge here!

Main Menu

Modbus Protocol

Started by Dave Loucks, October 27, 2014, 11:03:46 AM

Previous topic - Next topic

Dave Loucks

I wouldn't think I would need to post a link describing the Modbus protocol here, but as I've searched the web looking for complete information, I reviewed many "page 1" hits from all manner of sites that never measured up.

So in the interest of providing readers of this site with what I consider the most complete Modbus RTU information,   I am posting the link to the Modbus RTU protocol standard from Modbus.org:
For a quick reference if you are writing device drivers:

Modbus Function Code 03 (Read Registers)
Note: The first byte of any Modbus request or response is always the Modbus address of the device.  Likewise, the last two bytes of any Modbus request or response is always the CRC (low byte first, then high byte).  That means when looking at these tables, mentally always add one extra byte to the beginning (address) and two at the end (CRC).

All Modbus read register (03) messages are 8 bytes long (5 shown above + 1 byte for Modbus network address + 2 CRC bytes).  The acknowledgement reply response to a Modbus function code 03 message contains either 5 + (2*N) bytes for valid response or 5 bytes for exception (error) response.

mMINT Modbus Exception Codes Returned:

  • 1 - Illegal Function
    You used a Modbus function code that was not supported by the mMINT.
  • 2 - Illegal Address
    You attempted to read or write a address in the mMINT register map that does not exist (or is otherwise protected) in the device.
  • 3 - Illegal Data Value
    You created a message that had an invalid value in the message (such as invalid message length).  Note that Modbus doesn't care what is in the data payload.  This exception response is saying the construction of your messages is faulty.
  • 4 - Failure in Associated Device
    Message received by mMINT and validated, but no response heard from the connected device on the INCOM network.
  • 5 - ACK Code
    Undefined error.  Solution: Repeat request.  If issue remains, contact Eaton.
  • 7 - mMINT Unable to Process Request
    Undefined error.  Solution: Repeat request.  If issue remains, contact Eaton.
  • 84 - Partial Table Request Error
    The register address requested is valid, but you didn't request the entire 32 or 64 bit register(s).  You either didn't request enough 16-bit Modbus registers, or you requested enough registers, but didn't request starting at the right register boundary.

    Example: Read Ia, Ib and Ic
    Ia is contained in registers 404611 and 404612, Ib is 404613/404614, Ic is 404615/404616.  Assume that the programmer forgot that these are Modbus registers, not memory addresses in the Modbus message and requested address 4611 - 4616.  These are valid registers, but they don't begin on the boundary of a register.  You would receive an 84 exception.  The correct addresses would be 4610 - 4615.

There are other exception codes, but these are the most common.  For an example of an exception code, refer to the following exception response.

Example Exception Response (Read request of invalid block of registers)














ByteValueDescription
1247Modbus Device Address
2131Opcode (03) with 8th bit set i.e. 128+3=131
32Modbus Exception Code 02 (invalid address)
432CRC - low byte
5195CRC - high byte

Modbus Function Code 16 decimal (10 hex) (Write Registers)

All Modbus write register (16) messages are 9 + 2*(# registers) long.  The acknowledgement reply response to a Modbus function code 16 message contains either 8 bytes for valid response or 5 bytes for exception (error) response.

Another interesting note: Modbus register addressing and table lengths both are 16-bit values, therefore these 16-bit values must be divided into two bytes to transmit as a Modbus message (typical serial port settings are 8 data bits per character).  The Modbus standard choses to send the high order byte first for these register addresses and table lengths

HOWEVER, the Modbus standard states that the 16-bit CRC must be sent with the lower 8-bit byte sent first.

Example - Read two Modbus registers starting at register 46235 from Modbus address 001

Recall that Modbus registers begin with 40001 (there is no such thing as register 40000), which means if the first value has 0 offset, then the 6235th value has an offset of 6234 (one less). 













Modbus
Register
Remove
Prefix
Offset
Decimal
Offset
Hex
40001000110000
40002000220001
  :   :  :   :  :   :  :   :
4623562356234185A
  :   :  :   :

Therefore, to calculate the actual address of 46235:

  • Remove starting 4 --> leaving 6235
  • Subtract 1 --> 6234
  • Convert to hexadecimal --> 185A

Sent:

       
  • Modbus node address = 1
  • Modbus function code = 3
  • Modbus starting register address = 46235 (dec)  (memory offset: 185A hex)
  • Number of registers to read = 2



Node Func Add Hi Add Lo # Hi # Lo CRC Lo CRC Hi
01 03 18 5A 00 02 E2 B8

Reply:




Node

Func

Bytes
Data 1
Hi byte
Data 1
Lo byte
Data 2
Hi byte
Data 2
Lo byte

CRC Lo

CRC Hi
01 03 04 04 8800 00 7B 29

The data returned was:

  • 46235 = 0488 hex
  • 46236 = 0000

Another example:

Read two registers starting with 42001:

  • Remove starting 4 --> leaving 2001
  • Subtract 1 --> 2000
  • Convert to hexadecimal --> 07D0

Sent:

       
  • Modbus node address = 247
  • Modbus function code = 3
  • Modbus starting register address = 42001(dec)  (memory offset: 07D0 hex)
  • Number of registers to read = 2



Node Func Add Hi Add Lo # Hi # Lo CRC Lo CRC Hi
F7 03 07 D0 00 02 93 33

Reply:




Node

Func

Bytes
Data 1
Hi byte
Data 1
Lo byte
Data 2
Hi byte
Data 2
Lo byte

CRC Lo

CRC Hi
F7 03 04 FF FFFF FF 6D A8

The data returned was:

  • 42001 = FFFF hex
  • 42002 = FFFF hex



Writing a block of registers to a Modbus device uses Modbus function code 16 (10 hex).  Modbus also supports a single register write command (06 - Preset Single Register), but the Eaton mMINT and MPONI do not support this function code.

Modbus Function Code 16 / 10 hex (Write Registers)

Sent:

       
  • Modbus node address = 247
  • Modbus function code = 16 decimal
  • Modbus starting register address = 42001(dec)  (memory offset: 07D0 hex)
  • Number of registers to write = 1
  • Value to write = 0

As shown the Modbus read example above, the register numbers must be converted to the register addresses.

Convert 42001:

  • Remove starting 4 --> leaving 2001
  • Subtract 1 --> 2000
  • Convert to hexadecimal --> 07D0





Node Func Add Hi Add Lo # Hi # Lo # Bytes Data Hi Data Lo CRC Lo CRC Hi
F7 10 07 D0 00 01 02 00 00 EC A4

Reply:




Node

Func
Addr
Hi byte
Addr
Lo byte
# Regs
Hi byte
# Regs
Lo byte

CRC Lo

CRC Hi
F7 10 07 D0 00 01 15 D2

Dave Loucks

#1
As many know, and EIA-485 network can support 32 devices (31 slave devices + 1 master) over 4000 feet (1219 m) as long as you set the bit rate to no more than 100 kbps (higher bit rates limit distances allowed).  Also, in the original Modbus specification the highest usable Modbus address is 246 (0 and 247-255 have special purposes).  The mMINT adheres to this standard.

Now for the mMINT, an additional consideration might be the INCOM network limits, but since INCOM supports up to 4095 unique addresses and up to 10000 feet (3048 m) of twisted pair, the real limitation is the 246 uniquely addressable stations on the Modbus network.

Therefore for mMINT systems you can only have 246 unique devices on the INCOM network since you need one Modbus address for each INCOM device connected downstream of a mMINT.  So while you can have 4095 unique INCOM address 001-FFF on the INCOM side, that isn't any use since you can't have more than 246 unique Modbus addresses.

Here's a diagram:


This 246 per leg and 246 total might be confusing, but it just is to say you cannot have more than 246 devices on any single mMINT, but you can also not have more than 246 total Modbus devices on all mMINTs that might be connected to a single Modbus network.

To show how these limits work, here's an example of where you can load up a single mMINT, but could also put several more devices on two other mMINTs where all three mMINTs are  on the same Modbus network to bring the total up to 246 devices.


If this isn't enough devices, you get another 246 on a second port on the same Modbus master:


Using this technique you can build arbitrarily large systems -- recognizing that for practical systems, the desired throughput/update time will limit the number of devices

Depending on how much data you want to collect and how fast you want to collect it will establish a practical upper limit on the number of devices per COM port.