Yegor
04.04.2013, 11:54
Смарите посоны чо я выдумал...
Вместо подписывания в конфигурации каждого выхода берём их всех как битовую маску D_OUTS.
В разделе глобальных констант делаем ещё кучу масок для всех выходов отдельно или для их комбинаций. Например, DO3: DWORD := 4 (единичка в третьем разряде).
Теперь вместо DO1 := DO2 := DO3 := TRUE можно писать D_OUTS := DO1 + DO2 + DO3.
Само по себе не намного короче, но это здорово облегчает код когда в автоматическом режиме комбинации выходов на разных шагах сильно меняются. Фишка в том, что на очередном шаге уже не надо сбрасывать то, что включилось на предыдущем. То есть как оно раньше было:
Step1:
DO1 := DO2 := TRUE;
Step2:
DO1 := FALSE;
DO3 := TRUE;А масочным способом можно так:
Step1:
D_OUTS := DO1 + DO2;
Step2:
D_OUTS := DO2 + DO3;Но это ещё цветочки. Вот когда надо постоянно включать-выключать одни и те же комбинации по каким-то условиям, то получается супер-пупер-лаконично и семантично:
Step1:
D_OUTS :=
STEAMER * BOOL_TO_DWORD(temp < 40) +
COOLER * BOOL_TO_DWORD(temp > 60);
Step2:
D_OUTS :=
DECONDENS * BOOL_TO_DWORD(timer.ET < timer.PT);, где STEAMER, COOLER и DECONDENS — маски для двух и более клапанов или иных узлов, работающих по логическим сигналам.
Если ещё ввести примитивную функцию и писать, например, when вместо громоздкого BOOL_TO_DWORD, то совсем лепота:
Step1:
D_OUTS :=
STEAMER * when(temp < 40) +
COOLER * when(temp > 60);
Step2:
D_OUTS :=
DECONDENS * when(timer.ET < timer.PT);Сам в шоке. Код для ПЛК на человеческом английском O_o
Для сравнения этот же по смыслу код в традиционном исполнении:
Step1:
STEAM_IN := STEAM_OUT := temp < 40;
COOLANT_IN := COOLANT_OUT := temp > 60;
Step2:
STEAM_IN := STEAM_OUT :=
COOLANT_IN := COOLANT_OUT := FALSE;
DECOND_OUT := timer.ET < timer.PT;Я уж молчу про «веточный» подход, где многие стали бы огород городить:
Step1:
IF temp < 40 THEN
STEAM_IN := TRUE;
STEAM_OUT := TRUE;
ELSE
STEAM_IN := FALSE;
STEAM_OUT := FALSE;
[...]
Конечно, в масочном подходе свои минусы. Например, трудно выяснять состояние выхода за пределами блока, где он переключается — приходится обращаться к конкретному биту D_OUTS операциями сдвига или вводить ещё кучу констант для нумерации битов. И код становится уродливым если используется более 32 дискретных выходов. Но пригодиться этот метод вполне может. Мне уже пригодился в одном проекте.
Спасибо за внимание.
Вместо подписывания в конфигурации каждого выхода берём их всех как битовую маску D_OUTS.
В разделе глобальных констант делаем ещё кучу масок для всех выходов отдельно или для их комбинаций. Например, DO3: DWORD := 4 (единичка в третьем разряде).
Теперь вместо DO1 := DO2 := DO3 := TRUE можно писать D_OUTS := DO1 + DO2 + DO3.
Само по себе не намного короче, но это здорово облегчает код когда в автоматическом режиме комбинации выходов на разных шагах сильно меняются. Фишка в том, что на очередном шаге уже не надо сбрасывать то, что включилось на предыдущем. То есть как оно раньше было:
Step1:
DO1 := DO2 := TRUE;
Step2:
DO1 := FALSE;
DO3 := TRUE;А масочным способом можно так:
Step1:
D_OUTS := DO1 + DO2;
Step2:
D_OUTS := DO2 + DO3;Но это ещё цветочки. Вот когда надо постоянно включать-выключать одни и те же комбинации по каким-то условиям, то получается супер-пупер-лаконично и семантично:
Step1:
D_OUTS :=
STEAMER * BOOL_TO_DWORD(temp < 40) +
COOLER * BOOL_TO_DWORD(temp > 60);
Step2:
D_OUTS :=
DECONDENS * BOOL_TO_DWORD(timer.ET < timer.PT);, где STEAMER, COOLER и DECONDENS — маски для двух и более клапанов или иных узлов, работающих по логическим сигналам.
Если ещё ввести примитивную функцию и писать, например, when вместо громоздкого BOOL_TO_DWORD, то совсем лепота:
Step1:
D_OUTS :=
STEAMER * when(temp < 40) +
COOLER * when(temp > 60);
Step2:
D_OUTS :=
DECONDENS * when(timer.ET < timer.PT);Сам в шоке. Код для ПЛК на человеческом английском O_o
Для сравнения этот же по смыслу код в традиционном исполнении:
Step1:
STEAM_IN := STEAM_OUT := temp < 40;
COOLANT_IN := COOLANT_OUT := temp > 60;
Step2:
STEAM_IN := STEAM_OUT :=
COOLANT_IN := COOLANT_OUT := FALSE;
DECOND_OUT := timer.ET < timer.PT;Я уж молчу про «веточный» подход, где многие стали бы огород городить:
Step1:
IF temp < 40 THEN
STEAM_IN := TRUE;
STEAM_OUT := TRUE;
ELSE
STEAM_IN := FALSE;
STEAM_OUT := FALSE;
[...]
Конечно, в масочном подходе свои минусы. Например, трудно выяснять состояние выхода за пределами блока, где он переключается — приходится обращаться к конкретному биту D_OUTS операциями сдвига или вводить ещё кучу констант для нумерации битов. И код становится уродливым если используется более 32 дискретных выходов. Но пригодиться этот метод вполне может. Мне уже пригодился в одном проекте.
Спасибо за внимание.