PS Используется программный PLC
Вид для печати
PS Используется программный PLC
формированием маски массива, то, что "1" принимаем в работу, что "0" не принимаем.
Не знаю, как это на ST описать, на C# примерно такое делал, там где проставлял true, уходило в работу, остальное отбрасывалось.
У меня было два массива в результате. в Первом "источник" (например кран 1, кран 10, кран 23 и т.д.) во втором их данные.
Предположим у Вас есть ФБ ValveController, который осуществляет управление задвижкой.
ФБ выглядит примерно так:
Там, где Вам необходимо объявите массив ФБ (для примера объявлю в глобальных переменных):Код:FUNCTION_BLOCK ValveController
VAR_INPUT
sNameToSet : STRING;
END_VAR
VAR_OUTPUT
sName : STRING;
END_VAR
VAR
END_VAR
// Тело ФБ:
IF (sName = '') AND (sNameToSet <> '') THEN
sName := sNameToSet;
END_IF
и проинициализируйте его например так:Код:VAR_GLOBAL CONSTANT
g_c_uiValvesCount : UINT := 30;
END_VAR
VAR_GLOBAL
g_astValvesList : ARRAY [1..g_c_uiValvesCount] OF ValveController;
i : UINT;
END_VAR
Код:IF NOT m_xIsValvesInitialized THEN
FOR i := 1 TO g_c_uiValvesCount DO
g_astValvesList[i].sNameToSet := UINT_TO_STRING (i);
g_astValvesList[i]();
END_FOR
m_xIsValvesInitialized := TRUE;
END_IF
Когда станет известно к какой задвижке обратиться Вам нужно будет всего лишь найти индекс задвижки в массиве зная ее имя.
Например так:
Когда нужно будет обратиться к задвижке выполните кодКод:(*
Функция возвращает индекс задвижки в массиве по ее имени.
Если задвижка с указанным именем не найдена - вернет 0
*)
FUNCTION FindValveIndexByName : UINT
VAR_INPUT
sValveToFindName : STRING;
END_VAR
VAR
i : UINT;
END_VAR
// Тело функции
FindValveIndexByName := 0;
i := 1;
WHILE (FindValveIndexByName = 0) AND (i <= g_c_uiValvesCount) DO
IF g_astValvesList[i].sName = sValveToFindName THEN
FindValveIndexByName := i;
END_IF
i := i + 1;
END_WHILE
Единственное что нужно помнить - перебор 30000 значений приведет к увеличению времени цикла.Код:uiCurrentValveIndex := FindValveIndexByName ('5');
IF uiCurrentValveIndex > 0 THEN
(* Тут выполняете необходимые манипуляции с задвижкой примерно так g_astValvesList[uiCurrentValveIndex].state *)
END_IF
Поэтому выполняйте поиск по имени только тогда, когда это действительно важно.
В приложении файл, содержащий код из этого сообщения.
Если же Вы хотите сохранить возможность работы с задвижкой по имени переменной в программе подойдет второй способ:
Допустим ФБ Вашей задвижки выглядит так:
Объявите структуруКод:FUNCTION_BLOCK ValveController
VAR_INPUT
END_VAR
VAR_OUTPUT
dwState : DWORD;
END_VAR
VAR
END_VAR
Объявите массив структур (для примера в глобальных переменных)Код:TYPE NAMED_VALVE :
STRUCT
sName : STRING;
pfbValve : POINTER TO ValveController;
END_STRUCT
END_TYPE
Инициализируйте массив например так:Код:VAR_GLOBAL CONSTANT
g_c_uiValvesCount : UINT := 30;
END_VAR
VAR_GLOBAL
g_astValvesList : ARRAY [1..g_c_uiValvesCount] OF NAMED_VALVE;
END_VAR
Когда станет известно к какой задвижке обратиться Вам нужно будет всего лишь найти индекс задвижки в массиве зная ее имя.Код:IF NOT m_xIsValvesInitialized THEN
FOR i := 1 TO g_c_uiValvesCount DO
g_astValvesList[i].sName := UINT_TO_STRING (i);
g_astValvesList[i].pfbValve := 0; (* Вместо 0 ADR (экземпляр ФБ задвижки) *)
END_FOR
m_xIsValvesInitialized := TRUE;
END_IF
Например так:
Чтобы обратиться к задвижке выполните кодКод:(*
Функция возвращает индекс задвижки в массиве по ее имени.
Если задвижка с указанным именем не найдена - вернет 0
*)
FUNCTION FindValveIndexByName : UINT
VAR_INPUT
sValveToFindName : STRING;
END_VAR
VAR
i : UINT;
END_VAR
// Тело функции
FindValveIndexByName := 0;
i := 1;
WHILE (FindValveIndexByName = 0) AND (i <= g_c_uiValvesCount) DO
IF g_astValvesList[i].sName = sValveToFindName THEN
FindValveIndexByName := i;
END_IF
i := i + 1;
END_WHILE
Код:uiCurrentValveIndex := FindValveIndexByName ('5');
IF uiCurrentValveIndex > 0 THEN
IF g_astValvesList[i].pfbValve <> 0 THEN
;(* Тут выполняете необходимые манипуляции с задвижкой примерно так g_astValvesList[i].pfbValve^.dwState*)
END_IF
END_IF
Э-э, я дико извеняюсь, но объясните, пожалуйста, в чем смысл такой конструкции
Не проще ли тупо написать g_astValvesList : ARRAY [1..g_c_uiValvesCount] OF STRINGЦитата:
Код:
FUNCTION_BLOCK ValveController
VAR_INPUT
sNameToSet : STRING;
END_VAR
VAR_OUTPUT
sName : STRING;
END_VAR
VAR
END_VAR
// Тело ФБ:
IF (sName = '') AND (sNameToSet <> '') THEN
sName := sNameToSet;
END_IF
Там, где Вам необходимо объявите массив ФБ (для примера объявлю в глобальных переменных):
Код:
VAR_GLOBAL CONSTANT
g_c_uiValvesCount : UINT := 30;
END_VAR
VAR_GLOBAL
g_astValvesList : ARRAY [1..g_c_uiValvesCount] OF ValveController;
i : UINT;
END_VAR
Написать-то можно. А как потом понять что за задвижка под этим именем понимается?
Варианта 2:
1) Задвижка сама знает своем имя и входит в общий список задвижек (решение, приведенное в посте 13);
2) Задвижки не знают своих имен, но где-то в системе есть список всех задвижек с именами и указателями на них (решение, приведенное в посте 14).