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