News:

  • May 05, 2026, 06:04:26 AM

Login with username, password and session length

Author Topic: Modbus/TCP address offset  (Read 16618 times)

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Modbus/TCP address offset
« on: May 27, 2013, 05:39:17 PM »
I'm working up my first "real" DM project, and am starting with getting the Modbus checked out because I need to work on the HMI first.

First, let me give you guys HUGE kudos for the work you've done on this PLC!   :D

I've been playing around with one for a while now, but exploring and digging in to work on a project are two different things, and when you're doing a real project where you have to make X amount of progress in Y time, you can really sense the quality of the work that you guys have done.

The immediate reason for my post is that I'm getting responses offset by one register from what I was expecting.

My HMI is configured to request 9 registers starting with No. 1.   The actual poll is:

Tx (14:19:38.011): \x00\x00\x00\x00\x00\x06\x00\x03\x00\x01\x00\x09

which as I parse it is exactly as it should be.  But the response seems to be returning 9 values starting with MHR2 (as id'd by the value in the registers).  Here is the actual response:

Rx (14:19:38.014): \x00\x00\x00\x00\x00\x15\x00\x03\x12\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0A

Are you offsetting the requested register by 1?  That wouldn't be unheard of for Modbus, if so.
« Last Edit: May 27, 2013, 05:41:09 PM by Controls Guy »
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6154
  • Yes Pinky, Do-more will control the world!
Re: Modbus/TCP address offset
« Reply #1 on: May 27, 2013, 06:57:38 PM »
Memory addresses are 1-based and the protocol is 0-based, as is true in Modicon controllers, and as far as I am aware, as is generally true in most Modbus implementations. I realize right away that to suggest a single "Modbus standard" exists is pretty naive, but we tried to stay pretty close where we could.

And thanks for the kind words. Pat yourself on the back as well; you certainly had considerable input!
« Last Edit: May 27, 2013, 10:54:59 PM by BobO »
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Modbus/TCP address offset
« Reply #2 on: May 27, 2013, 07:27:47 PM »
And thanks for the kind words. Pat yourself on the back as well; you certainly had considerable input!

Thanks!   ;D

Quote
Memory addresses are 1-based

Can you expand on that a little?  I thought the first valid address for any type of memory was 0 (X, Y, C, V, MHR, etc.).  Data view lets me display MHR0 for instance.

Plus, there was no offset in DL Classic, just the Dec <-> Oct conversion.  V2000 was address 1024.  

Oh, and responding in 3ms?  Nice!!
« Last Edit: May 27, 2013, 07:33:23 PM by Controls Guy »
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3806
    • Host Engineering
Re: Modbus/TCP address offset
« Reply #3 on: May 27, 2013, 07:43:30 PM »
Most PLC people do not need to know the bits on the wire.  For example, what is the Do-more address at the protocol level for T19.Acc?  Unless you are implementing the protocol, you just program your HMI for T19.Acc - you don't even look at what's on the wire.

Modbus is the same.  You want to read Modbus Holding Register 40001.  Nowhere will you see the value 40001 in the bytes at the protocol level (not should you care, as a user).  It is actually sent as a Function Code "Read Holding Register", which eliminates the "4" part of the address.  You are left with the offset, which is the first offset, which is 1.  Modicon registers/coils/etc. start at 1, at the user level.  HOWEVER, at the protocol level (which users don't need to know), Modicon offsets start at 0, hence, you subtract 1 from the "Application Layer" address (i.e. 1), and at the packet leve, it ends up being 0.

That is the "official, specified" way of doing it.  There are many vendors (I don't want to name any) who don't do it based off the spec.  They push the low level offset up to the user level, and their addresses start at 0 (not 1).  Imagine specifying T19.Acc as 0x1234 (or whatever it is).  You'd be pulling your hair out.

There are even some Modbus devices out there that use the FULL 40001 address as the "offset".  Yes, they literally implemented their first Holding Register at protocol offset 40001 (possibly 40000 ;D).  So, technically, their application layer holding register address is 440001, where the first 4 is the type, and the 40001 is the offset.  Doh!

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Modbus/TCP address offset
« Reply #4 on: May 27, 2013, 07:55:36 PM »
Ah, OK, so what BobO was talking about was that Modicon memory is 1-based, so a DM will return the value in MHR765 in response to the same query that would get register 40765 from a Modicon controller, so the DM <-> Modicon mapping is 1:1 without the 1-offset.  Got it!

So what the heck am I supposed to use MHR0 for?  Extra memory, like we used to have to use unused X's and Y's back in the bad old days?   ;D
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3806
    • Host Engineering
Re: Modbus/TCP address offset
« Reply #5 on: May 27, 2013, 08:09:57 PM »
So what the heck am I supposed to use MHR0 for?  Extra memory, like we used to have to use unused X's and Y's back in the bad old days?   ;D
GREAT question.  We initially eliminated the 0 ID Modbus elements (since you can't read protocol offset -1), but then we realized that, say for BIT memory, if you needed to access the first BYTE as a CAST in MC (Do-more's Modbus Coil block), you cannot do MC1:UB (since this is not BYTE-aligned), you would need to do MC0:UB.  Technically, the first bit of that BYTE is not addressable via the protocol, but programmatically, you may want to move MC0:UB into Y48:UB.  Not sure about when you would actually need to use MHR0, but we allowed ID 0 programmatically for all 4 Modbus blocks: MC (Modbus Coils), MI (Modbus (discrete) Input), MIR (Modbus Input Register), and MHR (Modbus Holding Register).

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3607
  • Darth Ladder
Re: Modbus/TCP address offset
« Reply #6 on: May 27, 2013, 08:38:21 PM »
Makes perfect sense!  Thanks!
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6154
  • Yes Pinky, Do-more will control the world!
Re: Modbus/TCP address offset
« Reply #7 on: May 27, 2013, 11:07:16 PM »
Ah, OK, so what BobO was talking about was that Modicon memory is 1-based, so a DM will return the value in MHR765 in response to the same query that would get register 40765 from a Modicon controller, so the DM <-> Modicon mapping is 1:1 without the 1-offset.  Got it!

Yeah...too simple, no? We tend to ascribe to the apparently unusual view that our OS should eliminate complexity everywhere possible, and leave the flexibility where it can actually benefit the customer. An example of that thinking was the 1:1 Modbus mapping. I know, weird, right?
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO