ADS?
ADS is Automation Device Specification and We can use this ADS Interface in TwinCAT to Communicate with other ADS Devices.
TwinCAT System is operating the modules (Like TwinCAT , HMI) separately and all these task had a software module with Server and Client.
Servers
Same as the Name, It works as a Server and can receive any request from an ADS client.
Clients
We can imagine that it is a role to send the request to the server and implement it by “Message router”.This “Message router” exists in any TwinCAT devices to implement the function for Server and client to exchange the data.
ADS device identification
All ADS Devices had these two identifiers.
- PortNr
- NetId
AMS-Ports
TwinCAT will auto assign the port number on the first access from the client.
And the number port can not be changed.
While you login in to the TwinCAT Runtime in the first time, the below message should be shown:
Port851=TC3 PLC Runtime System 1.
AMS NetId
TwinCAT Devices are identified by AMS NetID. This ID is configured by 8 bytes of number.
The first 4 bytes are free for configure,and the last 2 (1.1) is the Subnet Mask.
Please be careful that AMS netId can not be duplicated in your network.
Method to Confirm your NetId-1
start your twincat xae and go to system >routes.
You can see the local netid in the local netid tab.
Method to confirm your Netid -2
Go to Task BAR>Router>Change AMS Netid.
You can see the AMS netid also.
installation
In this tutorial there are two main parts of the installation. Part one is Anaconda installation and part two is the pyads library installation.
You can use any ide instead of Anaconda, for example vscode, jupyter lab..etc.
Anaconda
Access the below link and download the installation file.
https://www.anaconda.com/products/individual
Next>.
Agree the License.
Select just me and next.
set up your Install Location and Next>.
UNCheck the options and start your installation.
Please wait a second..
Press next if the installation is finished.
Next>.
Finish!
test your environment
Start the Anaconda Navigator.
You only have a Base environment now.
Click the create button to build a new virtual environment.
Setup the environment name and your python version , press create.
Sure you can do all these stuff in the Anaconda command line.
Use this command to listup the existing environment.
conda info -e |
Use this command to start the virtual environment.
activate env_pyads |
pyads
Then we can install the pyads Library now.
LINK:
We can use this library yo implement the communication between twincat3 and your host in python.
This pyads library is using the TcAdsDll.dll in windows and adslib.so in Linux.
Use this command to start the installation.
pip install pyads |
test
Please use this line to check if the library is installed or not.
import pyads |
program
There are so many functions inside the package and I will explain some important features like establishing the connection,reading /writing the variables and variable subscriptions.
Connect
In this sample I will show you how to connect to a Beckhoff plc and get the system status.
Code
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) print(‘Closing the Connections..’) plc.close() print(‘Current Status:’,plc.is_open) |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) Closing the Connections.. Current Status: False |
pyads.Connection
NetID and port are needed for this pyads.Connection function and I showed how to check these settings in the previous step.
A connection is established after calling this function.
plc.open()
plc.is_open
plc.read_state()
Use to read the current status of ads device.You can see (5,0) is returned in the previous exmpale.5 is the adsState and 0 is the device states.
0 is ERR_NOERROR.
adsState=5 and it means that the system is in run mode.
Read Devices
Code
In this example I will show you how to read the twincat runtime variable.
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) print(‘Reading Devices..’) var=plc.read_by_name(data_name=’GVL.i32′,plc_datatype=pyads.PLCTYPE_DINT) print(‘GVL.i32 is’,var) print(‘Closing the Connections..’) plc.close() print(‘Current Status:’,plc.is_open) |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) Reading Devices.. GVL.i32 is 319 Closing the Connections.. Current Status: False |
read_by_name
We can use this function to read the current value of a variable.
Basically only data_name is needed , and it means the name of variables that you would like to read.
plc_datatype is an optional parameter that allows you to check the data type of the return value.
Nothing is operated if null is passed inside.
Read Devices As List
Here is an example to show you how to read couples variables at one time.
code
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) print(‘Reading Devices List..’) varList=[‘GVL.i32′,’GVL.var1′,’GVL.var2′,’GVL.var3’] vardata=plc.read_list_by_name(varList) for k,v in vardata.items(): print(k,’:’,v) print(‘Closing the Connections..’) plc.close() print(‘Current Status:’,plc.is_open) |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) Reading Devices List.. GVL.i32 : 319 GVL.var1 : 1 GVL.var2 : 2 GVL.var3 : 3 Closing the Connections.. Current Status: False |
read_list_by_name
The concept is the same as read_by_name, but a string array is passed inside the data_namr parameter.
Each element inside your array is the variable that you would like to read.
varList=[‘GVL.i32′,’GVL.var1′,’GVL.var2′,’GVL.var3’] |
And a dictionary object is returned.
Write Devices
Here is a sample of writing a value.
Code
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) plc.write_by_name(data_name=’GVL.i32′,value=100,plc_datatype=pyads.PLCTYPE_DINT) print(‘Reading Devices List..’) varList=[‘GVL.i32′,’GVL.var1′,’GVL.var2′,’GVL.var3’] vardata=plc.read_list_by_name(varList) for k,v in vardata.items(): print(k,’:’,v) print(‘Closing the Connections..’) plc.close() print(‘Current Status:’,plc.is_open) |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) Reading Devices List.. GVL.i32 : 100 GVL.var1 : 1 GVL.var2 : 2 GVL.var3 : 3 Closing the Connections.. Current Status: False |
write_by_name
value parameter is the value that you would like to change for the target variable.
Write Devices as list
Just like reading lists, you can also write several variables at one time.
Code
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) varList=[‘GVL.i32′,’GVL.var1′,’GVL.var2′,’GVL.var3’] varWriteList={ ‘GVL.i32’:20 ,’GVL.var1′:99 ,’GVL.var2′:32 ,’GVL.var3′:88 } plc.write_list_by_name(data_names_and_values=varWriteList) print(‘Reading Devices List..’) varList=[‘GVL.i32′,’GVL.var1′,’GVL.var2′,’GVL.var3’] vardata=plc.read_list_by_name(varList) for k,v in vardata.items(): print(k,’:’,v) print(‘Closing the Connections..’) plc.close() print(‘Current Status:’,plc.is_open) |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) Reading Devices List.. GVL.i32 : 20 GVL.var1 : 99 GVL.var2 : 32 GVL.var3 : 88 Closing the Connections.. Current Status: False |
write_list_by_name
The data_names_and_values is a dictionary object.
Noifications
Finally I will show you how to play with notifications.you can assign a callback for it and execute this callback while the value of target variable is changed.
code
import pyads from ctypes import sizeof ads_net_id=’172.16.52.5.1.1′ plc=pyads.Connection(ads_net_id,pyads.PORT_TC3PLC1) print(‘Connecting to TwinCAT PLC..’) plc.open() print(‘Current connection status:’,plc.is_open) print(‘Current Status:’,plc.read_state()) @plc.notification(pyads.PLCTYPE_DINT) def callback(handle, name, timestamp, value): print(handle, name, timestamp, value) attr = pyads.NotificationAttrib(sizeof(pyads.PLCTYPE_DINT)) handles = plc.add_device_notification(‘GVL.i32’, attr, callback) #do some things plc.del_device_notification(*handles) plc.close() |
Result
Connecting to TwinCAT PLC.. Current connection status: True Current Status: (5, 0) handle: 26 name: GVL.i32 timestamp: 2021-10-02 00:41:39.946000 value: 555 |
add_device_notification
Add the Device notification and you need the variable name,NotificationAttrib, and the CallBack function.
NotificationAttrib
del_device_notification
Please delete the notification if it is not using in your application anymore.
コメント
Hello Gomamenotes,
Thank you for the informative post. It has greatly helped me in understanding Pyads.
I have a question regarding this library. If my target device is in Config mode with TwinCAT, is it possible to initiate it using a Python command?
Thank you.
Hi Lujaini,
Thanks for your Comment.
For remote change the TwinCAT Runtime Mode,
Yoy may use the Automation Interface.
Please find more information from this link:
https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_automationinterface/242682763.html&id=
Hi,
I am interested with your blog here, since I want to communicate beckhoff cx5010 with siemens s7-1500 with python.
I want to know if it is possible a communication between twincat2 and python
Hi ,
How can I get the connection Between My jetson nano(Romote accessed using ssh) to twincat (HMI)