April 29, 2015

Большая клавиатура навсегда

Windows CE способно работать как с небольшими, так и с большими разрешениями экрана; поэтому в системе предусмотрены две экранные клавиатуры (Soft Input Panel (SIP): поменьше и побольше. В более новой Windwos CE 6 уже предусмотрено переключение клавиатур, и система этот выбор запоминает при перезагрузке. У более старой "пятерки" с памятью совсем плохо. Нужен костыль.

  1. "Start" → "Run..." → "regedit" → OK
  2. Открываем ветку: HKEY_CURRENT_USER\ControlPanel\SIP
  3. Правим значение параметра: DefaultIm
Большая клавиатура: {a523dfc7-1a7e-4af6-991a-510e75847828}
Маленькая клавиатура: {42429667-ae04-11d0-a4f8-00aa00a749b9}
Осталось перезагрузить контроллер.

April 28, 2015

Перформанс ADS.API под .NET

Как утверждает мой проводник, на этом компьютере есть библиотека TwinCAT.Ads.dll, которая позволяет обращаться к данным ПЛК через протокол ADS. Библиотека автоматически устанавливается вместе с Твинкатом (как вторым, так и третьим) и кроме нее, есть еще неплохой набор для множества других языков программирования.



Она удобная, есть документация и примеры. Вопрос в том - насколько она быстра?

Вопрос номер два - при наличии большого ассортимента контроллеров и гигантского количества "персоналок", как определить быстродействие и от чего отталкиваться?


Методика


На помощь спешит детерминированность ПЛК-цикла. Время цикла системы реального времени жестко выдерживается, значит мы можем посчитать сколько ПЛК-циклов библиотека ADS.API будет пропускать (или не будет) при использовании быстрого контроллера и быстрого ПК.

Берем ПКЛ Beckhoff CX2020 (подходит для ЧПУ систем) и ноутбук на базе Core i7-3630QM (позиционировался как игровой). Этого достаточно, чтобы "разогнаться" до 50 микросекунд, а меньше и не бывает.

Простейшая ПЛК-программа с заданным временем цикла, содержащая примитивный счетчик +1 каждый цикл. Будем раз-за-разом считывать его значение и замерять разницу между предыдущим и текущим значениями. При разнице в 1, мы получим время считывания равное одному ПЛК-циклу (его значение известно); при разнице в 2, мы получим время считывание равное двум ПЛК-циклам; при 10, соответственно 10 циклов на считывание одной переменной и т. д. Длина переменной счетчика типа UDINT = 4 байта. Чуть позже попробуем считывать строку длиной 100 байт и массив подлиннее.



Быстродействие


Синхронное чтение с помощью ReadAny() одной переменной длинной UDINT занимает 5..10мс. При асинхронном чтении с помощью уведомлений [event driven] и функции AddDeviceNotification(), можно разогнаться до 1мс: меньше не получится - это ограничение функционала библиотеки. Следует учесть, что такое поведение справедливо для обмена данными в UI-потоке: там же, где происходит обработка интерфейса пользователя (интерфейса как графического, так и консольного).

Синхронный обмен можно разогнать, если запустить поллинг (постоянный опрос) в параллельном потоке и считывать из него данные по мере необходимости. В таком случае можно "разогнаться" до 50мкс и даже намного быстрее, что конечно же бессмысленно т. к. ПЛК не сможет выдать данные быстрее своего цикла.


Объем


Оценка скорострельности бессмысленна без объема перекачиваемых данных. В тестах выше использовалась единственная переменная типа UDINT размером 4 байта. Что произойдет, если взять данных да побольше?

Количество последовательных синхронных операций ведут себя линейно - чем больше запросов, тем больше времени понадобится: два запроса удвоят время, три - утроят и т. д. Что если в одном запросе передать больше данных? Выше мы хотели посмотреть на строки и массивы, но т. к. это одно и то же (строки - это массивы символов с нулем в конце), то тестировать будем массивы разной длины.
Уточнение для педантичных разработчиков: я проверил работу со строками разной длины - оно работает аналогично линейным одномерным массивам байт. Никаких подводных камней.
И тут внезапно ждет печаль и разочарование - получить какие-то точные данные не получается: время запросов начинает сильно плавать как в синхронных, так и в асинхронных запросах. Вполне нормальное явление, когда детерминированное встречается с недетерминированным, но хотелось бы рекомендаций:
  1. Асинхронное однопоточное чтение быстрее синхронного однопоточного.
  2. Многопоточное синхронное чтение быстрее однопоточного асинхронного. "Сверхбыстродействие" можно получить созданием отдельного потока для поллинга синхронными функциями.
  3. Массив можно прочитать/записать за один вызов функции и за такое же время, как для одной простой переменной.
  4. Как следствие, для передачи большого количества переменных, их желательно упаковать в массив. Упаковать - не значит сжать, просто разместить.
  5. Начиная с размера массива в 16 килобайт, время запроса увеличивается нелинейно - становится чуть длиннее. Это связано с пакетной отправкой запросов и прочей сетевой кухней.
  6. После 16 килобайт, чем длиннее массив, тем больше времени понадобится на чтение/запись. До 16 килобайт объем данных на время обмена не влияет.
  7. 16 килобайт получено эмпирически для CX2020 и размера сетевого пакета "по умолчанию".

Представленная методика конечно же кривая, косая и неточная, но позволяет хоть как-то оценить и представить быстродействие обмена данными через ADS.API. К тому же, позволяет выбрать тип обмена: синхнронный, многопоточный, событийный асинхронный и т. п.

April 21, 2015

Преимущество другой стороны ADS

Почему хотят использовать сторонние разработки? У меня есть две версии о трех причинах: первая - это Linux, или лучше сказать - "не Windows"; вторая - интеграторов и пользователей отталкивает необходимость установки TwinCAT, допустим даже в минимальном варианте.

Если для первой версии все понятно, на второй остановимся подробнее.

Для начала, пользователя можно уговорить, а установку пакетов и прочих "окружений" можно автоматизировать (WiX, Inno Setup, InstallShield, добавьте свой). После этого мы получим установленный в системе ADS-роутер, в который нужно добавить запись роутинга, без которой связи с контроллером не будет совсем. Это третья причина почему разработчики идут за сторонними разработками.
Но(!), не стоит забывать, что для сторонних библиотек не нужен роутер на стороне ПК, но на стороне контроллера он по прежнему нужен. Настроить же роутер на ПК можно из самой программы или же через ключи реестра (тем же установщиком "окружения", который только что установил TwinCAT). 
ADS-роутер занимается не только преобразованием адресов, но и ставит пакеты в единую очередь, которая позволяет одновременно работать с конфигурацией, отлаживать ПЛК-задачи и обмениваться данными через ADS. В случае с независимыми разработками совмещать не получится.

Правда, в случае с роутером сложно разогнаться быстрее одной миллисекунды. Зато вы можете делать это детерминировано: роутер обеспечивает жесткий тайминг, но не быстрее 1мс. В случае же синхронных запросов время запроса растянется до 5-10мс или нужно городить многопоточное приложение, что начиная с .NET 4.5 делать несложно, но вдруг у вас C++, Java или живет питон.

Для самодельной реализации протокола таких ограничений нет, можете городить что угодно, правда, забыв про отладку программ на стороне контроллера.

ADS.API
+ Отладка.
+ Событийная модель чтения данных (event driven), детерминированность обмена данными.
+ Стабильность и быстрая разработка проекта.
+ Поддержка большинства языков программирования.
+ Поддержка со стороны фирмы производителя.
- Кособокая архитектура, как наследие COM-интерфейсов и C++.
- Ограничение в 1мс для детерминированных запросов.
- Установка на ПК TwinCAT и настройка роутера.

Независимые разработки
+ На ПК не нужен TwinCAT и не нужно настраивать роутинг.
+ По сути, нет ограничения на время обмена данными.
+ Как правило, удобная и красивая архитектура.
+ Открытый исходный код.
- Недетерминированность.
- Каждая библиотека поддерживает какой-то один язык программирования.
- Зависит от независимого разработчика.
- Нет возможности отладки конфигурации и ПЛК-задач.

April 17, 2015

Удаленная перезагрузка ПЛК

При подключении через удаленный рабочий стол (RDP, CERHost) контроллеры с Windows Compact|CE легко перезагрузить через пункт меню Start. С ПЛК на базе Windows Emb XP, 7 или проще говоря, настольных версиях Windows, нужно немного побыть системным администратором и воспользоваться командной строкой:
shutdown /r /t 1
Картинка, для тех, кто еще ни разу не был системным администратором:



Три совершенно одинаковых способа перезагрузить ПЛК:
  1. Start → Run... → набираем команду → OK.
  2. Через консоль командной строки.
  3. Облегчить себе задачу на будущее: создать текстовый документ на рабочем столе → вписать команду → сохранить → переименовать в reboot.cmd → кликаем и перезагружаемся.

Для способа №3 есть нюанс: если запущен FBWF или EWF, то фильтр необходимо отключить → перезагрузить ПЛК → создать cmd-файл → включить фильтр заново → перезагрузить ПЛК.
В Windows Compact|CE, в каталоге \Hard Disk\System\ лежит волшебная утилита CxSuspend.exe. Она перезагружает ПЛК.

April 15, 2015

Диалог о CNC

ЧПУ (CNC) система Beckhoff состоит из нескольких уровней (разделение условное, для удобства объяснения):
  1. CNC-ядро – драйвер операционной системы.
  2. HLI-интерфейс (High Level Interface).
  3. ПЛК-программа уровня runtime TwinCAT (IEC 61131-3). ПЛК –Программируемый Логический Контроллер.
  4. HMI-программа уровня пользователя (C#.NET), которую, можно называть терминалом оператора. HMI – Human Machine Interface.
(1) Код CNC-ядра закрыт от модификации пользователем, но может конфигурироваться с помощью TwinCAT System Manager.

(2) Существует HLI-интерфейс для обмена информацией с runtime-уровнем (уровнем ПЛК-программ). Он построен на основе разделяемой области оперативной памяти. Подробнее можно прочитать в «Beckhoff Information System», раздел «TwinCAT CNC HLI Interface».

(3) ПЛК-программа реального времени, уровня runtime TwinCAT. Программа подставляется вместе с CNC-системой в виде исходного кода на языке ST (IEC 61131-3). Она использует HLI-интерфейс и предоставляет разработчику возможность вносить свои изменения в алгоритм работы ЧПУ-системы; реализует часто используемые функции; поддерживает связь HMI←→HLI←→CNC-ядро. Эта же ПЛК-программа осуществляет связь и обмен данными внешнего мира с контроллером ЧПУ.

(4) Программа разработанная на C#.NET (с применением WinForms или WPF), предоставляющая интерфейс оператора. Исходный код программы закрыт, но она позволяет разработчику изменять свой внешний вид с помощью настроек самой программы. Поддерживается многоязычие: английский, русский, немецкий, китайский, любой другой необходимый язык. Кодировка Unicode позволяет использовать практически любой естественный язык. Можно изменять расположение экранных кнопок, изображений, шрифтов и пр. Изначально, вместе с программой, поставляются несколько надстроек позволяющих обмениваться данными с ПЛК-программой (с третьим уровнем). Надстройки конфигурируются там же.

Если необходимо, разработчик может сам разработать надстройку, которая представляет собой сборку (assembly) на любом из языков .NET (C#.NET, VB.NET, ...). Все формы WinForms из надстройки могут впоследствии использоваться в терминале оператора.

Каждая надстройка должна поддерживать паттерн внедрения зависимости (Dependency Injection  Pattern). Надстройка может взаимодействовать с HMI-терминалом, через предоставляемые паттерном интерфейсы: передавать/получать данные от пользователя, видоизменять внешний вид терминала и прочее. В свою очередь HMI-терминал предоставляет API ADS-сервера, с помощью которого надстройка получает доступ ко всем переменным ПЛК-программы уровня runtime TwinCAT (в моем рассказе – это уровень номер три).

API ADS-сервера, это некая прослойка между миром синхронного реального времени и асинхронным прикладным уровнем. Представляет собой набор библиотек для различных языков программирования. Она бесплатна, без  исходного кода, отлично задокументирована в справочной системе, с готовыми примерами использования, поставляется вместе с TwinCAT. Поддерживаются: C/C++, Delphi, C++ Builder, .NET(C#, VB.NET, …), OCX, Java, WebServices, WCF, возможно что-то еще. Используется не только в ЧПУ, но и в проектах произвольного назначения.

ADS.API позволяет получить доступ из прикладных программ пользователя к логическим переменным ПЛК-программы реального времени, а также к адресному пространству контроллера, шине и пр.

Сам по себе ADS – открытый протокол передачи данных, описанный в справочной системе. Существует несколько сторонних реализаций библиотек для доступа по ADS-протоколу.


Имеется ли возможность не только переконфигурировать терминал, но и осуществлять взаимодействие с ядром системы?
  • Конфигурирование внешнего вида терминала.
  • Добавление надстроек терминала для изменения его функционала.
  • Конфигурирование ядра через настройки.
  • Взаимодействие с ядром через HLI-интерфейс и ПЛК-программу реального времени.


Каким образом производится интеграция разработанной надстройки для терминала, с помощью специального ПО?

Разработанная надстройка – это сборка (assembly) .NET, которая выглядит как файл (обычно с расширением .dll). Файл копируется в каталог программы-терминала. В настройках терминала оператор регистрирует имя нового файла, местоположение и какие его «формы» будут использоваться. Для создания надстройки, разработчик может использовать любое ПО, предназначенное для разработки .NET приложений.


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

Да, можно разработать свое собственное приложение в качестве другого терминала.


Правильно ли я понял, что через программу TwinCAT System Manager производится стандартное конфигурирование ядра, а именно: каналов, осей, входов/выходов системы? Имеется ли возможность именно интеграции в ядро какого-либо решения, разработанного на определенном языке программирования, в соответствии с определенными требованиями?

Ядро закрыто от модификации. Могут модифицироваться ПЛК-программа и программа-терминал. Можно разработать стороннее решение, которое будет интегрировано в штатный терминал системы.


А имеются ли возможности доступа интегрированным в терминал проектам не только к ПЛК программе, но и к основным функциям работы ядра: считывание информации о текущей позиции режущего инструмента, информации об управляющей программе? И есть ли у них возможности влиять на технологический процесс: осуществлять запуск/стоп программы, корректировать подачу, скорость, и т. п.? Если да, то это производится также через API функции шины ADS?

ПЛК-программа является неотъемлемой частью ЧПУ-системы. Не имеет смысла рассматривать ЧПУ-систему без этого слоя, так как это уже будет не ЧПУ-система фирмы Beckhoff, а что-то другое.

Терминал общается с ПЛК-программой через ADS-сервер. ADS-сервер предоставляет доступ к внутреннему адресному и логическому пространству контроллера (в том числе и к данным/переменным ПЛК-программы). ПЛК-программа общается с ядром через разделяемую область памяти. Если хочется выкинуть «лишний» слой, то они, как ни странно, все на своих местах:
  • Ядро (CNC Server) – обеспечивает необходимый для ЧПУ функционал.
  • ПЛК-программа (PLC Server + IO Server) – обеспечивает управляющий программный слой в подсистеме реального времени, а также необходимые абстракции и функции для связи с внешним миром. На этом же уровне – обработка данных шины контроллера.
  • Терминал (HMI) – человеко-машинный интерфейс.
Что касается функционала  и влияния на технологический процесс: ПЛК-программа может производить все перечисленные действия.


Как производится передача данных между терминалом и ядром системы TX1270?

Через разделяемую область оперативной памяти. В основном, для этого задействован DMA-контроллер, который разгружает центральный процессор ПЛК, избавляя его от рутины переброса больших объемов данных.


В своих системах ЧПУ Beckhoff заявляет открытую модульную архитектуру? Является ли это важным фактором для системы в настоящее время?

Да, так как большинство решений на рынке разработаны под конкретные задачи. Открытая модульная архитектура позволяет интеграторам как разрабатывать свои собственные решение «с нуля», так и вносить изменения в готовые решения на всех уровнях.

April 14, 2015

Зачем нужен NC PTP и что он себе позволяет

Как и любой другой дополнительный слой абстракции, NC PTP привносит какие-то свои нюансы, заставляет разработчика проникаться новым принципом взаимодействия, нужно изучать новые аспекты, настройки, и прочие тонкости. К тому же, все это должно как-то взаимодействовать с нижележащими слоями... Так зачем это нужно?

Электродвигатели бывают разные: асинхронные, синхронные, линейные, шаговые, ... Существуют сервоусилители как полноценные, так и компактные (на дин-рейку), и как модули для управления шаговыми двигателями, и даже просто сборная солянка из обратной связи и "какого-то-там" исполнительного механизма. Все это управляется "словом управления" и контролируется "словом состояния", то есть, по сути, всегда есть какая-то пара регистров-ячеек которая управляет состоянием и которая отображает состояние. Это минимум.

Плюсы NC PTP и что он себе позволяет:
  • Одинаково контролировать и управлять всем многообразием, перечисленным выше. Одинаково, т. е. разработчику не нужно заморачиваться нюансами конкретного железа. Так было задумано.
  • Дает совместимость с "PLCopen". При переходе с других систем, почти ничего изучать не нужно.
  • Управление не в абстрактных попугаях или бананах, а в конкретных технологических единицах измерения: секунды, миллиметры, градусы, и пр.
  • Независимо от режима работы железа, можно задавать как скорость движения, так и позицию в которую привод должен вывести ось, т. е. позволяет одновременно работать как по положению, так и по заданной скорости. При работе напрямую с железом, так не получится: или так, или так, или строй свою собственную систему цифрового управления.
  • Новый уровень абстракции позволяет наращивать систему до сложных витиеватых вариантов движения: летающие пилы, кулачковые механизмы, экструдеры, и пр.
  • Позволяет управлять формой и параметрами рамп разгона/торможения. Это важно для "тяжелых" исполнительных механизмов.
  • Сохраняется полный доступ к низкоуровневым параметрам железа. Полезно для тонкой настройки.

Темная сторона:
  • Необходимо городить еще один уровень контроля и сброса ошибок.
  • Четко понимать "где и что" настраивается и когда работает.
  • "Тонкие моменты" все-равно требуют прямой работы с железом.
  • Контурный режим есть, но требует глубокого понимания.
  • Дополнительная нагрузка на процессор контроллера.
Резюме: NC PTP - вещь нужная, но в случае необходимости можно поработать и напрямую.