Exemplo n.º 1
0
        static async Task Main(string[] args)
        {
            /* Set interface name. Edit this to suit your needs. */
            var interfaceName = "eth0";

            /* Set ESI location. Make sure it contains ESI files! The default path is /home/{user}/.local/share/ESI */
            var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var esiDirectoryPath = Path.Combine(localAppDataPath, "ESI");

            Directory.CreateDirectory(esiDirectoryPath);

            /* Copy native file. NOT required in end user scenarios, where EtherCAT.NET package is installed via NuGet! */
            var codeBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            Directory.EnumerateFiles(Path.Combine(codeBase, "runtimes"), "*soem_wrapper.*", SearchOption.AllDirectories).ToList().ForEach(filePath =>
            {
                if (filePath.Contains(RuntimeEnvironment.RuntimeArchitecture))
                {
                    File.Copy(filePath, Path.Combine(codeBase, Path.GetFileName(filePath)), true);
                }
            });

            /* create logger */
            var loggerFactory = LoggerFactory.Create(loggingBuilder =>
            {
                loggingBuilder.SetMinimumLevel(LogLevel.Debug);
                loggingBuilder.AddConsole();
            });

            var logger = loggerFactory.CreateLogger("EtherCAT Master");

            /* create EtherCAT master settings (with 10 Hz cycle frequency) */
            var settings = new EcSettings(cycleFrequency: 10U, esiDirectoryPath, interfaceName);

            /* scan available slaves */
            var rootSlave = EcUtilities.ScanDevices(settings.InterfaceName);

            rootSlave.Descendants().ToList().ForEach(slave =>
            {
                // If you have special extensions for this slave, add it here:
                // slave.Extensions.Add(new MyFancyExtension());

                /*################ Sample code START ##################
                 *
                 * // Example code to add SDO write request during initialization
                 * // to Beckhoff "EL3021"
                 * if (slave.ProductCode == 0xBCD3052)
                 * {
                 *  var dataset = new List<object>();
                 *  dataset.Add((byte)0x01);
                 *
                 *  var requests = new List<SdoWriteRequest>()
                 *  {
                 *      // Index 0x8000 sub index 6: Filter on
                 *      new SdoWriteRequest(0x8000, 0x6, dataset)
                 *  };
                 *
                 *  slave.Extensions.Add(new InitialSettingsExtension(requests));
                 * }
                 *
                 ################## Sample code END #################*/

                EcUtilities.CreateDynamicData(settings.EsiDirectoryPath, slave);
            });

            /* print list of slaves */
            var message = new StringBuilder();
            var slaves  = rootSlave.Descendants().ToList();

            message.AppendLine($"Found {slaves.Count()} slaves:");

            foreach (var slave in slaves)
            {
                message.AppendLine($"{slave.DynamicData.Name} (PDOs: {slave.DynamicData.Pdos.Count} - CSA: {slave.Csa})");
            }

            logger.LogInformation(message.ToString().TrimEnd());

            /* create variable references for later use */
            var variables = slaves.SelectMany(child => child.GetVariables()).ToList();

            /* create EC Master (short sample) */
            using (var master = new EcMaster(settings, logger))
            {
                try
                {
                    master.Configure(rootSlave);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.Message);
                    throw;
                }

                /* start master */
                var random = new Random();
                var cts    = new CancellationTokenSource();

                var task = Task.Run(() =>
                {
                    var sleepTime = 1000 / (int)settings.CycleFrequency;

                    while (!cts.IsCancellationRequested)
                    {
                        master.UpdateIO(DateTime.UtcNow);

                        unsafe
                        {
                            if (variables.Any())
                            {
                                var myVariableSpan = new Span <int>(variables.First().DataPtr.ToPointer(), 1);
                                myVariableSpan[0]  = random.Next(0, 100);
                            }
                        }

                        Thread.Sleep(sleepTime);
                    }
                }, cts.Token);

                /* wait for stop signal */
                Console.ReadKey(true);

                cts.Cancel();
                await task;
            }

            return; /* remove this to run real world sample*/

            /* create EC Master (real world sample) */
            using (var master = new EcMaster(settings, logger))
            {
                try
                {
                    master.Configure(rootSlave);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.Message);
                    throw;
                }

                /*################ Sample code START ##################
                 *
                 * // Beckhoff EL2004 (4 channel digital output)
                 * var eL2004 = new DigitalOut(slaves[1]);
                 *
                 * eL2004.SetChannel(1, false);
                 * eL2004.SetChannel(2, true);
                 * eL2004.SetChannel(3, false);
                 * eL2004.SetChannel(4, true);
                 *
                 * // Beckhoff EL1014 (4 channel digital input)
                 * var eL1014 = new DigitalIn(slaves[2]);
                 *
                 * // Beckhoff EL3021 (1 channel analog input - 16bit)
                 * var pdoAnalogIn = slaves[3].DynamicData.Pdos;
                 * var varAnalogIn = pdoAnalogIn[0].Variables.Where(x => x.Name == "Value").First();
                 * var varUnderrange = pdoAnalogIn[0].Variables.Where(x => x.Name == "Status__Underrange").First();
                 * var varOverrange = pdoAnalogIn[0].Variables.Where(x => x.Name == "Status__Overrange").First();
                 *
                 * // Beckhoff EL3021 SDO read (index: 0x8000 sub index: 0x6)
                 * var datasetFilter = new byte[2];
                 * EcUtilities.SdoRead(master.Context, 4, 0x8000, 6, ref datasetFilter);
                 * var filterOn = BitConverter.ToBoolean(datasetFilter, 0);
                 * logger.LogInformation($"EL3021 filter on: {filterOn}");
                 *
                 ################## Sample code END #################*/

                /* start master */
                var random = new Random();
                var cts    = new CancellationTokenSource();

                var task = Task.Run(() =>
                {
                    var sleepTime = 1000 / (int)settings.CycleFrequency;

                    while (!cts.IsCancellationRequested)
                    {
                        master.UpdateIO(DateTime.UtcNow);

                        /*################ Sample code START ##################
                         *
                         * // Beckhoff EL2004 toggle digital output for ch1 and ch3
                         * eL2004.ToggleChannel(2);
                         * eL2004.ToggleChannel(4);
                         *
                         * // Beckhoff EL1014 read digital input state
                         * logger.LogInformation($"EL1014 channel 1 input: {eL1014.GetChannel(1)}");
                         * logger.LogInformation($"EL1014 channel 2 input: {eL1014.GetChannel(2)}");
                         * logger.LogInformation($"EL1014 channel 3 input: {eL1014.GetChannel(3)}");
                         * logger.LogInformation($"EL1014 channel 4 input: {eL1014.GetChannel(4)}");
                         *
                         * // Beckhoff EL2004 read digital output state
                         * logger.LogInformation($"EL1014 channel 1 output: {eL2004.GetChannel(1)}");
                         * logger.LogInformation($"EL1014 channel 2 output: {eL2004.GetChannel(2)}");
                         * logger.LogInformation($"EL1014 channel 3 output: {eL2004.GetChannel(3)}");
                         * logger.LogInformation($"EL1014 channel 4 output: {eL2004.GetChannel(4)}");
                         *
                         * // Beckhoff EL3021 SDO read (index: 0x6000 sub index: 0x2)
                         * // overrange of 12 bit analog input.
                         * var slaveIndex = (ushort)(Convert.ToUInt16(slaves.ToList().IndexOf(slaves[3])) + 1);
                         * var dataset1 = new byte[2];
                         * EcUtilities.SdoRead(master.Context, slaveIndex, 0x6000, 2, ref dataset1);
                         * bool overrange = BitConverter.ToBoolean(dataset1, 0);
                         * logger.LogInformation($"EL3021 overrange: {overrange}");
                         *
                         * // Beckhoff EL3021 SDO read (index: 0x6000 sub index: 0x1)
                         * // underrange of 12 bit analog input.
                         * var dataset2 = new byte[2];
                         * EcUtilities.SdoRead(master.Context, slaveIndex, 0x6000, 1, ref dataset2);
                         * bool underrange = BitConverter.ToBoolean(dataset2, 0);
                         * logger.LogInformation($"EL3021 underrange: {underrange}");
                         *
                         ################## Sample code END #################*/

                        unsafe
                        {
                            if (variables.Any())
                            {
                                /*################ Sample code START ##################
                                 *
                                 * // Read analog current from EL3021 (16 bit - PDO)
                                 * void* data = varAnalogIn.DataPtr.ToPointer();
                                 * int bitmask = (1 << varAnalogIn.BitLength) - 1;
                                 * int shift = (*(int*)data >> varAnalogIn.BitOffset) & bitmask;
                                 * short analogIn = (short)shift;
                                 * logger.LogInformation($"EL3021 analog current in: {analogIn}");
                                 *
                                 * // Read analog current underrange status (1 bit - PDO)
                                 * void* dataUnder = varUnderrange.DataPtr.ToPointer();
                                 * bitmask = (1 << varUnderrange.BitLength) - 1;
                                 * int under = (*(int*)dataUnder >> varUnderrange.BitOffset) & bitmask;
                                 * logger.LogInformation($"EL3021 underrange: {under}");
                                 *
                                 * // Read analog current overrange status (1 bit - PDO)
                                 * void* dataOver = varOverrange.DataPtr.ToPointer();
                                 * bitmask = (1 << varOverrange.BitLength) - 1;
                                 * int over = (*(int*)dataOver >> varOverrange.BitOffset) & bitmask;
                                 * logger.LogInformation($"EL3021 overrange: {over}");
                                 *
                                 ################## Sample code END #################*/
                            }
                        }

                        Thread.Sleep(sleepTime);
                    }
                }, cts.Token);

                /* wait for stop signal */
                Console.ReadKey(true);

                cts.Cancel();
                await task;
            }
        }
Exemplo n.º 2
0
        static async Task Main(string[] args)
        {
            /* Set interface name. Edit this to suit your needs. */
            var interfaceName = "eth0";

            /* Set ESI location. Make sure it contains ESI files! The default path is /home/{user}/.local/share/ESI */
            var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var esiDirectoryPath = Path.Combine(localAppDataPath, "ESI");

            Directory.CreateDirectory(esiDirectoryPath);

            /* Copy native file. NOT required in end user scenarios, where EtherCAT.NET package is installed via NuGet! */
            var codeBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            Directory.EnumerateFiles(Path.Combine(codeBase, "runtimes"), "*soem_wrapper.*", SearchOption.AllDirectories).ToList().ForEach(filePath =>
            {
                if (filePath.Contains(RuntimeEnvironment.RuntimeArchitecture))
                {
                    File.Copy(filePath, Path.Combine(codeBase, Path.GetFileName(filePath)), true);
                }
            });

            /* prepare dependency injection */
            var services = new ServiceCollection();

            ConfigureServices(services);

            /* create types */
            var provider         = services.BuildServiceProvider();
            var extensionFactory = provider.GetRequiredService <IExtensionFactory>();
            var loggerFactory    = provider.GetRequiredService <ILoggerFactory>();
            var logger           = loggerFactory.CreateLogger("EtherCAT Master");

            /* create EtherCAT master settings (with 10 Hz cycle frequency) */
            var cycleFrequency = 10U;
            var settings       = new EcSettings(cycleFrequency, esiDirectoryPath, interfaceName);

            /* create root slave info by scanning available slaves */
            var rootSlaveInfo = EcUtilities.ScanDevices(settings.InterfaceName);

            rootSlaveInfo.Descendants().ToList().ForEach(current =>
            {
                ExtensibilityHelper.CreateDynamicData(settings.EsiDirectoryPath, extensionFactory, current);
            });

            /* print list of slaves */
            var message = new StringBuilder();
            var slaves  = rootSlaveInfo.Descendants().ToList();

            message.AppendLine($"Found {slaves.Count()} slaves:");

            slaves.ForEach(current =>
            {
                message.AppendLine($"{current.DynamicData.Name} (PDOs: {current.DynamicData.PdoSet.Count} - CSA: { current.Csa })");
            });

            logger.LogInformation(message.ToString().TrimEnd());

            /* create variable references for later use */
            var variables = slaves.SelectMany(child => child.GetVariableSet()).ToList();

            /* create EC Master */
            using (var master = new EcMaster(settings, extensionFactory, logger))
            {
                try
                {
                    master.Configure(rootSlaveInfo);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.Message);
                    throw;
                }

                /* start master */
                var random = new Random();
                var cts    = new CancellationTokenSource();

                var task = Task.Run(() =>
                {
                    var sleepTime = 1000 / (int)cycleFrequency;

                    while (!cts.IsCancellationRequested)
                    {
                        master.UpdateIO(DateTime.UtcNow);

                        unsafe
                        {
                            if (variables.Any())
                            {
                                var myVariableSpan = new Span <int>(variables.First().DataPtr.ToPointer(), 1);
                                myVariableSpan[0]  = random.Next(0, 100);
                            }
                        }

                        Thread.Sleep(sleepTime);
                    }
                }, cts.Token);

                /* wait for stop signal */
                Console.ReadKey(true);

                cts.Cancel();
                await task;
            }
        }
Exemplo n.º 3
0
        static async Task Main(string[] args)
        {
            /* Set interface name. Edit this to suit your needs. */
            var interfaceName = "Lokal";

            /* Set ESI location. Make sure it contains ESI files! The default path is /home/{user}/.local/share/ESI */
            var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var esiDirectoryPath = Path.Combine(localAppDataPath, "ESI");

            Directory.CreateDirectory(esiDirectoryPath);

            /* Copy native file. NOT required in end user scenarios, where EtherCAT.NET package is installed via NuGet! */
            var codeBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            Directory.EnumerateFiles(Path.Combine(codeBase, "runtimes"), "*soem_wrapper.*", SearchOption.AllDirectories).ToList().ForEach(filePath =>
            {
                if (filePath.Contains(RuntimeEnvironment.RuntimeArchitecture))
                {
                    File.Copy(filePath, Path.Combine(codeBase, Path.GetFileName(filePath)), true);
                }
            });

            /* create logger */
            var loggerFactory = LoggerFactory.Create(loggingBuilder =>
            {
                loggingBuilder.SetMinimumLevel(LogLevel.Debug);
                loggingBuilder.AddConsole();
            });

            var logger = loggerFactory.CreateLogger("EtherCAT Master");

            /* create EtherCAT master settings (with 10 Hz cycle frequency) */
            var settings = new EcSettings(cycleFrequency: 10U, esiDirectoryPath, interfaceName);

            /* scan available slaves */
            var rootSlave = EcUtilities.ScanDevices(settings.InterfaceName);

            rootSlave.Descendants().ToList().ForEach(slave =>
            {
                // If you have special extensions for this slave, add it here:
                // slave.Extensions.Add(new MyFancyExtension());

                EcUtilities.CreateDynamicData(settings.EsiDirectoryPath, slave);
            });

            /* print list of slaves */
            var message = new StringBuilder();
            var slaves  = rootSlave.Descendants().ToList();

            message.AppendLine($"Found {slaves.Count()} slaves:");

            foreach (var slave in slaves)
            {
                message.AppendLine($"{slave.DynamicData.Name} (PDOs: {slave.DynamicData.Pdos.Count} - CSA: {slave.Csa})");
            }

            logger.LogInformation(message.ToString().TrimEnd());

            /* create variable references for later use */
            var variables = slaves.SelectMany(child => child.GetVariables()).ToList();

            /* create EC Master */
            using (var master = new EcMaster(settings, logger))
            {
                // If you want to change SDO values of a certain slave, register a callback:
                //
                // EcHL.RegisterCallback(master.Context, slaveIndex /* 1-based indexing */, slaveIndex =>
                // {
                //     var returnValue = EcUtilities.SdoWrite(master.Context, slaveIndex, ...);
                //     EcUtilities.CheckErrorCode(master.Context, returnValue);
                //     return 0;
                // });

                try
                {
                    master.Configure(rootSlave);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.Message);
                    throw;
                }

                /* start master */
                var random = new Random();
                var cts    = new CancellationTokenSource();

                var task = Task.Run(() =>
                {
                    var sleepTime = 1000 / (int)settings.CycleFrequency;

                    while (!cts.IsCancellationRequested)
                    {
                        master.UpdateIO(DateTime.UtcNow);

                        unsafe
                        {
                            if (variables.Any())
                            {
                                var myVariableSpan = new Span <int>(variables.First().DataPtr.ToPointer(), 1);
                                myVariableSpan[0]  = random.Next(0, 100);
                            }
                        }

                        Thread.Sleep(sleepTime);
                    }
                }, cts.Token);

                /* wait for stop signal */
                Console.ReadKey(true);

                cts.Cancel();
                await task;
            }
        }