Modbus Decode

Well, Ok, That's pretty straightforward. You had me going with the 16384 when the register was 1684. But I realize now you were just testing me.

Extra credit exercise:
Assuming for a minute that address 0010 and/or 0013 would change the number of decimal places occasionally ... How would one code that as a multiplier without a "lookup table" arrangement?

I don't believe that will happen here, but I am curious how that could be done.

Summat like this might work:

MUL .Data300008 65536.0 LREAL0809 XIC .Data300008.15 ADD LREAL0809 4294967296.0 LREAL0809

ADD .Data300009 LREAL0809 LREAL0809
XIC .Data300009.15 ADD LREAL0809 65536.0 LREAL0809

AND .Data300010 00ffh INTdecimalplaces

LBL loop GRT INTdecimalplaces 0 DIV LREAL0809 10.0 LREAL0809 SUB INTdecimalplaces 1 INTdecimalplaces JMP loop

 
Last edited:
Check me. I can't use the math you provided as I don't get the same answer you did, but using a UINT instead of (65536-Reg300012) I do.
First 3 instructions come up with the correct answer
Branched CPT's on the right do not.
What does conversion to UINT do differently than (65536-Reg300012)

MathIsHard.jpg
 
I should have thought of these first:

CPS .Data300011 UDINTbuff 1 BTD UDINTbuff 0 UDINTtarget 16 16 BTD UDINTbuff 16 UDINTtarget 0 16


N.B. That assumes COP/CPS will the .Data3xxxxx items are essentially an array, and will get .Data300011 and .Date300012.

MOV .Data300011 INTbuff[1] MOV .Data300012 INTbuff[0] CPS INTbuff[0] UDINTtarget 1



? All assume Local PLC is LSB-first.

There are probably lots of ways to skin this cat.
 
Gotcha. Ken mentioned that at the beginning, I think using the unsigned registers I have available on this proc will work just fine here.

Thanks for the help on this. I see light now.
 
Just got a little wierder

Edit: I got this working before I left yesterday and I'm off today but this is bugging me.

After getting these to read properly (thank you all again) I moved on to the reset process which seemed like a no brainer. Simply write FF00 to register 0.
But alas . . .

reset.jpg

In the 5069-SERIAL I can do the following
"write single register" (Command 06) which uses an INT as its source register
"write single coil" (Command 05) which uses a BOOL as its source register **

While the instructions clearly require that FF00 be written, I can't do that with Command 05 in the 5069-SERIAL. To write using Command 05, I can only store the value to be written into a BOOL register.

** It just occurred to me that perhaps the Command 05 register is an INT and I just can't write FF00 into it because that got interpreted as a string. But perhaps I could write 255 into it.
(Having said that if the MSB is FF and the LSB is 00 that equals 65280... they must swap somewhere... ) In either case I didn't try that but will next week.

I got it working by moving 1 into the register and that worked every time time.

But I am curious about this and if its unique to the 5069-SERIAL or if I mangled the attempt somehow.
 
For all Modubus Client requests, the data always and only ever comprise one or more 16-bit words. A 16-bit word value of 0xFF00 translates to a single-bit value of 1 in the discrete output coil when using Modbus Protocol Function code [05 (0x05) Write Single Coil].

TL;DR

Yes, a Modbus Client request using Modbus Function code [05 (0x05) Write Single Coil], is writing a single bit (coil) value on the Modbus Server device, but to write the coil via the Modbus protocol, it will

  • EITHER send the 16-bit word value x0000 to assign a single-bit value of 0 to the coil (device discrete output i.e. BOOL),
  • OR send the 16-bit word value 0xFF00 to assign a single-bit value of 1 to the coil.
So in the image supplied by @TheWaterboy in Post #23, that single 0xFF00* is a 16-bit word that is meant to be interpreted in toto by the Modbus Server for one coil (BOOL; bit) only.

* = 0xFF00 = FF00h A-B hex = -256 decimal, as noted by @AustralIan)

N.B. this only applies to protocol requests using Function code [05 (0x05) Write Single Coil]; for Function code [15 (0x0F) Write Multiple Coils] the protocol still uses a 16-bit word (or multiple 16-bit words, for more than 16 coils), but the mapping is one coil per bit in the word(s).

Cf. image below from pp. 17,18 of [April 26, 2012 http://www.modbus.org MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b3] at this link (scroll to bottom of that page).
Sidebar: I have a Micro820 Modbus TCP Client (MSG_MODBUS2 instruction) writing a single coil to an S7-1214C Modbus TCP server (MB_SERVER instruction, attached to a 120V relay and a lamp @OldChemEng's TV room), and writing 0xFF00 in the protocol does not flip the S7-1214C coil: it needs to be 0xFFFF (I forget if 0x0001 also works). I have to do some more testing to make sure I understand exactly what is going on, but this seems to imply that the Siemens MB_SERVER instruciton does not implement Modbus TCP protocol correctly, which seems odd to me, so maybe I am misinterpreting my setup. I would appreciate if anyone else could run the same test.

xxx.png
 
I understand that Cmd 05 and FF00 is the correct way, but I couldn't get the PLC to accept that value as valid using Cmd 05, it only accepted the value of 1. The only way it accepted FF00 was using Cmd 06 and the device wont accept that for obvious reasons.
Yet for some reason my value of "1" worked ... but shouldn't as it's an illegal value.

I'll poke at this more next week.
 
I understand that Cmd 05 and FF00 is the correct way, but I couldn't get the PLC to accept that value as valid using Cmd 05, it only accepted the value of 1. The only way it accepted FF00 was using Cmd 06 and the device wont accept that for obvious reasons.
Yet for some reason my value of "1" worked ... but shouldn't as it's an illegal value.

I'll poke at this more next week.




Yah, I am seeing the same symptom: Modbus TCP server does not assign 1 to single coil in respoonse to 0xFF00 in Function code 5 request as it should, but it will do it for 0x0001. In the end I used Function code [15 (0x0F) Write multiple coils] with a coil count of 1 and wrote the low bit of the 16-bit word.
 
This is from Rockwell staff:

You just need to specify a Boolean value to indicate whether you want to turn the coil on (1) or off (0). The 5069-SERIAL module will send a 0xff00 if you specified on or 0x0000 if you specified off.
 

Similar Topics

Where am I going wrong here? I'm trying to turn a modbus register into the expected value of around 375 as displayed on the instrument. According...
Replies
21
Views
5,710
I want to communicate my Q series PLC with Factory IO using GX works 2 software, I want to use modbus as server and the ips are as follows plc...
Replies
0
Views
1
Hi folks, I have a Controllogix in communication with a zigbee coordinator using Logix AIO for modbus tcp. This zigbee coordinator have 3 slaves...
Replies
2
Views
100
Hi, I'm setting up a modbus master on an S7-300. It seems to work in OB1 but not when I use it in OB35. Does anyone have any ideas why? Could...
Replies
10
Views
111
Hi Everyone, i was hoping for a little help with this module. i have data that needs to be read from a different plc through the Modbus plus...
Replies
11
Views
265
Back
Top Bottom