0

我在 Windows XP SP2 上使用 TwinCAT I/O 2.11。使用 .NET 库“TwinCAT.ADS”,我已经设法读取和写入输入/输出(来自 EtherCAT 总线上设备的映射对象)。但当然,这仅在 TwinCAT 处于 Freerun 或 Realtime 模式时才有效。

我现在的问题是:我可以手动设置 TwinCAT 模式。但是如何使用 Win32 程序设置 TwinCat 模式(Freerun、Realtime、...)?我没有在 TwinCAT.ADS 中找到合适的函数。有没有这样的功能?

4

3 回答 3

0

我找到了一个解决方案:命名空间 TCatSysManagerLib(来自文件 C:\TwinCAT\Io\AddIns\TCatSysManagerLib.dll)提供了一个名为 ITcSysManager 的类,它使您能够从 TwinCAT 访问系统管理器功能。

于 2014-05-08T07:21:51.417 回答
0

我只对 TwinCAT3 有一些经验,但是库是一样的。

在 TwinCAT3 中,我们区分了模式RUNCONFIG。要在两种模式之间切换,您将需要 TCatSysManagerLib,这是真的。但是(尤其是对于 TwinCAT3)没有切换回CONFIG模式的方法(但是……但是 Beckhoff 正在努力)。

如果你想这样做,你需要通过 AmsPort.SystemService 是 10000。

下面是一个如何从RUN模式切换到CONFIG模式的示例:

public void setConfigMode()
{
    TcAdsClient client = new TcAdsClient();
    StateInfo mode = new StateInfo();

    client.Connect((int)AmsPort.SystemService);
    mode.AdsState = AdsState.Reconfig;
    client.WriteControl(mode);

    client.Dispose();
}

而这里是从CONFIGRUN模式的相反方式(使用 TCatSysManagerLib):--> 仅适用于 TwinCAT3

public void setRunMode()
{
    // _solution_path, _solution_name must be replaced by your solution path and solution name
    Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
    EnvDTE80.DTE2 dte2 = (EnvDTE80.DTE2)System.Activator.CreateInstance(t);
    dte2.MainWindow.Visible = false; //keep TwinCAT window closed
    Solution4 solution4 = (Solution4)dte2.Solution;
    EnvDTE.Project project = null;
    solution4.Open(Path.Combine(_solution_path, _solution_name + ".sln").ToString());
    project = (EnvDTE.Project)solution4.Projects.Item(1);
    ITcSysManager5 sysmanager5 = (ITcSysManager5)project.Object;
    sysmanager5.StartRestartTwinCAT();
    dte2.Quit();
}

或(我没试过):

public void setRunMode()
{
    TcAdsClient client = new TcAdsClient();
    StateInfo mode = new StateInfo();

    client.Connect((int)AmsPort.SystemService);
    mode.AdsState = client.ReadState().AdsState;
    mode.AdsState = AdsState.Reset;
    client.WriteControl(mode);

    client.Dispose();
}
于 2015-11-05T15:56:43.687 回答
0

我已经根据@ChrisKo 的回答实施了一个解决方案。以下 WinForms 代码的运行前提是,存在一个名称为 的表单,该名称Form1具有三个按钮_runButton,分别为_configButton_exitButton。该项目应具有对 TwinCAT.Ads.dll 的引用。

using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using TwinCAT.Ads;

namespace TwinCatStateREader
{
    public partial class Form1 : Form
    {
        private TcAdsClient _tcClient;

        private TcAdsClient _tcSystemClient;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                _tcClient = new TcAdsClient();
                _tcClient.Connect(851);

                _tcSystemClient = new TcAdsClient();
                _tcSystemClient.Connect((int)AmsPort.SystemService);

                if (_tcSystemClient.ReadState().AdsState != AdsState.Run)
                {
                    _configButton.Enabled = false;
                    _runButton.Enabled = true;
                }
                else
                {
                    _runButton.Enabled = false;
                    _configButton.Enabled = true;
                }
            }
            catch (AdsErrorException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void _exitButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                _tcClient.Disconnect();
                _tcClient.Dispose();

                _tcSystemClient.Disconnect();
                _tcSystemClient.Dispose();
            }
            catch (AdsErrorException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void _configButton_Click(object sender, EventArgs e)
        {
            _configButton.Enabled = false;
            _tcSystemClient.WriteControl(new StateInfo(AdsState.Reconfig, _tcSystemClient.ReadState().DeviceState));

            if (WaitForState(AdsState.Config, 3000))
            {
                _runButton.Enabled = true;
            }
            else
            {
                _configButton.Enabled = true;
            }
        }

        private void _runButton_Click(object sender, EventArgs e)
        {
            _runButton.Enabled = false;
            _tcSystemClient.WriteControl(new StateInfo(AdsState.Reset, _tcSystemClient.ReadState().DeviceState));

            if (WaitForState(AdsState.Run, 3000))
            {
                _configButton.Enabled = true;
            }
            else
            {
                _runButton.Enabled = true;
            }
        }

        private bool WaitForState(AdsState state, int timeOutInMilliSeconds)
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            while (stopwatch.ElapsedMilliseconds <= timeOutInMilliSeconds)
            {
                try
                {
                    if (_tcSystemClient.ReadState().AdsState == state)
                    {
                        return true;
                    }
                }
                catch (AdsErrorException)
                {
                    // This can happen while ADS changes state and we try to read it
                }
                finally
                {
                    Thread.Sleep(20);
                }
            }

            stopwatch.Stop();
            return false;
        }
    }
}

请注意,此解决方案使用两个连接到不同端口 (851 / 10000) 的广告客户端

于 2018-08-30T13:41:48.003 回答