How to develop communication module between PLC and PC

The ADS protocol (ADS: Automation Device Specification) is a transport layer within the TwinCAT system. We use the ADS library provided by Beckhoff to communicate with the run time of the PLC. There are varieties of DLL provided by Beckhoff but we are talking here about DLL developed for the dot Net framework. The name of the DLL is TwinCAT.Ads.dll. This ADS library (DLL and library are used to mean the same thing in this document) wraps TCP/IP or UDP/IP protocols. 

In this article, we shall develop our own DLL that will wrap the TwinCAT ADS DLL (TwinCAT.Ads.dll) for easy use. The DLL will be used to read-write data from PLC. It will notify us when some variables in the PLC have changed as well. 

If you have seen the article https://www.hemelix.com/scada-hmi/beckhoff-hmi/beckhoff-twincat-hmi-javascript-framework-verses-extension-module/  then you may have noticed we have a module in the C# path that is PLC Data driver. We shall develop and describe how we can develop that module in this article. The bigger picture of the sample application will be as shown in the following image.

PLC DataManager is a DLL developed by us that can be loaded and linked by any application such as TwinCAT HMI, windows application, and so on. This is a helper class that implements reading, writing, and subscription mechanism. See how the events work in C# at https://www.hemelix.com/software/csharp-tutorial/

private TcAdsClient adsClient;
adsClient.AdsNotificationEx += new AdsNotificationExEventHandler(adsClient_AdsNotificationEx);
private void adsClient_AdsNotificationEx(object sender, AdsNotificationExEventArgs e)
{
string tag = null;
int handle = (int)e.UserData;
tag = variableHandles.FirstOrDefault(x => x.Value == handle).Key;
if (tag != null && ChangeUpdate != null)
{
ChangeUpdate(tag, e.Value);  //notify to upper level of the application
}
}

If we use TwinCAT.Ads.dll  library in our visual studio project and we add a reference to the DLL then we can declare a variable type  TcAdsClient. We need to create an event handler to get notification from the DLL. We pass a handler function when some thing happens that interests us ( see event section of https://www.hemelix.com/software/csharp-tutorial/).

If we use APP(WindowsFormsApp1) then we need to subscribe to the needed variables by ourselves and on the other hand, if we use APP (WindowsFormTestWithDLL) then the subscription is done in the PLC DataManager module.

 

If we use the ADS library directly then we need to subscribe to the change notification by ourselves.

            notificationHandles.Clear();
            try
            {
                //register notification
                notificationHandles.Add(adsClient.AddDeviceNotificationEx("MAIN.testBool", AdsTransMode.OnChange, 100, 0, handleBool, typeof(Boolean)));
                notificationHandles.Add(adsClient.AddDeviceNotificationEx("MAIN.testInt", AdsTransMode.OnChange, 100, 0, handleInteger, typeof(Int16)));
                notificationHandles.Add(adsClient.AddDeviceNotificationEx("MAIN.testReal", AdsTransMode.OnChange, 100, 0, handleReal, typeof(float)));
                notificationHandles.Add(adsClient.AddDeviceNotificationEx("MAIN.testString", AdsTransMode.OnChange, 100, 0, handleString, typeof(String), new int[] { 80 }));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

Download the test project ADS_Windows_Example_Hemelix.zip, there are 4 modules in the solution as described in the following table.

Tips

=> When we create DLL  it is better to make or use same .NET Framework.  If these are different  then we have strange problems, hard to debug.

=> If you run the test sample on your PC then the PLC and PC should be in the same network (same LAN or VPN)

=> The PLC  AMS Net ID should be added to the PC, more https://www.hemelix.com/automation/structured-text-how-to-add-route-for-plc/

=> short iclwValue = 0; //if we write int icwValue = 0; will cause problem in ADS,  see the data type