Invoking RPC methods with TwinCAT ADS .NET

A lot of GUI’s are written in a .NET framework language or even .NET5. For example a project in WPF/C#. A typical way to setup the communication between the PC and the PLC is to make use of the by Beckhoff provided .NET ads library. Reading and writing of variables is easily done, but sometime is is also useful to invoke a method. And haven’t we all done this:

IF _execute THEN
    _execute := FALSE;

Wrapping a boolean variable around a method. Simple, but effective however, there is another way:

Invoking RPC methods

TwinCAT provides a direct way of invoking methods over ADS. The so called RPC methods. RPC stands for Remote Procedure Call. The RPC methods were introduced to comply with the OPC-UA standard, but can be used outside this scope as well. To make a method available for a RPC the method has to be marked with the pragma: {attribute ‘TcRpcEnable’}

For example:

{attribute 'TcRpcEnable'}
    Input1 : LREAL;
    Input2 : LREAL;

Using the ADSClient from the .NET ADS V5 library which implements the IAdsRpcInvoke interface we can directly invoke the methods marked with the TcRpcEnable pragma.

Creating an example project

The PLC software

The easiest part is the PLC project this time, setup a new XAE project with a default PLC configuration. Now we are gonna add our RPC method. Add a new function block in the POU folder called ‘FbCalculator’. Then add the following method to this new function block:

{attribute 'TcRpcEnable'}
    Input1 : LREAL;
    Input2 : LREAL;


Sum := Input1 + Input2;

The main program simply holds an instance of the calculator class:

    _fbCalculator : FbCalculator;

Your project structure should now look like this:

The PC software

For the PC software i’m gonna use a console project in .NET 5. First step in the new project is to add the TwinCAT ADS nuget package:

dotnet add package Beckhoff.TwinCAT.Ads –version 5.0.458

In the program.cs we start with an async class:

using System;
using System.Threading;
using System.Threading.Tasks;
using TwinCAT.Ads;

namespace InvokingRpcMethodsDemo
    internal class Program
        private static async Task Main(string[] args)

In the class we create a new instance of the ADSClient. Notice the using statement! this correctly disposes the client when the programs exits. The new created instance ‘client’ connects to your plc.

CancellationToken cancel = CancellationToken.None;
using AdsClient client = new AdsClient(); // New instance of the TwinCAT ADS client.
client.Connect("", 851);
if (!client.IsConnected)
   Console.WriteLine("Cannot connect to the PLC");

Console.WriteLine("Succesfully connected to the PLC");

Once connected to the PLC we can ask the inputs from the user and call the RPC summation method:

Console.WriteLine("Summation demo, enter first value:");
float value1 = float.Parse(Console.ReadLine() ?? string.Empty);

Console.WriteLine("Summation demo, enter second value:");
float value2 = float.Parse(Console.ReadLine() ?? string.Empty);

ResultRpcMethod result =
    await client.InvokeRpcMethodAsync("Main._fbCalculator",
    new object[] { value1, value2 },

The method ‘InvokeRpcMethodAsync’ calls the RPC method in the PLC, in this example we use 4 arguments:

  1. The path to the method instance: “Main._fbCalculator”.
  2. The name of the RPC method to be invoked: “Sum”.
  3. An array of objects with the two user inputs.
  4. A cancellation token, which can be used as a timeout.

And to make this demo complete, outputting the results:

                ? $"Succesfully calculated, result is: {result.ReturnValue}"
                : $"Failed calling RPC method, error code: {result.ErrorCode}");


Time to run the demo application, make sure to login the PLC first, secondly make sure the that the AmsNetId in the console application matches the one of your plc.
Third step: Run your console application, and if everything goes well:


In this post I showed another way to communicate from you PC application with the PLC application using RPC method calling. The complete demo project can be found at this github repository Do you want to learn more about ADS communication? Check out this post.



Gerhard Barteling

Gerhard is a mechatronic engineer with a predilection for software engineering.