Jump to content

order of data tables


Recommended Posts

I want to read and write the data tables on a PLC using the PCOM binary protocol. There are three data tables.

When I read data starting at address 0, I get the data from the table that is listed second in the Data Tables window in VisiLogic. Is there any way to tell from within VisiLogic which table is stored first on the PLC?

Link to comment
Share on other sites

  • 5 years later...

Well,  you probably know that Read Data Table is using Command number 4, and write Data Table is using command number 68.

If you use command number 75, then you can read the part of project data tables.

I think that the "Number of bytes in the entire row of the Data Table." in this case is the size of the Part of projects  row (You can look in Visilogic for the offset in Flash of 2 consecutive rows... Look at the offset in each row of a part of project cell. This should give you the size of a part of project row).... This is off course if you want to read a specific column, and not the entire part of project cells, which in this case, the"Row Size" is the same, bug the number of bytes to read in each row has the same value.

Link to comment
Share on other sites

Well, I'm guessing that the PLC does not reply to the message. I'm getting the same result Maybe this Command is obsolete, so I'll post another solution (More complicated, but it works).

First, execute a Binary message as follows:

Address = 0,
CommandCode = 5,
ElementsCount = 16,

 

If the result is 0 bytes long then the request failed.

The TopicLength is an Int32 in offset 4

If the TopicLength is 16 bytes, then it means that there are no tables in the project.

 

Assuming that the TopicLength is more than 16 bytes then  TotalLength  is result.Len - 16.

Assuming that you've got more than 16 bytes then the TotalLength  is TopicLength - 16.

 

Now execute another binary request:

Address = 16

ElementsCount = TotalLength

CommandCode = 5

SubCommand = 7

 

The TopicBlock is the result of that command.

 

Note: The TotalLength might be a big number, probably larger than 960. 

The communication buffer size in the PLC is about 960 bytes (it is a little more, but I'm taking some extra bytes so you'll not accidentally hit the limit).

If the total number of bytes you need to read (or write in some cases) is larger than the Buffer Size, then you need to split it to several messages. 

Address must always be Even

ElementsCount must always be Even

 

For example, I need to read 2495 bytes, then:

First request: Address = 16, ElementsCount = 960

Second request: Address = 976, ElementsCount = 960

Third request: Address = 1936, ElementsCount = 576  (I need 575 bytes, but I read an extra byte)

 

 

Now that you've got the TopicBlock, then you can take the Part Of Projects data out of it.

 

Inside the TopicBlock, in offset 4, you will get the total size of the Part of project cells  (Part of project cells length)

In order to get the Part of project cells, you need to take them from the TopicBlock, starting offset 12, and with the length you got (Part of project cells length.

 

If you look in Visilogic, then you will notice that the first Part of project cell in the first table starts with Flash Address 28. Why 28? 16 bytes of header, and then the 12 bytes which is the offset of the first offline cell.

But now when you have the values of the offline cells directly, then the first cell starts at offset 0 (So take the offset in Visilogic and subtract 28 from it. This would be the offset in the Part of project cells data that we have).

 

Here is a C# code example using the .Net communication driver.

            BinaryRequest br = new BinaryRequest()
            {
                Address = 0,
                CommandCode = 5,
                ElementsCount = 16,
            };

            ReadWriteRequest[] rw = new ReadWriteRequest[] { br };

            plc.ReadWrite(ref rw);

            var header = br.IncomingBuffer;

            var topicLength = BitConverter.ToInt32(header, 4);

            var totalDataLength = topicLength - 16;

            if (totalDataLength % 2 != 0)
                totalDataLength++;
 

            BinaryRequest br = new BinaryRequest()
            {
                Address = 16,
                CommandCode = 5,

                SubCommand = 7,
                ElementsCount = totalDataLength,
            };

 

            ReadWriteRequest[] rw = new ReadWriteRequest[] { br };

            plc.ReadWrite(ref rw);

 

            var topicBlock = br.IncomingBuffer;
            int cellsLength = BitConverter.ToInt32(topicBlock, 4);

            byte[] partOfProjectBlock = new byte[cellsLength];

            if (cellsLength > 0)
            {
                Array.Copy(topicBlock, 12, partOfProjectBlock, 0, cellsLength);
            }

 

 

In my case: the TopicLength is 212, so the Total Length is 196.

Here is an example of the messages that were sent to the PLC:

Sent: 2F 5F 4F 50 4C 43 00 FE 01 00 00 00 05 00 00 00

 00 00 10 00 00 00 30 FD 00 00 5C 

Received: 2F 5F 4F 50 4C 43 FE 00 01 00 00 00 85 64 00 00 

00 00 10 00 10 00 3C FC 44 42 64 FF D4 00 00 00 

FF FF FF FF FF FF FF FF 4B F5 5C 

 

Send: 2F 5F 4F 50 4C 43 00 FE 01 00 00 00 05 07 10 00

 00 00 C4 00 00 00 65 FC 00 00 5C 

Received:  2F 5F 4F 50 4C 43 FE 00 01 00 00 00 85 64 10 00 

00 00 C4 00 C4 00 C4 FA 91 B9 32 ED 3C 00 00 00 

7C 00 00 00 01 00 05 00 09 00 02 00 06 00 0A 00 

03 00 07 00 0B 00 04 00 08 00 0C 00 00 00 00 00 

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

00 63 94 60 CC 61 98 B8 D3 E8 2D 03 1F 03 17 23 

17 03 23 03 17 03 03 03 13 10 32 42 D9 8C 40 CC 

D0 F0 FF FF FF 7A 06 B8 0C 13 48 9C 11 9B 0C 33 

4E 3D 2C 38 65 58 71 CA B0 E1 94 61 C7 E9 02 0E

9C 7A 38 71 EA E1 C2 D0 C3 18 92 98 94 93 AA 60  

C8 E0 9C 9F 53 9A 9B A7 60 C0 00 63 19 C2 59 46 

70 96 31 9C 65 02 67 99 C2 59 66 70 96 39 9C 65 

01 67 59 32 30 00 00 88 49 00 CD 00 E1 C8 5C 

 

 


 

 

 

Link to comment
Share on other sites

If you follow the PCOM Protocol pdf, on page 9 you have: Binary Message Format.

the first 24 bytes are the Header, and the last 3 bytes are the Footer.

The message doesn't have to have a message details. You can see from the messsages I sent that the Data Length (bytes 20-21 in the Header) is 0.

 

The documentation does not specify that Byte 13 in the Header is the subcommand, and that bytes 14-17 is the Address, and that Bytes 18-19 are the Length to read

Lets take for example. the second message I sent:

Send: 2F 5F 4F 50 4C 43 00 FE 01 00 00 00 05 07 10 00

 00 00 C4 00 00 00 65 FC 00 00 5C 

05  - Command Code

07- Sub Command

10 00 00 00 - Address (the value is 16)

C4 00 - Length (the value is 196)

 

Please reconstruct messages like I did (you don't have to send them to the PLC, just output them) with your code. You must verify that you got the exact same message. If for example, the checksum calculation is wrong, the PLC won't reply.

 

The messages I posted were sent to a real PLC, and the replies I posted were also received from it. It works!

Link to comment
Share on other sites

C4 = 196, which is the size of All the Part of project cells + the size of the tables structure (compressed).

 

I assume (didn't check)  that if you use Binary Message with Command Code 5, Sub Command 0, Address = Flash Address from Visilogic, and Length (for example 4), then you will get the value of the first offline cell.

I did not test it, but I think it should work.

 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...