Beckhoff ADS Read Tag properties

NevisGroup

Member
Join Date
Jan 2014
Location
Wisconsin
Posts
78
Hello all:
I am in the process of writing some drivers on a PC that will communicate with a Beckhoff PLC via AMS/ADS o_O .
I can request a handle to a tag and read and write via that handle. No probs....
What I need now is how to get info about a given tag.
ie, is it a bool,int,float, etc.
if it is a struct, what is the make up of the struct?
if is is an array, how big is it?
etc...

I have done a lot of digging through the Beckhoff website.
I have found a few documents that allude to being able to do this and a few examples that use a Bechhoff library to do it.

It kind of looks like I want to use idxgrp 0xf000,0xf001,and 0xf002. But I can not find documentation on these.
If I call them I get responses.

Any pointers?
 
Here is a snippet from the AdvancedHMI TwinCAT driver where it retrieves symbol information, see if it helps:
Code:
            Dim VarName() As Byte = System.Text.Encoding.ASCII.GetBytes(symbol.ToUpper(System.Globalization.CultureInfo.InvariantCulture))
            Dim Packet(VarName.Length + 16) As Byte

            '* Group=&HF009 (ADSIGRP_SYM_INFOBYNAMEEX) and Offset=0
            BitConverter.GetBytes(Convert.ToUInt32(&HF009)).CopyTo(Packet, 0)

            'Read Length
            BitConverter.GetBytes(Convert.ToUInt32(&HFFFF)).CopyTo(Packet, 8)

            '* Length of Symbol Name + null terminator
            BitConverter.GetBytes(Convert.ToUInt32(VarName.Length + 1)).CopyTo(Packet, 12)

            '* Add symbol name to packet
            VarName.CopyTo(Packet, 16)

            '* Send the Packet to TwinCAT
            SendAMSPacket(ADSCommand.ReadWrite, Packet)
 
This code build a response packet as TwinCAT would, but you can use the offsets to parse the packet that is returned from the request:
Code:
        BitConverter.GetBytes(Result.Length).CopyTo(Result, 0)
        BitConverter.GetBytes(Convert.ToUInt32(m_IndexGroup)).CopyTo(Result, 4)
        BitConverter.GetBytes(Convert.ToUInt32(m_IndexOffset)).CopyTo(Result, 8)
        BitConverter.GetBytes(m_Size).CopyTo(Result, 12)
        BitConverter.GetBytes(m_DataType).CopyTo(Result, 16)
        BitConverter.GetBytes(m_Flags).CopyTo(Result, 20)
        BitConverter.GetBytes(Convert.ToUInt16(m_Name.Length)).CopyTo(Result, 24)
        BitConverter.GetBytes(Convert.ToUInt16(m_Type.Length)).CopyTo(Result, 26)
        BitConverter.GetBytes(Convert.ToUInt16(m_Comment.Length)).CopyTo(Result, 28)

        System.Text.ASCIIEncoding.ASCII.GetBytes(m_Name).CopyTo(Result, 30)
        System.Text.ASCIIEncoding.ASCII.GetBytes(m_Type).CopyTo(Result, 30 + m_Name.Length + 1)
        System.Text.ASCIIEncoding.ASCII.GetBytes(m_Comment).CopyTo(Result, 30 + m_Comment.Length + m_Name.Length + 2)
 
Thanks Archie. This will be very helpful.
I will be pulled away from this for a few days (bigger fires have sprung up)
Is this documented anywhere? I see references to all kinds of useful stuff in index groups 0xF000 through 0xF010.

BTW: I know I can read this out of the XML file that TC2 creates. I want to read it out of the PLC so that I don't have to worry about someone changing something online ( i.e. the size of an array) and not updating the computer.
 
Thanks Archie:
Now I have some other odd behavior.
Let me explain my setup first. This is kinda important so take notes...
My CX8090 is at IP address 192.168.73.114
My Linux work station is at 192.168.73.101
My win7 laptop is at 192.168.73.134 AND 192.168.73.156. (It is dual homed and they are the same physical port)
Each ADS address is also unique.
So with a lot of wire sharking....
I have TC2_PLC running on my laptop using 192.168.73.134...all is well
I started my Python code to read tags from the CX8090 on my Linux box (...101).
Without an explicit route setup in the CX8090 things fail..but wait..
Wireshark captures the CX8090 accepting the connection and the query from the Linux box. Instead of responding, it sends something to port 137. It appears to be a netbios name query!!!
It trys this query a few times then closes the connection that the Linux box opened. Hmmmmm

So I put in an explicit route into the CX8090 and tried this all again. Everything works great and there is no mystery packet sent to port 137.

OK so now back to my laptop.

If I do not have anything TC2 running (mind you the router is still lurking in the background somewhere) I can run my code and it works fine. The code is using IP Addr ...134. All is well.
As soon as I start TC2_PLC things get fishy.
My currently running program gets its connection closed. At this point TC_PLC in not online, just open.

Wireshark shows me that TC_PLC is also using IP addr ...134.
What I see is my running program and TC_PLC connecting to the CX8090. The CX8090 then closes one of the connections. Not right away. There my be a few transactions on both connections. It seams about 50/50 which connection it closes.
The take away here is that the CX8090 closed the connection! The connection was NOT closed on the PC side.

So..
I forced my program to use IP Addr ...156 (Dual homed, remember).
Now it behaves like my Lunix connection. If there is not an explicit route in the CX8090 to ...156, I get packets aimed at port 137 that appear to be netbios Name service.
(Note: the TCP side of the connection is all setup. All the handshaking is done. The Netbios query does not occur until I send an actual ADS packet).
After a few attempts at Netbios on port 137 the CX8090 closes the TCP connection.

When I put in the explicit route to ...156 into the CX8090 all works well.

Currently I have TC_PLC running in one window ( using ip addr ...134) and my software running in another (using ip addr 156) all on my win7 laptop. I also have my software running on the Linux workstation. Very busy network but it is working fine.

So....
What is this Netbios Name query about?
Can I ever have more than one connection to the PLC from a given IP addr?
Is there a way to answer the Netbios query such that a route gets created?
And is any of this documented?????

This was supposed to be easyo_O
 
Earlier this year I ran into a problem with both a CX8090 and a CX5010 controller in which it seemed to not want to connect. After hours of testing, I finally figured out there was an exactly 24 second delay between the first read and the response. Although I never completely figured out the cause of this, but it seemed to be related to the NETBIOS.

Since only a few controllers showed this long delay, I began experimenting to try to figure how to fix it. So far I found the only way to eliminate the long delay was to delete everything from the flash card, re-install the OS image, and set everything back up from scratch.

I never have figured out what triggers this to start happening nor an easier way to fix it. On the controllers that did it, I did a quick test to eliminate anything my driver was doing. After rebooting my PC, I opened System Manager, selected the controller, then watched the status on the lower right. It took the full 24 seconds before it would show "run". I even sent the WireShark captures to Beckhoff and they were never able to give me an answer.

I made a work around in my driver by making the timeout 25 seconds for the first read.
 
Interesting...
After I posted, I went back to playing with it a bit.
When a route is defined in the CX8090 I noticed that is still tried the NETBIOS reads but gave up and connected. Yeah it probably took 25 seconds or so. I did not time it.

But if the route is not defined it closes the connection instead.

I will try pestering my contact at Beckhoff somemore.

The issue on my end will be that the end customer will want to put my software on any computer and have it connect with the PLC.

Why can't anything simple be easy?
 
Interesting...
After I posted, I went back to playing with it a bit.
When a route is defined in the CX8090 I noticed that is still tried the NETBIOS reads but gave up and connected. Yeah it probably took 25 seconds or so. I did not time it.
If you Wireshark it and see from the first request to the first response is 24 seconds, let me know. I want to be able to go back to Beckhoff and show them that it is not just me having the problem.
 
The further I dig into this. The messier it gets.
I put wire shark on the CX8090 side so I could see everything that it was up to.
There is a lot of traffic that does not belong on an industrial network. Looks like debits from WinCe.
Anyway...My delay is more like 8 seconds. It is clearly 4 NetBios Name requests that need to time out. Each timeout is 2 seconds. There is also a DNS request that goes out as well. But my DNS server answers right away.

If your network is not answering DNS or NetBios then there would be huge delays.

Do you know if there is a way into WinCe to turn some of this off?

Also it appears that the AMS router that is lurking in the background goes a little crazy when it sees packets with a destination port of 48898. Even if they are not targeted at this computer.
(I put a port mirrored switch on the PLC and the mirrored port came into my laptop on a different network. Whenever AMS saw any packet with a destination port of 48898 it sent odd disconnect messages out the proper interface to the CX8090...very messy)
 

Similar Topics

TwinCat3 Beckhoff "Add route to remote system failed ADS Error 1804 (0x70C)" Hi everyone, I have a problem connecting with a Beckhoff CX5120...
Replies
4
Views
39,665
Hello all, I ran in to some trouble. I created 2 virtual machines to try out ADS communicating One machine is a PLC (TC2 32bit (runtime)), other...
Replies
3
Views
19,736
I want to read variables from the PLC with my C# programm. Is it possible to run my c# programm on a computer without the TwinCat System...
Replies
2
Views
2,750
Hi, I need to make two twincat 3 PLCs communicating together. I read about the Beckhoff ADS communication protocol but could not find that much...
Replies
0
Views
2,584
I has an industrial pc connect to the controller. And write the PLC program to control the machine On and off in the industrial PC. It is work...
Replies
14
Views
23,967
Back
Top Bottom