Ранее мы уже реализовали выдачу коротких импульсов с использованием скриптов WinCC. Однако иногда импульсы должны всё-таки иметь какую-то минимальную длительность.
Рассмотрим один из способов формирования таких импульсов. Создадим Global action, выполняемый по срабатыванию циклического триггера с заданной периодичностью (я использовал 500 мс), и будем подсчитывать количество его вызовов:
В качестве счетчика здесь используется статическая переменная counter. Подсчет начинается после установки тега в единицу в обработчике события нажатия кнопки:
и останавливается при достижении счетчиком заданного значения (в данном примере 2с = 4 * 0.5с). По окончании счета значение тега устанавливается в 0 и сбрасывается счетчик.
Измерения проводились при использовании как синхронной, так и асинхронной версии функции записи значения тега в контроллер:
Результаты меня несколько удивили, казалось бы, при использовании асинхронной функции длина импульса должна была бы быть короче (предположительно, команда записи выдается с некоторой задержкой после вызова функции). На практике же разницы между результатами работы обеих функций не наблюдается.
После этого функция ShortPulse была переписана с использованием асинхронного SetTagBit:
В результате 100 нажатий на кнопку в WinCC контроллер не потерял ни одного импульса.
В попытках понять есть ли вообще разница между этими функциями был написан следующий скрипт:
В контроллере же измерялось количество сканов между установкой в единицу первого и второго тегов:
Как видно из таблицы, синхронная версия функции в среднем выполняется все же немного дольше. При увеличении длительности скана эта разница скорее всего исчезнет.
WinCC V7.0+SP3
Рассмотрим один из способов формирования таких импульсов. Создадим Global action, выполняемый по срабатыванию циклического триггера с заданной периодичностью (я использовал 500 мс), и будем подсчитывать количество его вызовов:
#include "apdefap.h" int gscAction( void ) { // WINCC:TAGNAME_SECTION_START // syntax: #define TagNameInAction "DMTagName" // next TagID : 1 #define tag1 "tag1" // WINCC:TAGNAME_SECTION_END static long counter = 0; if(GetTagBit(tag1)){ if(++counter > 4){ counter = 0; SetTagBit(tag1, 0); } } return 0; }
В качестве счетчика здесь используется статическая переменная counter. Подсчет начинается после установки тега в единицу в обработчике события нажатия кнопки:
#include "apdefap.h" void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { // WINCC:TAGNAME_SECTION_START // syntax: #define TagNameInAction "DMTagName" // next TagID : 1 #define tag1 "tag1" // WINCC:TAGNAME_SECTION_END SetTagBitWait(tag1, 1); }
и останавливается при достижении счетчиком заданного значения (в данном примере 2с = 4 * 0.5с). По окончании счета значение тега устанавливается в 0 и сбрасывается счетчик.
Тестирование
Тестирование проводилось с использованием ПЛК Quantum 140CPU43412A, протокол обмена Modbus TCP, сеть Ethernet 10Мбит/c. Скан контроллера - 4 мс.Измерения проводились при использовании как синхронной, так и асинхронной версии функции записи значения тега в контроллер:
Количество измерений | Время импульса, с | Функция | ||
---|---|---|---|---|
среднее | минимальное | максимальное | ||
100 | 2.38 | 2.09 | 2.74 | SetTagBitWait |
100 | 2.38 | 2.11 | 2.75 | SetTagBit |
Результаты меня несколько удивили, казалось бы, при использовании асинхронной функции длина импульса должна была бы быть короче (предположительно, команда записи выдается с некоторой задержкой после вызова функции). На практике же разницы между результатами работы обеих функций не наблюдается.
После этого функция ShortPulse была переписана с использованием асинхронного SetTagBit:
void ShortPulse(char* tagName) { SetTagBit(tagName, 1); SetTagBit(tagName, 0); }
В результате 100 нажатий на кнопку в WinCC контроллер не потерял ни одного импульса.
В попытках понять есть ли вообще разница между этими функциями был написан следующий скрипт:
#include "apdefap.h" void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { SetTagBit("tag1", 1); SetTagBit("tag2", 1); SetTagBitWait("tag1", 0); SetTagBitWait("tag2", 0); }
В контроллере же измерялось количество сканов между установкой в единицу первого и второго тегов:
Количество измерений | Количество сканов контроллера | Функция | ||
---|---|---|---|---|
среднее | минимальное | максимальное | ||
500 | 2.22 | 1 | 8 | SetTagBitWait |
500 | 1.92 | 1 | 5 | SetTagBit |
Как видно из таблицы, синхронная версия функции в среднем выполняется все же немного дольше. При увеличении длительности скана эта разница скорее всего исчезнет.
Выводы
Используя приведенные результаты можно предположить, что асинхронная функция записи работает следующим образом:
- немедленно выдает команду записи в контроллер;
- не дожидаясь подтверждения выполнения команды заканчивает свою работу.
В любом случае использование синхронной версии для выдачи коротких импульсов более надежно.
Для длинных же импульсов с целью устранения задержек выполнения скриптов при возникновении проблем со связью допустимо использование асинхронной версии.
WinCC V7.0+SP3
Комментариев нет:
Отправить комментарий