June 9, 2016

Нюансы библиотек в TwinCAT 3

В TwinCAT 3 изменился подход к библиотекам. Он усложнился.

Новые библиотеки бывают двух видов:
  • .library — с исходными кодами и собранной библиотекой. Занимает больше места и не скрывает интеллектуальную собственность.
  • .compiled-library — только собранная библиотека, без исходных кодов. Очень небольшого размера и зашифрована. Восстановить исходный код невозможно.

Эти файлы, как сейчас стало модно, являются zip-архивами с человеко-невменяемым содержимым.

Стандартный репозиторий (хранилище библиотек) расположен здесь:
x:\TwinCAT\3.1\Components\Plc\Managed Libraries.

Далее идут: организация разработчик → имя библиотеки → версия → и непосредственно сама библиотека. В итоге для библиотеки Tc2_EtherCAT получается следующий путь:
x:\TwinCAT\3.1\Components\Plc\Managed Libraries\Beckhoff Automation GmbH\Tc2_EtherCAT\3.3.7.0\Tc2_EtherCAT.compiled-library-ge33

Рядом с библиотекой лежат три файла (ничего интересного):
  • projectinfo — бинарная информация о библиотеке;
  • dependencies — текстовый файл со списком библиотек от которых зависит данная библиотека;
  • browsercache — вспомогательная системная информация в виде xml-файл.

Если библиотека поставляется с исходными кодами, то вместо файла .compiled-library-ge33 будет лежать файл .library.


де / Инсталляция


Нельзя просто так взять и удалить библиотеку. Добавить тоже не просто так.
Вообще-то можно, но TwinCAT будет ругаться и последствия могут быть произвольными.

Теперь недостаточно просто скопировать файл библиотеки, его необходимо установить в локальное хранилище (репозиторий). Для это ткнуть правой кнопкой мыши ветку References и выбрать Library repository... Затем воспользоваться кнопкой Install... Аналогично для деинсталляции, только кнопка Uninstall.


Плейсхолдеры вместо библиотек


На самом деле в References проекта добавляются не библиотеки, а плейсхолдеры (placeholders), которые служат оберткой вокруг библиотеки и позволяют всегда загружать необходимую версию библиотеки для разного оборудования и разных версий TwinCAT.

Там еще много чего вокруг них наворочено, но по большей части для стандартных библиотек они работают автоматически.


Разработка


Для того чтобы создать новую библиотеку необходимо добавить к ветке PLC → Empty PLC Project. После окончания разработки функций библиотеки, достаточно ткнуть правой кнопкой мыши экземпляр PLC-проекта: ветка PLC → <имя проекта> Project, и выбрать Save as library... или Save as library and install... чтобы еще и установить сразу же в локальный репозиторий.


Чуть больше подробностей для разработчиков библиотек можно почерпнуть в статьях Intro PLC Libraries и Library Management.

June 7, 2016

Работа с CANopen из C# программы

Большинство модулей расширения на шине EtherCAT внутри себя работают через собственную шину: CANopen, SERCOS, и т. п. Чтобы напрямую обратиться к внутренним регистрам модуля, необходимо выполнить ряд подготовительных операций, а точнее, правильно сформировать AmsNetId, индекс группы и смещение в функциях чтения через протокол ADS. Включать ADS-сервер шины EtherCAT при этом не требуется.
Про работу с SERCOS можно прочитать в статье S и P параметры сервоусилителей.

Адрес модуля, к регистрам которого мы будем обращаться, можно подсмотреть в зеленой ветке InfoData.



Передать адрес модуля в программу на C# можно через ПЛК-программу и выделенную переменную с заранее известным именем, либо извлечь через TwinCAT Automation Interface. Первый вариант — проще, второй — универсальный.

Для демонстрации я взял модуль инкрементального энкодера EL5151. Просто потому, что у него красивый артикул и внутри шина CANopen.

Индекс группы сервиса ADS, отвечающего за работу с CANopen SDO:
EC_ADS_IGRP_CANOPEN_SDO = 0xF302;
Индекс смещения формируется как двойное слово (32-разряда), состоящее из индекса и субиндекса адреса CANopen:
SHLWORD_TO_DWORD(nIndex), 16 ) OR BYTE_TO_WORD( nSubIndex )

В качестве примера я хочу прочитать 1018:02 (Identity : Product code), т. е. я хочу прочитать из модуля его артикул:

using System;
using TwinCAT.Ads;

class Program
{
    static long EC_ADS_IGRP_CANOPEN_SDO = 0xF302;

    static void Main(string[] args)
    {
        const string ETHERCAT_BUS_AMSNETID = "192.168.1.18.2.1";
        const int EL5151_AMSPORT = 1002;

        TcAdsClient client = new TcAdsClient();
        client.Connect(
            ETHERCAT_BUS_AMSNETID,
            EL5151_AMSPORT);

        // CANopen SDO Identity:Product code = 1018:02
        uint cansdo_Index = 0x1018;
        uint cansdo_SubIndex = 0x02;

        long CanSdoOffset = cansdo_Index << 16 | cansdo_SubIndex;

        uint Identity_ProductCode =
            (uint)client.ReadAny(
                EC_ADS_IGRP_CANOPEN_SDO, 
                CanSdoOffset,
                typeof(uint));

        Console.WriteLine(
             string.Format(
                "1018:02 = 0x{0} ({1})",
                Identity_ProductCode.ToString("X2"),
                Identity_ProductCode));

        Console.ReadKey();
    } // Main
} // class


Сравниваем полученный результат:



Аналогично можно записывать параметры, при условии, что они доступны для записи. На картинке выше колонка Flags отображает доступность регистров: RO — только для чтения, RW — чтение/запись.