Any Modbus gurus here? Addressing question... - Page 1
Forum section: electronics / projects

author: mc
author_rank: Regular Contributor
timestamp: November 15, 2013, 12:01:53 am
content: I'm hoping somebody here can help me out as I'm close to having no hair left!I'm trying to programme a motion controller (a Dynomotion KFlop+Kanalog to be precise) to talk to a Click PLC over Modbus.I have the sample script working, which reads the inputs and copies thier status to virtual bits and sets the outputs depending on other virtual bits (virtual bits are essentially an easily accesible globally readable/writeable storage bit within the KFlop).What I need to do is read two internal holding registers (DS registers in Click speak), however I'm struggling to identify the correct modbus address. Part of this is I don't quite understand how the sample script modbus request is actually working.For the read register example, the following modbus request is sent-Code:Tx:01;04;e0;00;00;01;06;0a;01 is the device ID, 04 is the function code, e000 is the register address, 0001 is the number of registers to read, and the 060a is the CRC.Now, according to the manual, the hex address of the X (input) register, is 0000, so how does that translate to e000 in the above request?Also, according to the Click manual, 04 is not a valid function code for the X register, only 02 is valid.Officially 04 is a Read Input Register request, whereas 02 is Read Input Status.Anyway, the main issue is how do I access the DS/holding register.The hex address for the first holding register (DS1 - simply stores a value between 1 and 6) I need to read is also 0000, but with a function code of 3 (Read Holding Registers), 6 (Preset Single Register) or 16 (Preset Multiple Registers). Going by my understanding of the manual, the switch between the X and DS registers is made depending on the function code so the following request should work, so swapping the 04 for 03 in the above example should work, however it doesn't and I get the X register value returned.I've tried swapping the e for a 0 but then things fail.Can somebody help me out, and explain what I'm doing wrong?I've attached the extract from the Click help regarding the addressing, and it's probably worth noting that the CRC code is automatically handled by the KFlop script, so that isn't the problem.

author: mc
author_rank: Regular Contributor
timestamp: November 15, 2013, 12:40:56 am
content: And I think the penny just dropped!I just searched through the Click software address picker, and E000 is a valid address for the XD aka input registers, which explains the mystery E.I'm now questioning if I actually tried swapping the E for a 0....

author: orion242
author_rank: Unknown
timestamp: November 15, 2013, 12:48:56 am
content: Tx:01;04;e0;00;00;01;06;0a;Dev adr 1, read input register 57,344.Do you get the expected value in the response to this request? Do you have the register list for the slave device?Register addressing is never documented the same between slaves. Some start at 1, some at 0, some start input registers at 30,000 and go up from there.

author: mc
author_rank: Regular Contributor
timestamp: November 15, 2013, 01:00:48 am
content: That request gets a valid response, and works exactly how it should in the sample script.The issue is that the manual and help only briefly mention where groups of register addresses start/finish. I only found out about the XD register by manually going through each register in the address picker within the Click programming software checking to see if E000 was a valid address. And it is, with a valid function code of 04, which answers my other question.The ascii code is listed as 357345, which sounds right given that it needs offset by 1.This is my first attempt at using PLCs and Modbus properly, and also the first machine I've used a KFlop on which itself needs a fair bit of C programming, so although each part isn't too hard to learn and handle, everything at once is proving to be a bit challenging.

author: orion242
author_rank: Unknown
timestamp: November 15, 2013, 01:06:48 am
content: You might want to google Modscan or Modbus poll. These can quickly scan registers and help with troubleshooting.

author: VintageTekFan
author_rank: Regular Contributor
timestamp: November 15, 2013, 02:46:49 am
content: The big thing to remember with Modbus messaging is that the 'address' field isn't and address, it's an offset.So, if you are using Function Code 03, and have an offset of, say, 5, then the address read in the remote system will be 400006. This assumes a Modicon style addressing scheme in the Modbus server - IE, numbering begins at register 400001.There are 4 types of memory (first address):Coils (000001)Inputs (100001)Input Reg (300001)Holding Reg (400001)Which memory range gets accessed depends upon the Function Code used.A good reference I use is located:http://modbus.org/docs/PI_MBUS_300.pdf

author: mc
author_rank: Regular Contributor
timestamp: November 15, 2013, 12:38:42 pm
content: Thanks for that link VTF, I've saved a copy of that for future reference. I've got another machine to retrofit, which is going to involve alot more complex systems, so will likely rely even more on modbus.I've been out this morning, and triedCode:Tx:01;03;00;00;00;01;xx;xx;and it worked!I've also managed to add code to write a new value to the DS2 register, so I now have the basics working.I was getting a bit frustrated yesterday, as I didn't fully understand how the example was working, so in my best guesses I must of skipped changing the obvious digit.Thanks!