Найти в Дзене

Ротация нагрузок

Возникла проблема. Имеется несколько пароувлажнителей, общая мощность у них выше, чем мы можем использовать. Попросили реализовать такое решение - например одновременно разрешаем работать одновременно не больше пяти, ставим в очередь, и последовательно переключаем. Сперва хотел сделать в FBD. В регистр пишем, сдвигаем по кругу, но сходу не получилось. Этот регистр может меняться на ходу, его как то надо накладывать на регистр выходов, нет функции сдвига регистра с переносом битов (можно сделать свою конечно :) ) Короче сходу с FBD не заладилось. Благо в owenlogic есть возможность использовать модули в ST. Вкратце - создаем массив увлажнителей, которые нужно включить. Из этого массива читаем индексы первых пяти увлажнителей (1,2,3,4,5). Через заданное время начинаем считать со второго элемента следующие 5 индексов (2,3,4,5,6) и т.д. При этом следим, что если дошли до конца массива увлажнителей, то возвращаемся к началу. Ссылка на прогу Макрос ротатор получает состояние входов контрол

Возникла проблема. Имеется несколько пароувлажнителей, общая мощность у них выше, чем мы можем использовать. Попросили реализовать такое решение - например одновременно разрешаем работать одновременно не больше пяти, ставим в очередь, и последовательно переключаем.

Сперва хотел сделать в FBD. В регистр пишем, сдвигаем по кругу, но сходу не получилось. Этот регистр может меняться на ходу, его как то надо накладывать на регистр выходов, нет функции сдвига регистра с переносом битов (можно сделать свою конечно :) ) Короче сходу с FBD не заладилось. Благо в owenlogic есть возможность использовать модули в ST.

Вкратце - создаем массив увлажнителей, которые нужно включить. Из этого массива читаем индексы первых пяти увлажнителей (1,2,3,4,5). Через заданное время начинаем считать со второго элемента следующие 5 индексов (2,3,4,5,6) и т.д. При этом следим, что если дошли до конца массива увлажнителей, то возвращаемся к началу.

Ссылка на прогу

Общий вид
Общий вид

Макрос ротатор получает состояние входов контроллера и управляет выходами.

Импульсы для смещения очереди получает от генератора импульсов "BLINK".

Ниже представлено, как макрос выглядит внутри.

==============================================

FUNCTION_BLOCK rotator
VAR_INPUT
di_01, di_02, di_03, di_04, di_05, di_06, di_07, di_08,
di_09, di_10, di_11, di_12, di_13, di_14, di_15, di_16 : BOOL;

(* овен лоджик не позволяет создавать для входных и выходных переменных
массивы, так что приходится так извращаться *)
pulse:BOOL;
n_enable: UDINT; //количество разрешенных одновременно включенных входов
END_VAR


VAR_OUTPUT
do_01, do_02, do_03, do_04, do_05, do_06, do_07, do_08,
do_09, do_10, do_11, do_12, do_13, do_14, do_15, do_16 : BOOL;
n_active: UDINT;
END_VAR
VAR
di: ARRAY [0..16] OF BOOL;
dout: ARRAY [0..16] OF BOOL;
di_activ: ARRAY [0..16] OF UDINT; //массив индексов включенных входов
bgn: UDINT:=1; //первый индекс для формирования массива выходов включения

i, j: UDINT;
mempulse: BOOL; //для отлова фронта pulse
frontpulse: BOOL;
END_VAR

//формирование массива di [i] (эта конструкция нужна, потому что овенлоджик не умеет работать с массивами на входе и выходе)
di[1]:=di_01; di[2]:= di_02; di[3] :=di_03; di[4] :=di_04; di[5]:= di_05; di[6]:= di_06; di[7]:= di_07; di[8]:= di_08;
di[9]:=di_09; di[10]:=di_10; di[11]:=di_11; di[12]:=di_12; di[13]:=di_13; di[14]:=di_14; di[15]:=di_15; di[16]:= di_16;
//формирование массива активных входов (
j:=0;
n_active := 0;
FOR i:=1 TO 16 DO di_activ [i]:=0; END_FOR; //инициализация
FOR i:=1 TO 12 DO
IF di[i] THEN j:=J+1; di_activ[j]:=i;
END_IF
END_FOR
n_active := j;
//отлов фронта pulse
frontpulse := pulse AND (NOT mempulse);
mempulse := pulse;
//приращение begin
IF frontpulse THEN bgn:=bgn+1; END_IF //приращение
IF bgn >16-n_enable THEN bgn :=1; END_IF //переход в начало
//включение выходов, сколько входов
IF n_active > n_enable and (not di_14) THEN //если активных входов больше разрешенных или вход "нет ограничение"=true
FOR i:=1 TO 16 DO dout [i] :=FALSE; END_FOR; //инициализация
FOR i:=bgn TO (bgn + n_enable-1) DO
IF i>n_active
THEN dout [ di_activ [i - n_active ] ] :=TRUE; //если в массиве di_activ
закончились разрешенные входы
ELSE dout [ di_activ[i] ]:=TRUE; //если массив не закончился
END_IF
END_FOR
ELSE // если активных входов меньше разрешенных
FOR i:=1 TO 13 DO dout [i] := di [i]; END_FOR;
END_IF

//отправка на выход
do_01:=dout[1] ; do_02:=dout[2] ; do_03:=dout[3] ; do_04:=dout[4] ;
do_05:=dout[5] ; do_06:=dout[6] ; do_07:=dout[7] ; do_08:=dout[8] ;
do_09:=dout[9] ; do_10:=dout[10]; do_11:=dout[11]; do_12:=dout[12];
do_13:=dout[13]; do_14:=dout[14] ; do_15:=dout[15] ; do_16:=dout[16];

end_function_block

================================================

Овенлоджик не позволяет во время отладки видеть, что происходит внутри макроса. Поэтому редактировал и отлаживал его в кодесисе, потом просто скопировал раздел переменных и тело программы в макрос в овенлоджике.