TwinCAT 2.11: установка режима Config/Freerun с Win32-приложением

Я использую TwinCAT I/O 2.11 в Windows XP SP2. С .NET-библиотекой "TwinCAT.ADS" мне уже удалось прочитать и записать Входы/Выходы (сопоставленные объекты с устройства на шине EtherCAT). Но, конечно, это работает только тогда, когда TwinCAT находится в режиме Freerun или в режиме реального времени.

Теперь мой вопрос: я могу установить режим TwinCAT вручную. Но как установить режим TwinCat (Freerun, Realtime, ...) с помощью программы Win32? Я не нашел подходящей функции в TwinCAT.ADS. Существует ли такая функция?


person user3297416    schedule 07.05.2014    source источник


Ответы (3)


Я нашел решение: пространство имен TCatSysManagerLib (из файла C:\TwinCAT\Io\AddIns\TCatSysManagerLib.dll) предоставляет класс с именем ITcSysManager, который позволяет вам получить доступ к функциям системного администратора из TwinCAT.

person user3297416    schedule 08.05.2014

У меня есть только некоторый опыт работы с TwinCAT3, но библиотека та же самая.

В TwinCAT3 различаются режимы RUN и CONFIG. Для переключения между обоими режимами вам понадобится 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();
}

А здесь обратный путь из режима CONFIG в режим RUN (с использованием 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();
}
person Chris    schedule 05.11.2015

Я реализовал решение, основанное на ответе @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).

person froeschli    schedule 30.08.2018