January 24, 2017

Питание энкодерной оси

Нужно ли активировать питание энкодерной оси (Encoder Axis) с помощью функционального блока MC_Power?


Нет, не нужно. Достаточно просто регулярно читать статус переменной, связанной с осью движения. Следующего достаточно:

PROGRAM MAIN
VAR
    EncoderAxis : AXIS_REF;
END_VAR

(* Обновляем информацию об оси движения *)
EncoderAxis.ReadStatus;

(* Работаем с текущей позицией *)
IF EncoderAxis.NcToPlc.ActPos > 0 THEN
[...]
Стоит учитывать, что без вызова метода ReadStatus, автоматически обновляются только статусные поля структуры NcToPlc (поля, отвечающие за состояние оси). Поля, содержащие позицию, скорость и другое, обновляться без вызова ReadStatus не будут. Это также относится и к обычным (Continuous Axis) приводным осям.
Делаем предварительный вывод ― энкодерная ось отличается от обычной приводной (Continuous Axis) только тем, что преобразует параметры движения в цифру, но не осуществляет управление. Следовательно, силовое питание энкодерной оси не требуется.

― Хорошо, а что будет если все-таки задействовать MC_Power? Сможет ли он запретить вращение в обратную сторону или что-нибудь подобное?
― Нет, не сможет. Энкодерная ось всегда находится в неподвижном состоянии. Поля State.HasBeenStopped и .StandStill всегда равны TRUEState.MotionState также всегда равно MC_AXISSTATE_STANDSTILL. Теперь мы знаем, что MC_Power активирует и контролирует только управление движением (то есть выход), но никак не влияет на входные данные.

Что еще полезного в структуре State?

Поля .Moving / .NotMoving ― показывают, движется ли ось. Причем, ожидаемо, каламбур: .NotMoving = NOT .Moving. Направление движения помогают определить поля .NegativeDirection и .PositiveDirection.

Не ждите полезной информации от полей Error. Лучше следите за Status.IoDataInvalid. Это поле показывает валидность данных. Поле становится равным TRUE, когда данные неверны, что можно интерпретировать как ошибку энкодерной оси.

January 13, 2017

System Manager и четыре рантайма

При попытке создать несколько рантаймов и добавить несколько ПЛК-проектов, System Manager начинает капризничать, брыкаться, а в конце выдает ошибку: Runtime system is used by another project!



... и это не баг и не фича — это нюанс, который придется обойти.

Проект строится с помощью двух системных программ: System Manager — конфигуратор ПЛК и PLC Control в котором непосредственно разрабатывается программа контроллера. В какой-то момент разработки необходимо пробросить между ними мостик и познакомить их, передавать настройки из одной в другую и обратно. Для этого служат файлы с расширением .tpy, которые делает PLC Control при сборке (Project → Build) или пересборке (Project → Rebuild all) проекта.
Кроме файлов TPY, также существуют файлы TPA. Их создает System Manager, когда вы добавляете в конфигурацию новый проект или пересканируете уже существующие приекты (Rescan Project...). В эти TPA-файлы System Manager сохраняет конфигурацию переменных ввода/вывода (%I*, %Q*), заменяя звездочки (*) на реальные адреса.

При последующей пересборке проекта, PLC Control увидит файл TPA, созданный ранее System Manager'ом, и добавит в ПЛК-проект конфигурацию переменных, которую впоследствии можно увидеть в Resources → Global Variables → TwinCAT_Configuration.
В файле TPY находится полная информация о проекте, в том числе информация о рантайме, в котором планируется исполнять ПЛК-программу. К сожалению, невозможно выбрать нужный рантайм вручную, если вы разрабатываете проект без контроллера на столе и рядом с вами. По умолчанию система автоматически подставляет в проект первый рантайм, а затем сама же на это ругается, когда вы пытаетесь добавить второй, третий или четвертый проект в System Manager: ведь первый рантайм уже занят и нужно выбрать другой?

Чтобы покинуть тупиковую ситуацию, придется вручную отредактировать файл TPY, а конкретнее поле <Port> настроек роутинга <RoutingInfo> проекта <PlcProjectInfo>. Откройте в любом текстовом редакторе файл с расширением .tpy:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--This file is created by the TCatPlcCtrl automatically. Manually changes will be overwritten!-->
<PlcProjectInfo xmlns:p="http://www.beckhoff.com/2002/01/TcPlcProjectDesc">
    <ProjectInfo>
[...]
    </ProjectInfo>
    <RoutingInfo>
        <AdsInfo>
            <NetId>0.0.0.0.0.0</NetId>
            <Port>801</Port>
            <TargetName>
                <![CDATA[Target: Local (192.168.56.1.1.1), Run Time: 1]]>
            </TargetName>
        </AdsInfo>
    </RoutingInfo>

Номера портов жестко фиксированы: 1 — 801; 2 — 811; 3 — 821; 4 — 831. Достаточно заменить номер порта на соответствующий необходимому рантайму, а все остальные упоминания о рантайме можно оставить без изменений: на них система не обращает никакого внимание. Сохраните файл и без проблем добавьте его в конфигурацию System Manager'а.

November 30, 2016

TcHVAC: Структура библиотеки и проекта

Функционал управления отоплением, вентиляцией и кондиционированием (ОВК, ОВиК, HVAC: Heating, Ventilation, & Air Conditioning) в TwinCAT оформлены в виде библиотеки TcHVAC. Библиотека стоит денег и обозначена артикулом TS8000. В справочной системе можно найти в разделе: TS8000 | TwinCAT PLC Lib: HVAC.

Структура справки и структура каталогов в библиотеке различается, поэтому будем отталкиваться от структуры библиотеки, так как она ближе к практике. Следует сразу учесть, что библиотека строилась с учетом специфики разработки в виде функциональных блоков (FBD, CFC) и на ST временами будет выглядеть уродливо: за универсальность приходится платить.

Как правило, простые системы HVAC строятся исходя из релейной логики "тумблеры и лампы": нажали кнопку, собралась цепочка, загорелась лампа (включился мотор, открылся вентиль и т. п.). Для полного описания такой системы составляют таблицу входов/выходов, оптимизируют ее (например, вручную с помощью карт Карно) и только затем переносят в виде LD-диаграмм или блоков FBD|CFC. На практике так никто не делает, поэтому библиотека построена так, что следуя ее логике, цепочка функциональных блоков сложится сама, библиотека просто настроена на это: ставите один блок — за ним неминуемо тянутся другие.

Управление объектами строится на базе одного или каскада ПИД-регуляторов. Причем есть как классические (универсальные) регуляторы, так и специализированные, заточенные под управление конкретными объектами ОВиК, что позволяет объединять управляемые объекты в цепочки типа заслонка-рекуператор/подмешивание-подогреватель-увлажнитель-вентилятор-итп (смотри картинку выше).


Каталоги библиотеки

  • Actuators — насосы, моторы, одно-, двух-, трех-скоростные, резервирование и авторотация основной-резервный по времени наработки. Под мотором можно понимать целый исполнительный механизм, например, вентилятор.
  • Analog modules — преобразование аналоговых данных в обе стороны. Исполнительные механизмы с аналоговым управлением и датчики контролируемых параметров: температура PT100/1000, давление, управляющие сигналы 0-10В, 4-20мА или сигналы обратной связи и т. п. Параметры можно масштабировать в обе стороны.
  • BackupVar NOVRAM — автосохранение и автовосстановление переменных и настраиваемых параметров функциональных блоков библиотеки в NOVRAM памяти контроллера.
  • BackupVat Persistent — аналогично предыдущему пункту, но сохранение производится на флешку ПЛК.
  • Controller — различные регуляторы: ПИД, двухточечные, цепочки регуляторов, регуляторы заточенные под конкретный исполнительный механизм.
  • Room functions — специализированные функции для управления параметрами в жилых помещениях: климат-контроль, освещение, засветка солнцем.
  • Setpoint modules — формируют кривые и рампы задания, основываясь на времени суток, летнем-зимнем сезоне и т. п.
  • Special functions — вспомогательные функции, помогающие преобразовывать типы данных, контролировать фронты входов/выходов или просто универсальные функции-обертки, позволяющие строить универсальные алгоритмы, подходящие для ПЛК различных типов. Самый простой пример — функция Blinker для мигания лампочкой с интервалом в одну секунду.
  • System — общесистемные функции: чтение/установка часов операционной системы, создание копий параметров функциональных блоков, получать сведения о циклах ПЛК-задачи и немного других системных функций.
  • Time schedule — планировщик действий по расписанию на один день, неделю, месяц, по праздникам и будням и т. д.


Структура проекта


Входная точка управления вентиляцией (и всем остальным) расположена в недрах функционального блока FB_HVACStartAirConditioning. Основная роль этого ФБ — быть диспетчером или дирижером всего оркестра устройств. Именно к нему прикрепляются все остальные функциональные блоки, именно он дает разрешение в виде сигнала Enable на блоки управления заслонками, вентиляторами, насосами и т. п.

Параллельно с блоком StartAirConditioning, каждый цикл вызывается ряд блоков, отвечающих за системные функции. Типичный набор этих функций выглядит так:
  • Считывание уличной температуры с компенсацией, FB_HVACOutsideTempDamped.
  • Мигалка, формирователь однополярного меандра, FB_HVACBlink.
  • Сохранение энергонезависимых данных, FB_HVACPersistentDataHandling.
  • Чтение системного времени, FB_HVACGetSystemTime.
  • Чтение параметров ПЛК-задачи, FB_HVACSystemTaskInfo.
  • Дополнительно: трансляция данных наружу через один или несколько протоколов передачи данных (например, Modbus).

Не все из них требуют вызова каждый цикл, но некоторые особо чувствительны к этому. Например, FB_HVACSystemTaskInfo. Казалось бы, система TwinCAT — это система жесткого реального времени; достаточно прочитать параметры задачи (Task) один единственный раз и больше они не изменятся. Проблема в том, что время цикла фиксировано, но ПЛК-задача может выполняться быстрее отведенного для нее времени цикла. В то же время функции для работы с ПИД-регуляторами требуют точного значения времени прошедшего с момента последнего вызова ФБ. Специально для этого в ФБ FB_HVACSystemTaskInfo есть поле tCycleTime, содержащее значение количества времени затраченного на выполнение ПЛК-задачи в предыдущем цикле — как долго выполнялся предыдущий цикл.

На вход функционального блока FB_HVACStartAirConditioning подаются запросы от специализированных подпрограмм отвечающих за ночное охлаждение (с рекуператором или подмешиванием вытяжного воздуха), вентиляцию в ночное летнее время, защиты от замораживания или перегрева, планировщика задач. Параллельно с запросами приходят сигналы и данные от общих для всех систем датчиков и сенсоров: уличная температура, температуры приточного и вытяжного воздуха, температура воды подогревателя, сигналы с кнопок шкафа управления (авария, сброс ошибки и т. п.).

В ответ ФБ StartAirConditioning выдает сигналы на специализированные ФБ, которые управляют исполнительными механизмами: воздушные заслонки, вентили подогревателя, увлажнители, вентиляторы и другие устройства.

Несложно самостоятельно разработать логику управления, если требуется другая структура блоков или функций. Все "большие" блоки построены на основе других, небольших и более специализированных функций библиотеки.

November 24, 2016

Взгляд со стороны клиента ModbusTCP

Копнем чуть глубже — как выглядит сервер ModbusTCP с точки зрения клиента — по каким адресам модбаса нужно стучаться и что мы там найдем. Для свежести в памяти — обзор катушек и холдинг регистров и настройка сервера Modbus TCP.

После установки сервера ModbusTCP у нас уже есть настроенный конфигурационный файл, которым заранее удобно пользоваться. Все адреса десятеричные и все это можно позднее переделать под себя в том же конфигурационном файле. Пока же воспользуемся параметрами заданными по умолчанию в конфигурационном файле. Сетевой порт TCP = 502, полезная справочная документация = Mapping between Modbus and ADS.


Работа со стандартными массивами


Немецкие инженеры о нас позаботились — четыре заранее сформированные массива открывают доступ к данным Modbus. Причем открывают без какой-либо головоломки с расчетом индексов, упаковкой битов в слова и других отвлекающих преобразований.

После установки на ПЛК сервера ModbusTCP, последний автоматически ищет четыре глобальные переменные с заранее заданными именами.
Эти имена (или пара индекс-смещения) задаются в конфигурационном файле в разделах <VarName> или парой <IndexGroup> // <IndexOffset>.
Еще раз: в самой ПЛК-программе, вам ничего добавлять не нужно: сервер сам попытается найти эти имена среди глобальных переменных, и если найдет — автоматически начнет трансляцию данных по шине Modbus. Включать в проект дополнительные библиотеки не требуется, просто добавляем в глобальные переменные четыре массива:

.mb_Input_Coils [0..255] OF BOOL
.mb_Output_Coils  [0..255] OF BOOL
.mb_Input_Registers [0..255] OF WORD
.mb_Output_Registers  [0..255] OF WORD

С точки зрения ModbusTCP массивы получают адреса начиная с 3276810 (или 0x800016). Расчет полного адреса ведется с учетом индекса в массиве:

.mb_Input_Coils [0..255] OF BOOL
.mb_Output_Coils  [0..255] OF BOOL

Адрес Modbus = 32768 + индекс в массиве (0..255)

Одна катушка или дискретный порт ввода-вывода соответствует одной ячейке массива типа BOOL. Это очень удобно, так как не требуется упаковка битов в "слово". Аналогично с регистрами:

.mb_Input_Registers [0..255] OF WORD
.mb_Output_Registers  [0..255] OF WORD

Адрес Modbus = 32768 + индекс в массиве (0..255)

В каждом массиве всего 256 элементов, поэтому адресация этих массивов заканчивается для Modbus на числе 33023. Полный диапазон 32768..33023.

Для клиента .mb_Input-Coils/Registers массивы доступны только для чтения (функции модбас #2, #4). .mb_Output-Coils/Registers доступны и для чтения (функции #1 #3), и для записи (функции #5, #6).


Переменные ввода/вывода


Дополнительно к массивам, автоматически транслируется область переменных ввода-вывода, то есть также одновременно транслируются те переменные, которые связаны с физическими входами/выходами или, иначе говоря, переменные, которые обозначены как AT %I* и AT %Q*. Простые правила помогут запомнить что-с-чем ассоциируется:
  • Катушки (coils) можно намагничивать и размагничивать — поэтому они могут менять свое значение и поэтому они связаны с AT %Q*. Аналогичное правило для регистров хранения (holding registers): в них тоже можно сохранять и читать.
  • Inputs — это входа и они только для ввода данных, поэтому записывать нельзя — AT %I*.

Чтение с помощью функций модбаса:
  • Катушки %QX — функция #1, Read Coils.
  • Регистры хранения %QB, %QW,... — #3, Read Holding Registers.
  • Дискретные входа %IX — функция #2, Read Discrete Inputs.
  • Дискретные регистры ввода %IB%IW,... — #4, Read Input Registers.

Запись доступна только для катушек и регистров хранения, по одному за раз, но вообще можно и несколько за раз (функции 15 и 16):
  • Катушки %QX — функция #5, Write/Force Single Coil.
  • Регистры хранения %QB, %QW,... — #6, Write/Preset Single Register.

В итоге выстраивается стройная система — с точки зрения Modbus, мы номером функции выбираем тип переменных (чтение/запись, катушки/регистры), а затем адресом уточняем какую именно переменную мы хотим.

Адрес Modbus для переменных ввода данных (AT %I) лежит в диапазоне 0..32767. Для переменных ввода/вывода (AT %Q, катушки и регистры хранения) верхняя граница занижена 0..12287, иначе они будут пересекаться с меркерной памятью (читай ниже).

Расчет адресов идет по единому принципу и для тех, и для других. Так как дискретные или битовые входа/выхода упаковываются в байты — значения адресов Modbus придется немного повычислять, :

%IX#.@ (где # — номер байта, @ — номер бита в байте)
%QX#.@

Адрес Modbus = # / 2 * 16 + @ = # * 8 + @

Пример:

bSomeVar AT %IX6.2 : BOOL;

Адрес Modbus = 6 * 8 + 2 = 50


Для байтовых входов/выходов важно учитывать, что чтение с шины Modbus идет 16-разрядными словами. Чтобы прочитать байт, нужно прочитать слово целиком, а затем выделить из слова байт. Важно знать порядок следования байтов в слове — он не определен!

%IB# (где # — номер байта)
%QB#

Адрес Modbus = # / 2

Modbus 0 = %IB1 : %IB0
Modbus 1 = %IB3 : %IB2
Modbus 2 = %IB5 : %IB4
%IB123 → 123 / 2 = 61.5 ≈ 61 → Modbus 61 = %IB123 : %IB122
...

"Слова" состоят из двух байт, поэтому идут с шагом два. Например, для %IW и %QW:

iSomeVar0 AT %QW0 : WORD;
iSomeVar1 AT %QW2 : WORD;
iSomeVar2 AT %QW4 : WORD;
[...]
iSomeVarN AT %QW# : WORD;

Адрес Modbus = # / 2


Меркерная память


Для шины Modbus эта область памяти (AT %M*) лежит в диапазоне адресов 12288..24575. Адреса строятся аналогично переменным ввода/вывода из предыдущего пункта.
Обратите внимание, что адреса Modbus для меркерной памяти пересекаются с адресами переменных ввода/вывода %Q и в то же время не пересекаются с адресами переменных ввода %I. Это происходит по причине доступности переменных %M как на чтение, так и на запись, аналогично переменным ввода/вывода %Q. Именно поэтому M- и Q-области памяти  выглядят одинаково с точки зрения Modbus, а значит и доступны с помощью одних и тех же функций Modbus.


Порядок слов


Modbus как таковой ничего о типах данных не знает и перегоняет битовые единицы упакованными в "слово", а регистры просто как "слова" (WORD). При этом протокол ничего не знает ни о знаке числа (для него все числа целые), ни о плавающей запятой, ни о порядке байт в слове.

Например, я сейчас включил ПЛК и при использовании типа WORD получил следующую картину:

%MB0 — младший байт
%MB1 — старший байт

%MW0 — 12288 (%MB1 : %MB0)
%MW2 — 12289 (%MB3 : %MB2)
%MW4 — 12290 (%MB5 : %MB4)

...а мой сосед включил сервоусилитель какой-то другой фирмы и получил обратный порядок байт, что смешало бы значения параметров в кашу. Проверяйте!


Загадочные области памяти


На самом деле — нет, но начиная с 24576 идет область данных, где хранятся значения переменных ПЛК-программы. Отсюда можно вытащить значения обычных локальных и глобальных переменных ПЛК-программы. Правда порядок их следования не гарантирован, поэтому использовать не рекомендуется.


Обновлено: 12 ноября 2017 г.

November 3, 2016

Системный диалог даты-времени в Windows CE

Как быстро сделать ввод системной даты/времени при создании визуализации TwinCAT 2 под Windows CE? Нужно воспользоваться системным диалогом из панели управления — открыть  проводник explorer.exe, а дальше оператор сам найдет, исправит, настроит, испортит. Чтобы избежать такого поведения можно открывать только панель даты/времени.

1. Из меню Start запускаем notepadce.
2. Аккуратно вводим одну строчку, внимательно следя за пробелами и другими символами:

35#"ctlpnl.exe" \Windows\cplmain.cpl,13

35# — это количество символов в строке. Между ..ctlpnl.exe" и \Windows\... стоит пробел.

3. Файл сохраняем как datetime.lnk во флэш памяти контроллера (имя файла произвольное, если-что). Сохранить можно где-нибудь в \Hard Disk\datetime.lnk

4. Для элемента, при нажатии на который будет открываться панель настройки даты/времени, выставляем параметр визуализации (кавычки там обязательны):

Input → Execute program: "\Hard Disk\datetime.lnk"

Теперь при нажатии на элемент можно отображать только системную панель настройки даты/времени:



Можно открывать и другие апплеты панели управления:


PC Connection – 35#"ctlpnl.exe" \Windows\cplmain.cpl,0
Dialing – 35#"ctlpnl.exe" \Windows\cplmain.cpl,1
Keyboard – 35#"ctlpnl.exe" \Windows\cplmain.cpl,2
Password – 35#"ctlpnl.exe" \Windows\cplmain.cpl,3
Owner – 35#"ctlpnl.exe" \Windows\cplmain.cpl,4
Power – 35#"ctlpnl.exe" \Windows\cplmain.cpl,5
System – 35#"ctlpnl.exe" \Windows\cplmain.cpl,6
Display – 35#"ctlpnl.exe" \Windows\cplmain.cpl,7
Mouse – 35#"ctlpnl.exe" \Windows\cplmain.cpl,8
Stylus – 35#"ctlpnl.exe" \Windows\cplmain.cpl,9
Volume & Sounds – 35#"ctlpnl.exe" \Windows\cplmain.cpl,10
Input Panel – 35#"ctlpnl.exe" \Windows\cplmain.cpl,11
Remove Programs –  35#"ctlpnl.exe" \Windows\cplmain.cpl,12
Date/Time – 35#"ctlpnl.exe" \Windows\cplmain.cpl,13
Certificates – 35#"ctlpnl.exe" \Windows\cplmain.cpl,14
Accessibility – 35#"ctlpnl.exe" \Windows\cplmain.cpl,15


Для открытия CX Configuration или полностью Beckhoff CX Configuration Tool, нужно запустить другой апплет:

35#"ctlpnl.exe" \Windows\CxConfigCpl.cpl


Для юных исследователей доступен каталог \Windows, который может содержать (и содержит) другие апплеты панели управления в виде файлов с расширением .cpl

October 18, 2016

Я сделаю свой NC с рампами и траекториями

В частотных приводах AX5000 и сервомодулях EL72xx изначально заложена возможность прямого управления сервоусилителями: кидаете задание Velocity command value, формируете слово управления Master control word и постоянно следите за словом состояния Drive status word. По сути вам необходимо самостоятельно обрабатывать все, что есть в AT|MDT ветках сервоусилителя. Просто и дешево, но:
  • Не умеет масштабировать величины. Все значения задаются в инкрементах. Хотя можно реализовать пересчетные функции (как уже сделано в NC).
  • Только базовый набор функций: вкл/откл силового питания, вращение с заданной скоростью, абсолютное позиционирование, контроль тока, ограничение момента.
  • Все управление идет из ПЛК-задачи: если в программе тех. процесса допустить ошибку, то она отразится в том числе и на работе сервоусилителя, так как они все вместе работают внутри одной и той же задачи (в отличии от NC, которая работает как независимая подсистема TwinCAT).
  • Зависимость от времени цикла ПЛК-задачи. NC не зависит от времени цикла задачи, что положительно сказывается на скорости реакции, плавности/точности траекторий и пр. 
  • Нет разгонно-тормозных рамп, но можно реализовать их самостоятельно.
  • Зависимость от режима работы сервоусилителя: нельзя задать скорость вращения в режиме позиционирования и обратная ситуация — нельзя выйти в абсолютную позицию в режиме управления по скорости.
  • Нет ни гарантии, ни тех. поддержки: умер разработчик — умерла система.

Должны быть плюсы:
  • Дешево.
  • Будет работает на всем, что может обеспечить EtherCAT-мастер, в том числе и на контроллерах CX8010 + EK1110.


Что-то подобное уже всплывало в зачем нужен NC PTP и что он себе позволяет.

October 11, 2016

SIL-3

EL6900 и желтые Safety-терминалы соответствуют системному уровню надежности SIL-3. Будет ли разрабатываемая система считаться безопасной или нужны дополнительные процедуры?

В документации по желтым модулям постоянно встречается упоминание SIL-3, а в конце тех. документации есть изображение сертификатов, которые к тому же можно скачать отдельным pdf-документом. В дополнение к ним можно посмотреть на сертификаты таможенного союза (Россия, Белоруссия, Казахстан). Там же есть соответствия требованиям промышленной безопасности, которое говорит, что модули можно использовать в промышленности и они будут соответствовать бюрократическим требованиям.

В общем, не важно когда начинать разрабатывать программную и safety-логики: до согласования или после сертификации. Модули уже соответствуют SIL-3. Это означает, что они готовы и могут обеспечить соответствующие требования МЭК/TUV. Правда соответствие модулей не означает, что вся система будет соответствовать требованиям безопасности только потому, что в ней все модули безопасности соответствуют SIL-3. Да и сам SIL-3 говорит только о степени надежности отдельных модулях, а не о безопасности всей системы в целом.

Еще раз: модули соответствуют требованиям SIL-3. Функционал модулей достаточен для обеспечения соответствующего уровня надежности системы. Что в итоге "вылепит" разработчик — никому не известно.

Как итог, приемку системы в целом, будет осуществлять заказчик по своим нормам и правилам или делегирует в какую-либо сертификационную/проверочную организацию. Лучше с самого начала узнать у заказчика, что он собственно подразумевает, когда просит SIL-3 и работать в соответствии с этим.

Хорошая статья в тему: SIL — это не сложно.

October 4, 2016

Как добавить точку в ломаную линию?

В преддверии новой визуализации на html5 и css3 поковыряем нюансы старой-доброй визуализации под TwinCAT 2.

Начнем с простого — надписью может быть любой элемент, достаточно отключить у него бордюр: Colors → No frame color.

Кнопкой может быть любой элемент, но элемент Button (кнопка) ведет себя как кнопка и не требует дополнительных телодвижений от разработчиков. Правда она не так удобна в плане изменения своего внешнего вида, зато всегда ведет себя как кнопка, а не как ХЗ-что.

Поле Variables → Invisible — это в прямом смысле "невидимость". TRUE → элемент невидим, FALSE → элемент отображается, то есть его видно.

Значение параметров фигуры (цвет, размер и пр.) могут задаваться в нескольких местах одновременно и тогда одни значения начинают перекрывать другие. Можно задать величину параметра как статическое значение (например, цвет в поле Colors). Это значение перекроется значением, заданным в виде переменной  из раздела ColorVariables. Переменную, в свою очередь, может перекрыть программная структура из раздела Programmability. При отладке программы, значения переменных введенные через Watch-n-Recipe перекрывают вообще все.

Можно добавить новую точку в ломаную линию или многоугольник: удерживая клавишу Ctrl, тянем левой кнопкой мыши за уже существующую точку и вытягиваем из нее новую точку. Ctrl + Shift + клик — удаляет уже существующую точку.

Последнюю точку в фигуре нужно ставить правой кнопкой мыши.

Motion absolute:
  • Углы задаются в градусах.
  • Масштабирование, оно же Scale: 1000 = 100% размера фигуры. Масштабирование касается всей фигуры в целом, в том числе и расстояния до центра фигуры.
  • Y-offset, X-offset — сдвинуть всю фигуру влево-вправо / вверх-вниз.
  • Angle — поворот относительно центра (кружок с перекрестием), но(!): Shape (прямоугольники и эллипсы) вращаются так, что верх фигуры остается всегда вверху. Polygon (многоугольники, контуры, кривые) вращаются так, что все точки совершают вращение относительно центра фигуры. Если вам нужен квадрат вращающийся относительно своего центра — нарисуйте его из ломаной поли-линии.

Можно добавить один экран визуализации на другой экран в виде элемента меньшего размера. Размер такого элемента определяется типом масштабирование пропорций:
  • Anisotropic — произвольные пропорции и размер.
  • Isotropic — фиксированные пропорции, но произвольный размер.
  • Fixed — фиксированные пропорции и размер.
  • Fixed and scrollable — как и Fixed, но можно прокручивать (не работает в Windows CE, см. раздел про ограничения).

Пунктирные, штрихпунктирные и прочие тире-тире-точки можно получить, задав ColorVariables → Frame flag отличный от нуля. Тип линии меняется только во время работы визуализации и не меняется во время разработки:
  • 0 сплошная ____
  • 1 пунктир - - - -
  • 2 точки ......
  • 3 тире-точка -.-.-
  • 4 тире-точка-точка -..-..-
  • 8 невидимая, но ее толщина учитывается

Input → Execute Program — это целый отдельный мир программирования. Здесь можно создавать макросы (Macro). Например, при нажатии кнопки Сохранить на экране задания параметров, сменяется текущая визуализация (Input → Zoom to viz.). Можно сделать так, что одновременно со сменой визуализации будет задаваться значение какой-либо переменной (как глобальной, так и локальной в подпрограмме). Таким образом можно отследить, что пользователь уходит с экрана настроек и необходимо сохранить persisitent-переменные, если он нажал ОК, и не сохранять, если он ушел по кнопке Отмена.

Programmability → Object name, если установить галку и ввести имя переменной, то после перекомпиляции проекта появляется новая глобальная переменная-структура типа VisualObjectType. Объявление этой переменной не видно в проекте, но она как суслик все-равно есть и доступна для Intellisense по F2.


Все эти вопросы неплохо рассмотрены в справочной системе, но на английском языке (или немецком) и все равно всплывают раз-за-разом:

September 28, 2016

Вебинар. Новое поколении TwinCAT HMI

Много клиентов, много серверов, много рантаймов и много всего остального. Основной акцент на слово "много". Сводный обзор по возможностям и полезностям визуализаций в TwinCAT 3 провел Дэймон Томпсон (Daymon Thompson). По окончании на вопросы ответил глобальный продукт-манагер Свен Обершмидт (Sven Oberschmidt). По прежнему хочется "мяса" из инженеров.

Все это уже было, но теперь подводятся какие-то итоги и обещают уже в начале следующего года англоязычную версию.

Основные черты продукта:
  • Основан на технологиях пришедших из интернета: html5, css3, javascript.
  • Клиенты из-под браузеров (в том числе и Edge) и клиенты на мобильных системах Android и iOS, ведь там тоже есть браузеры, только мобильные.
  • Система рассчитана на продолжительный срок жизни: придет и останется с нами надолго.
  • Всё такое масштабируемое, модульное и независимое, векторное и веб-ориентированное. Если кратко и без патетики — должно стать удобнее как в разработке, так и в применении.


TwinCAT HMI Creator


Визуальный редактор: не нужно программировать, просто рисуйте и редактируйте готовые шаблоны.
  • Интеграция с Visual Studio.
  • Интеграция с TwinCAT.
  • Редактор с упором на визуальную разработку.
  • Использование систем контроля версий (tfs, svn, git, ...).
  • Менеджер пакетов.
  • Готовые шаблоны проектов.
  • Темы оформления.
  • Графическая библиотека готовых элементов: SVG, сложные и составные элементы.


TwinCAT HMI Framework


  • Готовые контролы (элементы управления интерфейсом):
    • стандартные;
    • графики, чарты, события/логи/журналы (events);
    • пользовательские (самодельные) контролы.
  • Применение сложных типов данных (структуры, дата/время и пр.).
  • Интернационализация:
    • переключение языков;
    • национальные единицы измерения, меры длины, денежные знаки и т. п.
  • Расширябильность засчет html5 и javascritpt.


TwinCAT HMI Server


Веб-сервер написанный Бекхоффом (фирмой, а не человеком). Обещают, что будет работать на всем, что начинается с CX9020. В том числе и на Windows CE.

  • ADS — что позволяет использовать рантайм как от TwinCAT 3, так и от TwinCAT 2.
  • OPC UA — что позволит использовать вообще все что угодно.
  • Цифровой осциллограф Scope. Пока не понятно куда и как он будет встраиваться, но возможно имеется в виду его серверная часть.
  • Безопасность данных (https, tls и прочий эS).
  • Уровни доступа пользователей (роли пользователей, login | logout).
  • Предварительно подготовленные данные для тестирования и отладки (recipe management).
  • Логирование событий.
  • Сбор данных.
  • Сможет расширяться модулями на C++ / C#.


Разработка


  • Сплошная интеграция с Visual Studio.
  • Живое взаимодействие с визуализацией во время разработки. Будет сразу видно, что и как работает.
  • Графический редактор с набором стандартных и не очень элементов.
  • Предварительно настроенные шаблоны, которые можно доработать. Обещают современный внешний вид с анимацией и прочими свистелками.
  • Контролы пользователя расширяются с помощью javascript. Серверная часть расширяется на C++ / C#. Можно подготовить заранее темы в корпоративном стандарте под брендбук, а затем использовать во всех остальных проектах.

Про архитектуру уже было в Новый HMI для TwinCAT 3 (8 декабря 2015). Про сценарии применения было в Визуализации в TwinCAT 3 (24 марта 2016), но если кратко:

  • Наиболее распространенный сценарий "локальный клиент": визуализация и браузер работают на одном контроллере, а графическая панель подключается через DVI.
  • Много клиентов через интернет (например, мобильные телефоны и планшеты) подключаются к локальному клиенту.
  • Много клиентов подключается к одной машине с сервером TwinCAT HMI, который собирает (агрегирует) данные с нескольких ADS-серверов (умных коплеров или младших моделей CX).
  • Много TwinCAT HMI серверов, которые подключены к одной машине, которая отображает сводные данные со всех других серверов (сервер серверов).

При этом сохраняется мультипротокольность: сервер общается с коплерами по любым протоколам, клиенты подключаются к серверу через http(s) и браузеры.


Лицензирование


  • Стоимость не зависит от количеств тегов. 
  • Инструменты разработчика бесплатны, включая обновление, сопровождение и поддержку.
  • Лицензирование касается только сервера. Клиенты работают бесплатно и не лицензируются.

Стоимость лицензии строится исходя из:
  • уровня платформы на которой будет работать TwinCAT HMI Server;
  • количества клиентов и целевых систем (target runtimes).

Пример


TF2000 HMI Server — рассчитан на 1 клиента (браузер) и  одну целевую систему (netId), то есть в базовой версии один клиент — один таргет.

Можно добавить клиентов или таргетов:
- TF20x0 Clients Pack 1/3/10/25 (пакет клиентов — один, три, десять дополнительных клиентов).
- TF20x0 Targets Pack 1/3/10/25 (пакет таргетов).

Можно добавить расширения визуализации HMI Extension (Scope, OPC UA) — это расширения для добавления протоколов или дополнительных функций.

В итоге будет сформирована лицензия TwinCAT 3 HMI License.


Итого


  • Быстрая разработка, где мало разработки и больше рисования.
  • HTML5, javascript.
  • Клиент не зависит от платформы. 
  • Модные веб-технологии.
  • Гибкая архитектура.
  • Модульность.


Вопросы-ответы


  • Разница между TwinCAT PLC HMI и TwinCAT HMI? Первый будет только патчиться, новые фичи будут появляться только в TwinCAT HMI.
  • Какие версии Visual Studio? Пока что 2013-2015. Дальше будет видно, а пока этого достаточно.
  • Локальные переменные будут доступны (транслируются) в контекст браузера. Надо смотреть что там имелось в виду.
  • Когда? В этом году (2016) немецкая версия, в начале следующего года для всех остальных, кто говорит на английском.
  • Веб-сессии (sessions) поддерживаются, информация о веб-клиенте доступна.
  • PLC HMI контролы и модные HMI контролы, да и другие элементы тоже, смешивать и перемещать туда-сюда нельзя. Вполне возможно, хотя и маловероятно, в будущем появится конвертер первого во второй, но не обратно.

September 8, 2016

Пропорционально-интегрально-дифференцирующий

С параметрами ПИД-регулятора можно играться как с кошкой — до бесконечности: пока в колебательный процесс не впадет или не надоест.

Несмотря на тонны матана, прячущиеся за тройкой входных параметров, около 90% регуляторов в мире основано на ПИД (гугл, википедия, нормальное распределение). Именно благодаря простому интерфейсу, скрывающему интегралы-дифуры, использовать ПИД-регулятор невероятно просто, главное правильно отстроить и не умереть от скуки.

TcControllerToolbox.lib — это основная профессиональная библиотека TwinCAT для работы с регуляторами, генераторами и прочими алгоритмами автоматизации. Там много разных штук, но мы посмотрим на ПИД-регуляторы, как самые распространенные и востребованные.


PLC Controller Toolbox


В прайсе эта библиотека обозначена артикулом TF4100. Это для TwinCAT 3. Если вам нужно модернизировать старую систему на TwinCAT 2, ищите TS4100. Библиотека платная, но построена профессионально — с учетом всего того, что просто необходимо учитывать.
Например: все ФБ библиотеки контролируют циклы и тайминги программных циклов. В случае повторного вызова ФБ за один и тот же цикл или если будет пропуск цикла — ФБ адекватно обработает эту ситуацию. Даже если будет пропущен не один цикл или не один раз.

Кроме непосредственно регулирования, блоки ПИД-регулятора умеют дополнительные опции.

FB_CTRL_PI
FB_CTRL_PID
  • Контроль интегрального насыщения, верхний и нижний пределы.
  • Ручная уставка задания в обход автоматической: можно вмешаться в работу регулятора.
  • Ручное отключение интегральной составляющей.
  • Жесткий контроль циклов ПЛК-задачи и таймингов.

FB_CTRL_PID_EXT
  • Зона нечувствительности для входного значения. При нахождении в ней значение выхода регулятора постоянно.
  • Зона нечувствительности для нулевой величины выхода.
  • Окно для отключения интегральной составляющей (она постоянна или равна нулю).
  • Окно для уменьшения масштаба интегральной составляющей.

FB_CTRL_PID_SPLITRANGE
  • Аналогично FB_CTRL_PID, но можно задать разные наборы коэффициентов "p-i-d" для охлаждения (температура ниже нуля) и для нагрева (температура выше нуля).
  • Имеет два различных выхода, но активен только один. В зависимости от величины выхода — больше нуля или меньше нуля, он запускает нагрев или охлаждение, обнуляя значение противоположного выхода. Кусок кода, для разнообразия:
fOut := fY;

IF fOut > 0.0 THEN
    fOutPos := fOut;
    fOutNeg := 0.0;
ELSE
    fOutNeg := fOut;
    fOutPos := 0.0;
END_IF

FB_CTRL_PID_EXT_SPLITRANGE
  • Всё и сразу: FB_CTRL_PID + _EXT + _SPLITRANGE.


Простой ПИД-регулятор


К тому же бесплатный. Можно было бы перевести дословно — "примитивный", но он работает и это — самое главное.

В бесплатной библиотеке TcUtilities.lib, есть встроенный функциональный блок FB_BasicPID, который умеет три параметра и — все. Больше он ничего не умеет (плюс демпфирование диф.-составляющей Td, но это у разработчика случайно получилось).

Главное отличие от профессиональной библиотеки — это:

FB_BasicPID
  • нет контроля интегрального насыщения;
  • нет контроля повторного или пропущенного вызова за цикл. Вызывайте строго один раз за цикл — иначе пожалеете.

С циклом более менее понятно, а вот отсутствие контроля за интегральным насыщением (integral windup, reset windup, integral saturation) может сыграть злую шутку. Мы сейчас попробуем поиграться с этим эффектом, и заодно убедимся, что функция регулятора действительно примитивная.

Да собственно уже играемся — длинная портянка графика справа показывает, как мы сначала нагрели нечто до 27 градусов, а затем пытаемся охладить, но что-то никак не получается...
Зеленый — задание-уставка.
Синий — выход ПИД-регулятора.
Красный — актуальное, текущее значение на выходе исполнительного механизма.
... А все потому, что не хватает возможности исполнительного механизма — он не справляется, а ПИД-регулятор все топит и топит педальку тормоза-охлаждения. И график ползет вниз...

Чтобы хоть как-то исправить ситуацию, мы попробуем ограничить выход регулятора в соответствии с возможностями нашего исполнительного механизма. Предположим, что он может нагреть до 60 и охладить до 18 условных градусов, условного цельсия:

PID(
    SetpointValue := TargetValue,
    ActualValue   := ActualValue,
    Kp := kp,
    Ti := ti,
    Tv := tv,
    Td := td,
    MaxCtrlOutput := Model.LimitHi,
    MinCtrlOutput := Model.LimitLow,
    CtrlOutput    => SetpointValue);

IF SetpointValue < 18 THEN
    SetpointValue := 18;
END_IF

IF SetpointValue > 60 THEN
    SetpointValue := 60;
END_IF

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

Пока же оставим регулятор как есть, и в итоге получим как на картинке ниже — задание изменилось и кажется, что регулятор чего-то ждет... На самом деле интегральная ошибка убежала далеко вверх (накопилась) и в данный момент стремительно падает, уменьшаясь и пытаясь достичь заданного. И это я еще ждал недолго, за сутки она бы убежала на столько далеко...



Попробуем зайти с другой стороны и заморозим накопление ошибки (интегральную часть). Для этого перепишем часть регулятора:

// расчет интегральной части
IF is_Ipart THEN
    IF (maxLimReached AND (e >= 0.0)) OR (minLimReached AND (e <= 0.0)) THEN
        yi := yi1;                    // замораживаем интегральную часть
    ELSE
        yi := yi1 + di * (e + e1);    // интегрируем
    END_IF
ELSE
    yi := 0.0;
END_IF;

[...]

y := yp + yi + yd;    // суммируем П-И-Д части для расчета выхода регулятора

// проверяем выход на ограничения
IF y < MinCtrlOutput THEN
    y := MinCtrlOutput;
    minLimReached := TRUE;
    maxLimReached := FALSE;
ELSIF y > MaxCtrlOutput THEN
    y := MaxCtrlOutput;
    minLimReached := FALSE;
    maxLimReached := TRUE;
ELSE
    minLimReached := maxLimReached := FALSE;
END_IF

CtrlOutput := y;      // формируем выход функционального блока


Проверяем:



Модель процесса


Это абстрактная модель "какого-то" объекта, имитирующая "какой-то" слегка нелинейный процесс. Чтобы придать модели линейность — уберите в расчете переменной delta часть под квадратным корнем (вместе с самим корнем SQRT) и оставьте только Grow и CycleTime.

PROGRAM Model
VAR_INPUT
    Run       : BOOL;
    Setpoint  : LREAL;
    Grow      : LREAL  := 0.1;    // градусы за секунду
    CycleTime : LREAL  := 0.01;   // секунды
    LimitHi   : LREAL  := 70;
    LimitLow  : LREAL  := 18;
END_VAR
VAR_OUTPUT
    Actual : LREAL;
END_VAR
VAR
    delta  : LREAL;
END_VAR

[...]

IF Setpoint > LimitHi THEN
    Setpoint := LimitHi;
END_IF

IF Setpoint < LimitLow THEN
    Setpoint := LimitLow;
END_IF
 
delta := Grow * CycleTime * SQRT(ABS(Actual * Actual - Setpoint * Setpoint));

IF Actual > Setpoint THEN
    Actual := Actual - delta;
ELSE
    Actual := Actual + delta;
END_IF

Если у вас есть модель получше — присылайте почтой, комментариями и пр.


Про диф.-составляющие


Чаще всего используется ПИ-регулятор. Дальше можете не читать.

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

Чтобы включить ПИД-регулятор в FB_BasicPID необходимо выставить оба диф. коэффициента в значения отличные от нуля. Причем основным диф. параметром является Tv (он расположен в числителе). Td — это время демпфирования и находится в знаменателе диф. составляющей. Его значение можно выставить равным единице и тогда останется только основная Tсоставляющая диф. компоненты ПИД-регулятора.