Search code examples
c#.netvisual-studioplctwincat-ads

Send an array from C# to TwinCat 3 via ADS.Net


I want to make an automated graphical fountain using TwinCat 3 to control the valves and Visual Studio C# for processing the image that want to show on the fountain.

The final form of the image processing program is a binary array image (attached) : Image Processing Result 1; Image Processing Result 2;

I want to used the final form of the image processing to control the valve on the machine (the valve will turn on when it's 1, and the valve will turn off when it's 0).I am very new with TwinCat 3 especially with the ADS Library.

The sample from infosys beckhoff not really helpful for me, can someone help me with this ?

Thank You


Solution

  • Edit: Times change, today more Linq is used, and asynchronous programming takes over. I've rewritten the code and using .Net Core with Beckhoff.TwinCAT.Ads NuGet. This code connects to localhost PLC at port 851 and writes array of 100 boolean. Array location in PLC is "MAIN.boolArray".

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using TwinCAT.Ads;
    
    namespace ArrayWrite
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                await WriteBoolArray(100);
            }
    
            private static async Task WriteBoolArray(int arrayLength)
            {
                byte[] boolArray = new byte[arrayLength];
                // Fill array with 010101010...
                boolArray = Enumerable.Range(0, arrayLength).Select(val => (val % 2 == 0) ? (byte)0 : (byte)1).ToArray();
    
                // Connect to PLC
                AdsClient client = new AdsClient();
                AmsAddress address = new AmsAddress("127.0.0.1.1.1", 851);
                client.Connect(address);
    
                // Get the handle for the array
                uint variableHandle;
                ResultHandle handleResult = await client.CreateVariableHandleAsync("MAIN.boolArray", default);
                if (handleResult.Succeeded)
                {
                    variableHandle = handleResult.Handle;
                }
                else
                {
                    Console.WriteLine($"Could not get handle. Error code: {handleResult.ErrorCode}. Press any key to exit");
                    Console.ReadKey();
                    return;
                }
    
                // Write the array
                ResultWrite writeResult = await client.WriteAnyAsync(variableHandle, boolArray, new int[] { arrayLength }, default);
                if (writeResult.Succeeded)
                {
                    Console.WriteLine($"Write successful. Press any key to exit");
                    Console.ReadKey();
                }
                else
                {
                    Console.WriteLine($"Could not write variable. Error code: {writeResult.ErrorCode}. Press any key to exit");
                    Console.ReadKey();
                    return;
                }
                // In real code the exit should clean after the code like this:
                await client.DeleteVariableHandleAsync(variableHandle, default);
                client.Disconnect();
            }
        }
    }
    

    PLC Code:

    PROGRAM MAIN
    VAR
        boolArray           : ARRAY [0..99] OF BOOL;
    END_VAR
    

    Original answer: I've made a sample console program that connects to local PLC at port 851 and writes array of 100 bools named "boolArray" in MAIN of TC3 (TwinCAT 3):

    using System;
    using TwinCAT.Ads;
    using System.Threading;
    
    namespace WriteArrayToPLC
    {
        
        class Program
        {
            static void Main(string[] args)
            {
                TcAdsClient adsClient = new TcAdsClient();
                byte[] boolArray = new byte[100];
                // Fill array with 010101010...
                for (int i = 0; i < 100; i++)
                {
                    boolArray[i] = (i % 2 != 0) ? (byte)1 : (byte)0;
                }
                // Connect to PLC
                try
                {
    
                    if (adsClient != null)
                    {
                        Console.WriteLine("Connecting to PC");
                        adsClient.Connect(851);
                    }
                }
                catch (Exception err)
                {
                    Console.WriteLine(err.Message);
                    adsClient = null;
                }
    
                if (adsClient != null)
                {
                    try
                    {
                        // Get the handle for the array
                        int handle_array = adsClient.CreateVariableHandle("MAIN.boolArray");
                        // Write the array to PLC
                        Console.WriteLine("Writing the array at handle: " + handle_array.ToString());
                        adsClient.WriteAny(handle_array, boolArray);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }
                    // The end
                    Console.WriteLine("Done");
                    Thread.Sleep(3000);
                }
            }
        }
    }
    

    This code well represents writing an array to TC3.