3

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

Calvin Joseph
  • 33
  • 1
  • 4
  • What have you tried so far? The samples on infosys are helpful... – Felix Keil Jun 23 '17 at 11:24
  • Actually, I am trying to write array into TwinCat 3. On infosys, there is an example to read the array from twincat 3 but there is not an example how to write array from twincat 3. – Calvin Joseph Jul 03 '17 at 08:48
  • I found the example 9 is very helpful for me, now I am try to figure out how to implemented this example in my project. – Calvin Joseph Jul 03 '17 at 08:49

2 Answers2

6

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.

SomeBody
  • 7,515
  • 2
  • 17
  • 33
Ilya Dan
  • 301
  • 1
  • 8
1

I used System.Runtime.InteropServices.MarshalAs with TwinCAT 3.1.4022.0

Array declaration:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data;

And then I can send it via

TcAdsClient.WriteAny( ixGroup, ixOffset, data )
SUhrmann
  • 632
  • 1
  • 8
  • 26