Micro820 Modbus TCP

Sign In

Found this but I don’t think I’m using it right. I get error 6
See here:
Code:
COP status codes (Sts)
The following table describes the COP status codes.
COP Status code Status description
...
0x06 Source data size is too small for copy.

Is the Src input parameter to the COP instruction an array of at least 2 elements?
Is the Length input parameter to the COP instruction 1 for each REAL, and for each 2 Src Words, that will be COPied?

Take note of items (i) and (vii) below.
 
IMG_6070.jpeg

IMG_6073.jpeg
IMG_6074.jpeg
IMG_6075.jpeg
Getting closer!! Not sure why I can’t get precise values though. Just a little off. That might be over my head. Tried to scale but that didn’t work.
 
Short answer:
  • The Modbus slave's CPU architecture is LSByte-first (Least-Significant Byte-first)
  • The Micro820's CPU architecture is MSByte-first (Most-Signiricant Byte-first)
  • The SrcOffset should be 0, not 1
  • The PLC code needs to swap the 16-bit Words la[0] and la[1]
    • N.B. the bytes do not need to be swapped within the words
  • Welcome to the world of bookeeping the bits.
TL;DR

Here is what is happening:

Code:
0         1        2        3        4 Register offsets
|21.35.............|0.0..............|The 32-bit float values 21.35 and 0.0 at Modbus 16-bit register address pairs [0,1] and [2,3]
|57429....|16810...|0.......|0.......|The corresponding 16-bit register values are LSWord-first
|la[0]....|la[1]...|la[2]...|la[3]...|Those 16-bit registers are transferred to Micro820 array elements la[0..3]
|                                    |  - N.B. the BYTE-order within each two-byte word is corrected by the Modbus protocol
|ignored..|16810...|0.......|ignored.|The COP instruction, with SrcOffset 1 moves the bits from 16-bit la[1] and la[2] ...
|.........|21.25............|........|  ... to 32-bit REAL Analograw, which is MSWord-first

Here is what is happening using Python:

The device's 32-bit floats are packed as 16-bit register words LSWord-first (Least-Significant Word-first):
Code:
>>> struct.unpack('<HHHH',struct.pack('<ff',21.35,0.0))
(52429, 16810, 0, 0)
>>>
  • The .pack('<ff',21.35,0.0) packs the 32-bit REALs 21.35 and 0.0 into eight LSByte-first bytes
  • The .unpack('<HHHH') unpacks those eight bytes into four 16-bit unsigned words (52429, ...)
The Modbus protocol transfer fixes the byte-order within the words, but does not reverse the word (register) order:
Code:
>>> struct.unpack('>HHHH',struct.pack('>HHHH',*struct.unpack('<HHHH',struct.pack('<ff',21.35,0.0))))
(52429, 16810, 0, 0)
  • The .pack('>HHHH',...) packs those four LSByte-first words, (52429,...) into eight MSByte-first bytes (Most-Significant Byte-first)
  • the .unpack('>HHHH',...) unpacks those four MSByte-first words, the same as the Modbus transfer does into the Micro820 array (la)

The COP instruction does this:
Code:
>>> struct.unpack('>HfH',struct.pack('>HHHH',*struct.unpack('HHHH',struct.pack('ff',21.35,0.0))))
(52429, 21.25, 0)
  • The .unpack('>HfH',...)unpacks those four MSByte-first 16-bit words as
    • 'H': one 16-bit MSByte-first word (52429, the LSWord of original REAL 21.35)
    • 'f': one 32-bit MSByte-first REAL, using the 16-bit words 16810 (MSWord) and 0 (LSWord)*
    • 'H': one 16-bit MSByte-first word (0, the MSWord of original REAL 0.0)
 
Last edited:
And to further prove that this is what is happening, here is how 1351.0 became 1344.0:
Code:
>>> struct.unpack('>HfH',struct.pack('>HHHH',*struct.unpack('HHHH',struct.pack('ff',1351.0,0.0))))
(57344, 1344.0, 0)
 
From yesterday; see the highlighted notes in red:
[...]

That is Python using the struct module to combine 16-bit (Half-)words 0 and 16844. You can do the same thing: COPy the bits (not the values) of the 16-bit word pair (two contiguous elements of the array from the Modbus TCP transfer) into a REAL tag; you may need to reverse the word order before the COPy. You will not have to swap the byte order within the words.
 
If you want to see something funny, keep the existing code (no word swap; SrcOffset=1), and put 42.70 (or 10.675) as Float-1 on the Modbus slave, and then you will see 21.35 as Analograw. The code is still wrong, but if you grok why this gives the right answer, then this kind of thing will never "be over your head" again.

analysis_profitability_rentabilite.jpg
 
Last edited:
From yesterday; see the highlighted notes in red:
I tried swapping the words yesterday and it ended up being way off. I follow to a point. But I’m not sure exactly what to do if the word swap doesn’t work. The slave device allows you to select which order to send the words.
 
I tried swapping the words yesterday and it ended up being way off. I follow to a point. But I’m not sure exactly what to do if the word swap doesn’t work. The slave device allows you to select which order to send the words.
And I don’t know anything about coding yet. Python is on my todo list but only just jumped into the intro recently. I’m not sure where or how to even make changes to the code on one of these programs yet. This is turning into a great learning project though lol.
 
I tried swapping the words yesterday and it ended up being way off. I follow to a point. But I’m not sure exactly what to do if the word swap doesn’t work. The slave device allows you to select which order to send the words.
Now that I think about it I may have had the offset wrong when I did the word swap and that could’ve been it.
 
Now that I think about it I may have had the offset wrong when I did the word swap and that could’ve been it.
(y)(y)(y)
Good thinking; that was probably the problem; I am certain that, if you COPy a the first 16-bit word with the value 16810 and the second 16-bit word with the value 52429 to a 32-bit REAL, then that REAL will have the value 25.35.
 
(y)(y)(y)
Good thinking; that was probably the problem; I am certain that, if you COPy a the first 16-bit word with the value 16810 and the second 16-bit word with the value 52429 to a 32-bit REAL, then that REAL will have the value 25.35.
Sure enough! Thank you for all the help. I’ve got a lot to learn still but piecing it together is starting to make some sense. Mind if I PM you if I have any more questions related to this in the future?
 
Sure enough! Thank you for all the help. I’ve got a lot to learn still but piecing it together is starting to make some sense. Mind if I PM you if I have any more questions related to this in the future?
I think keeping it here is better; I am not the only person who understands this stuff.
 

Similar Topics

Hi, I started my journey with Micro820 and I have to read input status address 10001-10010 from one device via Modbus TCP, everything works fine...
Replies
0
Views
1,191
I have the HMI setup as shown in the picture. Then from my PLC and from the handy Baseblock ComTest Pro program I get a illegal data address. "...
Replies
8
Views
4,423
Hi Guys I have completed a couple of applications with the Micro820 from AB so I thought I would use one for an automated test system. I have a...
Replies
12
Views
7,137
Hello, I set up my Micro820 with a basic mapping. When I try to run a script to read the addresses I get errors for illegal addresses...
Replies
2
Views
172
Hi Guys, I am a new member and this is my first post! I have a little PLC experience but it is mostly with siemens logo and using ladder...
Replies
4
Views
905
Back
Top Bottom