Просмотр полной версии : Переключатель по заданному времени
Доброе время суток!
Уважаемые профессионалы, прошу помочь в такой проблеме:
Задача:
Необходимо выполнять переключение 2-х групп реле через определенный промежуток времени. Т.е. необходимо, чтобы по нажатию кнопки "PWR", включалась 1-я группа реле, а через определенное время включалась 2-я группа реле и так в цикле 1-2-1-2-1-2.... до выключения кнопки "PWR".
Программу переключения вручную я без проблем сделал. Но с таймерами не могу разобраться. Все начинает переключаться хаотично (таймеры при этом стоят).
Я так понимаю, у меня не получается изменить вход "IN" с TRUE на FALSE на таймерах, после первого события. (Я так понял, что команды выполняются не последовательно и я постоянно присваиваю переменным разные значения...)
WHILE pwr=TRUE
DO
IF ADS=TRUE THEN
CicleADSL(IN:= STARTL, PT:= CicleTime, Q=>ADS_L, ET=>TimeSee);
ADS:=FALSE;
STARTL:=FALSE;
STARTR:=TRUE;
END_IF;
IF ADS=FALSE THEN
CicleADSR(IN:= STARTR, PT:= CicleTime, Q=>ADS_R, ET=> TimeSee);
ADS:=TRUE;
STARTR:=FALSE;
STARTL:=TRUE;
END_IF
END_WHILE;
По моему видению, при нажатии кнопки "PWR" если ADS=TRUE, то запускается таймер, при его истечении меняется ADS на FALSE, входной сигнал таймера сбрасывается и подается сигнал на другой таймер... Но такая программа точно не работает.
Объясните пожалуйста.
Пишу на ST
Andrew_Stranger
26.06.2016, 18:09
Сперва наверно можно от цикла while do отказаться.
Сперва наверно можно от цикла while do отказаться.
Ваш вариант - как закоментировать действие пока нажата кнопка "PWR" ?
lara197a
26.06.2016, 18:47
используйте фронт.
ПЛК и так работает в цикле, поэтому специально его не надо организовывать
Владимир Ситников
26.06.2016, 19:37
Ваш вариант - как закоментировать действие пока нажата кнопка "PWR" ?
Смотрите:
1) программа для ПЛК должна отвечать на вопрос "что делать прямо сейчас", и отвечать она должна крайне быстро (оставшееся время тратится, например, на обработку сети и т.п. служебных функций)
2) во время работы программы, значения входов/выходов не изменяются
Поэтому вместо "while(true) { включить один насос; выключить другой; }" надо программировать в духе "если (пришла_пора_включать) { включить; }"
В итоге, циклы (while, for, и т.п.) -- только для обработки массивов (ну или какой-нибудь высшей математики в крайнем случае)
Смотрите:
1) программа для ПЛК должна отвечать на вопрос "что делать прямо сейчас", и отвечать она должна крайне быстро (оставшееся время тратится, например, на обработку сети и т.п. служебных функций)
2) во время работы программы, значения входов/выходов не изменяются
Поэтому вместо "while(true) { включить один насос; выключить другой; }" надо программировать в духе "если (пришла_пора_включать) { включить; }"
В итоге, циклы (while, for, и т.п.) -- только для обработки массивов (ну или какой-нибудь высшей математики в крайнем случае)
Огромная благодарность всем.
Я так понял, что переключение лучше делать через триггеры. Сейчас изучаю данную тему.
2-й день только учусь программировать в CodeSys...
С Визуализациями разобрался очень быстро. уже нарисовал управление и вводы с выводами, назначил устройства, подключил СПК-107. Теперь осталось освоить принципы построения программ...
krollcbas
26.06.2016, 20:13
На мой личный взгляд - проще использовать автомат состояний
На CASE пишется (http://lapshinvr.ru/algoritm.html)
На мой личный взгляд - проще использовать автомат состояний
На CASE пишется (http://lapshinvr.ru/algoritm.html)
Я очень давно на турбопаскале программировал, поэтому мне пока простые программы более понятны если строками писать. Освою это, буду осваивать другие.
Все написал, все работает как часы! Еще раз огромная благодарность всем!
Прошу Подсказать еще один вопрос. Ввод времени я сделал через REAL_TO_TIME*1000. (получил 1000 х Миллисекунд). Как мне вывести на панель показание прошедшего времени?
Т.е. есть функция TimeSee:=TON_gen.ET - как ее показания вывести на панель?
Все написал, все работает как часы! Еще раз огромная благодарность всем!
Прошу Подсказать еще один вопрос. Ввод времени я сделал через REAL_TO_TIME*1000. (получил 1000 х Миллисекунд). Как мне вывести на панель показание прошедшего времени?
Т.е. есть функция TimeSee:=TON_gen.ET - как ее показания вывести на панель?
От я балбес! тоже самое!
Объявляем TimeSee:REAL а не TIME
Конвертируем TimeSee:=TIME_TO_REAL (TON_gen.ET/1000)...
Создал программу как функциональный блок.
добавил в тело программы входы и выходы - не работает.
Подскажите балбесу - что не так?
FUNCTION_BLOCK Cicle_TiMeR
VAR_INPUT
start: BOOL;
interval: TIME;
END_VAR
VAR_OUTPUT
//Прошедшее время таймера - индикация
Time_See:TIME;
// Выход 1
OUT1:BOOL;
// Выход 2
OUT2: BOOL;
END_VAR
VAR
TON_gen: TON;
switch: BOOL;
R_TRIG_start: R_TRIG;
END_VAR
_______________________
R_TRIG_start(CLK:= start);
IF R_TRIG_start.Q THEN
TON_gen(IN:= FALSE);
switch:=FALSE;
END_IF
TON_gen(IN:= NOT TON_gen.Q, PT:= interval);
IF TON_gen.Q THEN
switch:=NOT switch;
END_IF
OUT1:=start AND NOT switch;
OUT2:=start AND switch;
Time_See:=TON_gen.ET;
______________________________
Программа
ADSL:=Timer1.OUT1;
ADSR:=Timer1.OUT2;
Timer1.interval:=REAL_TO_TIME (TimeIn)*1000;
Timer1.start:=TRUE;
// Вывод пройденого времени
TimeSee:=TIME_TO_REAL(Timer1.Time_see/1000);
// Правое направление в работе
IF ADSR=TRUE THEN RL1:=FALSE;
END_IF
// Левое направление в работе
IF ADSL=TRUE THEN RL1:=TRUE;
END_IF
Создал программу как функциональный блок.
добавил в тело программы входы и выходы - не работает.
Подскажите балбесу - что не так?
FUNCTION_BLOCK Cicle_TiMeR
VAR_INPUT
start: BOOL;
interval: TIME;
END_VAR
VAR_OUTPUT
//Прошедшее время таймера - индикация
Time_See:TIME;
// Выход 1
OUT1:BOOL;
// Выход 2
OUT2: BOOL;
END_VAR
VAR
TON_gen: TON;
switch: BOOL;
R_TRIG_start: R_TRIG;
END_VAR
_______________________
R_TRIG_start(CLK:= start);
IF R_TRIG_start.Q THEN
TON_gen(IN:= FALSE);
switch:=FALSE;
END_IF
TON_gen(IN:= NOT TON_gen.Q, PT:= interval);
IF TON_gen.Q THEN
switch:=NOT switch;
END_IF
OUT1:=start AND NOT switch;
OUT2:=start AND switch;
Time_See:=TON_gen.ET;
______________________________
Программа
ADSL:=Timer1.OUT1;
ADSR:=Timer1.OUT2;
Timer1.interval:=REAL_TO_TIME (TimeIn)*1000;
Timer1.start:=TRUE;
// Вывод пройденого времени
TimeSee:=TIME_TO_REAL(Timer1.Time_see/1000);
// Правое направление в работе
IF ADSR=TRUE THEN RL1:=FALSE;
END_IF
// Левое направление в работе
IF ADSL=TRUE THEN RL1:=TRUE;
END_IF
Прежде чем обращаться к переменным ФБ, нужно это ФБ вызвать на выполнение, т.е.
сначала
Timer1();
и только потом
ADSL:=Timer1.OUT1;
ADSR:=Timer1.OUT2;
TimeSee:=TIME_TO_REAL(Timer1.Time_see/1000);
Кое что можно совместить, например
Timer1(start:= TRUE, interval:=REAL_TO_TIME (TimeIn)*1000 , OUT1=>ADSL , OUT2=>ADSR );
25162
Все в точности как Вы делаете при использовании ФБ из библиотек
Сначала Вы вызываете ФБ
R_TRIG_start(CLK:= start);
А уже затем анализируете выход ФБ
IF R_TRIG_start.Q THEN
..........
Понял! Все заработало.
Огромная благодарность!
Насколько я понял - данная реализация переключения построена на изменении "ЗНАКА" переменной, посредством подачи сигнала на запуск таймера TON, а затем, как только (через заданный интервал) на выходе Q таймера TON появляется сигнал, происходит сброс входа IN и происходит смена "знака" переменной. И мгновенно снова подается сигнал на вход таймера TON. и так цикл повторяется. Все верно я понял?
Усложнил задачу.
Ситуация следующая:
Необходимо чтобы при включении питания сработал таймер включающий функцию отдувки на заданное время. По окончании данного цикла, включилась левая сторона, по окончании работы левой стороны включился цикл отдувки, затем правая сторона и т.д. (главное чтобы после каждого цикла отдувки включались разные стороны.
ЧТО я опять сделал неправильно и наверное через Ж... реализовал задачу???
Вот функц. блок таймера:
____________________________
FUNCTION_BLOCK Timer_CCL
VAR_INPUT
Start:BOOL;
Interval:TIME;
SwitchIN:BOOL;
END_VAR
VAR_OUTPUT
Signal:BOOL;
CicleON:BOOL;
SwitchOUT:BOOL;
TimeSee:REAL;
END_VAR
VAR
//Триггер
R_TRIG_start: R_TRIG;
//Таймер TON
TON_GEN:TON;
END_VAR
_____________________________
TON_gen(IN:= Start, PT:= interval);
IF TON_gen.Q THEN (*если пришел импульс от таймера*)
Start:=FALSE;
SwitchOUT:=NOT SwitchIN; (* Переключение входной функции на противоположный знак*)
END_IF
// Вывод пройденного времени
TimeSee:=TIME_TO_REAL(TON_gen.ET/1000);
//Включение Цикла во время работы таймера
CicleON:=start AND NOT TON_gen.Q; (*Сигнал пока таймер работает*)
//Подача сигнала из выхода таймера на вывод "Signal" из блока
Signal:=TON_GEN.Q;
______________________________
Само тело программы
IF PWR THEN
IF Start=FALSE THEN Timer_SDUV(Start:=NOT Start, Interval:=REAL_TO_TIME(TimeInSduv*1000), SwitchIN:=Start, Signal=>SignalC, CicleON=>Otduv, SwitchOUT=>Start, TimeSee=>TimeSeeSduv);
ELSE
Cicle(Start:=SignalC, Interval:=REAL_TO_TIME(TimeInCicle*1000), SwitchIN:=Switch, Signal=>SignalO, CicleON=>ADS, SwitchOUT=>Switch, TimeSee=>TimeSeeCicle);
Timer_SDUV(Start:=SignalO, Interval:=REAL_TO_TIME(TimeInSduv*1000), Signal=>SignalC, CicleON=>Otduv, TimeSee=>TimeSeeSduv);
END_IF
ADSL:=ADS AND switch;
ADSR:=ADS AND NOT switch;
ELSE START:=FALSE; RL1:=FALSE; RL2:=FALSE; RL3:=FALSE; RL4:=FALSE; RL5:=FALSE; RL6:=FALSE; RL7:=FALSE;
END_IF
_____________________________
Заменил в теле программы "IF PWR THEN
IF Start=FALSE THEN Timer_SDUV(Start:=NOT Start, Interval:=REAL_TO_TIME(TimeInSduv*1000), SwitchIN:=Start, Signal=>SignalC, CicleON=>Otduv, SwitchOUT=>Start, TimeSee=>TimeSeeSduv);
на
R_TRIG_START.CLK:=FALSE;
IF PWR THEN
R_TRIG_START(CLK:=PWR, Q=>SignalC);
Cicle(Start:=SignalC, Interval:=REAL_TO_TIME(TimeInCicle*1000), SwitchIN:=Switch, Signal=>SignalO, CicleON=>ADS, SwitchOUT=>Switch, TimeSee=>TimeSeeCicle);
Timer_SDUV(Start:=SignalO, Interval:=REAL_TO_TIME(TimeInSduv*1000), Signal=>SignalC, CicleON=>Otduv, TimeSee=>TimeSeeSduv);
ADSL:=ADS AND NOT switch;
ADSR:=ADS AND switch;
ENF_IF
....
Все равно циклы не запускаются....
так подойдет?
Не могу импортировать - пишет "Недопустимые данные на корневом уровне., строка 3, позиция 1."
в простом редакторе откройте
Доработал чуток...
вот что получилось.
Так и не могу понять почему циклы не запускаются....
Объясните пожалуйста в чем ошибка?
R_TRIG_START.CLK:=FALSE;
IF PWR THEN
R_TRIG_START(CLK:=PWR);
SignalO:=R_TRIG_START.Q;
Timer_SDUV(Start:=SignalO, Interval:=REAL_TO_TIME(TimeInSduv*1000), Signal=>SignalC, CicleON=>Otduv, TimeSee=>TimeSeeSduv);
Cicle(Start:=Timer_SDUV.Signal, Interval:=REAL_TO_TIME(TimeInCicle*1000), SwitchIN:=Switch, Signal=>SignalO, CicleON=>ADS, SwitchOUT=>Switch, TimeSee=>TimeSeeCicle);
ADSL:=Cicle.CicleON AND NOT switch;
ADSR:=Cicle.CicleON AND switch;
// Отдувка в работе
IF Timer_SDUV.CicleON THEN RL1:=FALSE; RL2:=FALSE; RL3:=FALSE; RL4:=FALSE; RL5:=FALSE; RL6:=FALSE; RL7:=TRUE;
END_IF
// Правое направление в работе
IF ADSR THEN RL1:=FALSE; RL2:=TRUE; RL3:=TRUE; RL4:=FALSE; RL5:=FALSE; RL6:=TRUE; RL7:=TRUE;
END_IF
// Левое направление в работе
IF ADSL THEN RL1:=TRUE; RL2:=FALSE; RL3:=FALSE; RL4:=TRUE; RL5:=TRUE; RL6:=FALSE; RL7:=TRUE;
END_IF
ELSE RL1:=FALSE; RL2:=FALSE; RL3:=FALSE; RL4:=FALSE; RL5:=FALSE; RL6:=FALSE; RL7:=FALSE;
END_IF
Я понял. Циклы не меняются, потому что на вход подается сигнал и исчезает, соответственно когда таймер заканчивается, нет сигнала на выходе из ФБ...
Cамый дельный совет - п#8
Cамый дельный совет - п#8
Переведите пожалуйста...
Пост нумер 8
На мой личный взгляд - проще использовать автомат состояний..На CASE..
Пост нумер 8
сегодня 3-й день как я начал заниматься программированием в CodeSys... Пока пишу на ST (ввиду прошлых знаний "ТурбоПаскаль").
Но я все сделал!!! Все работает как часы!!!!
25173 25174 25175 25176
Что сделал - молодец. Касаемо ТР, так КДС2 - брат ТР5.5
Чисто для справки :
Необходимо чтобы при включении питания сработал таймер включающий функцию отдувки на заданное время.
По окончании данного цикла, включилась левая сторона, по окончании работы левой стороны включился цикл отдувки, затем правая сторона и т.д. (главное чтобы после каждого цикла отдувки включались разные стороны
var_input
питание : bool;
...
end_var
var_output
выход_влево, //выходы для примера
выход_вправо,
выход_отдувалки : bool;
end_var
var
шаг : (нету_питания, отдув_перед_вправо, вправо, отдув_перед_влево, влево);
t : ton;
end_var
------------
if нет питание then
шаг := нету_питания;
end_if
case шаг of
нету_питания:
if питание then
t(in := false);
шаг := отдув_перед_вправо;
end_if
отдув_перед_вправо:
t(in:=true, pt := ...); //время хоть для каждого шага свое
if t.q then
t(in := false);
шаг := вправо;
end_if
вправо:
t(in:=true, pt := ...);
if t.q then
t(in := false);
шаг := отдув_перед_влево;
end_if
отдув_перед_влево:
t(in:=true, pt := ...);
if t.q then
t(in := false);
шаг := влево;
end_if
вправо:
t(in:=true, pt := ...);
if t.q then
t(in := false);
шаг := отдув_перед_вправо;
end_if
end_case
//по автомату - выставляем выходы, например
выход_вправо := шаг = вправо;
выход_влево := шаг = влево;
выход_отдувалки := шаг = отдув_перед_вправо or шаг = отдув_перед_влево;
Немного громоздко - но на порядок читаемей и модифицируемей. А после свернуть в трубочку можно что угодно.
Например вышеизложенное - с той же автоматной логикой :
t(in := питание, pt := mux(шаг, t#0s, .....));
if нет питание then
шаг := нету_питания;
end_if
if t.q then //вот тут весь кейс
t(in := false);
шаг := mux(шаг, отдув_перед_вправо, вправо, отдув_перед_влево, влево, отдув_перед_вправо);
end_if
... //установка выходов
Вот ФБ и программа:
FUNCTION_BLOCK Timer_CCL
VAR_INPUT
Start:BOOL;
Interval:TIME;
SwitchIN:BOOL;
END_VAR
VAR_OUTPUT
CicleON:BOOL;
SwitchOUT:BOOL;
TimeSee:REAL;
END_VAR
VAR
//Таймер TON
TON_GEN:TON;
END_VAR
_______________________________
TON_gen(IN:= Start, PT:= interval);
IF TON_gen.Q THEN (*если пришел импульс от таймера*)
Start:=FALSE;
SwitchOUT:=NOT SwitchIN; (* Переключение входной функции на противоположный знак*)
END_IF
// Вывод пройденного времени
TimeSee:=TIME_TO_REAL(TON_gen.ET/1000);
//Включение Цикла во время работы таймера
CicleON:=start AND NOT TON_gen.Q; (*Сигнал пока таймер работает*)
____________________________________________
Тело программы
IF PWR THEN
IF START THEN Timer_SDUV(Start:=PWR, Interval:=REAL_TO_TIME(TimeInSduv*1000),CicleON=>SignalC);;
SignalO:=PWR; START:=FALSE;
END_IF;
Timer_SDUV(Start:=NOT SignalO, Interval:=REAL_TO_TIME(TimeInSduv*1000), CicleON=>SignalC, TimeSee=>TimeSeeSduv);
Cicle(Start:=NOT SignalC, Interval:=REAL_TO_TIME(TimeInCicle*1000), SwitchIN:=Switch, CicleON=>SignalO, SwitchOUT=>Switch, TimeSee=>TimeSeeCicle);
Otduv:=Timer_SDUV.CicleON;
ADSL:=SignalO AND NOT switch;
ADSR:=SignalO AND switch;
// Отдувка в работе
IF Otduv THEN RL1:=FALSE; RL2:=FALSE; RL3:=FALSE; RL4:=FALSE; RL5:=FALSE; RL6:=FALSE; RL7:=TRUE;
END_IF
// Правое направление в работе
IF ADSR THEN RL1:=FALSE; RL2:=TRUE; RL3:=TRUE; RL4:=FALSE; RL5:=FALSE; RL6:=TRUE; RL7:=TRUE;
END_IF
// Левое направление в работе
IF ADSL THEN RL1:=TRUE; RL2:=FALSE; RL3:=FALSE; RL4:=TRUE; RL5:=TRUE; RL6:=FALSE; RL7:=TRUE;
END_IF
ELSE Otduv:=FALSE; SignalO:=FALSE; SignalC:=FALSE; ADSR:=FALSE; ADSL:=FALSE;
RL1:=FALSE; RL2:=FALSE; RL3:=FALSE; RL4:=FALSE; RL5:=FALSE; RL6:=FALSE; RL7:=FALSE;
END_IF
Исходил из того, что усложнял первые попытки работать с таймерами и закладывал базу на доп. направления через ФБ (если понадобится).
Не судите строго пожалуйста!
Первый блин всегда комом...
В моей программе для добавления направления, достаточно создать еще один вызов ФБ... и т.д.
А Вашу программу сейчас изучу.
Вам всем - Огромная благодарность за помощь и советы!
На мой личный взгляд - проще использовать автомат состояний
На CASE пишется (http://lapshinvr.ru/algoritm.html)
Добрый день!
Это FBD который?
Добрый день!
Это FBD который?
я Вам на ST написал рабочий пример, так и не посмотрели что ли
я Вам на ST написал рабочий пример, так и не посмотрели что ли
Я-то всего несколько дней занимаюсь этим...
ФБ там нормально, в самом начале прописана, а вот тело программы я пока не понял где и как... Да и ночь у меня уже глубокая была.
Буду на выходных разбираться и с Вашей и с другой, которую тут тоже разместили.
Надо вникать мне, поэтому в любом случае буду...
Я вчера еще посмотрел.
Но он у меня в таком вот виде...
И мне пока далеко не все понятно там...
_CHANNEL
_SECTION_NAME: 'BitOutput'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: ''
_COMMENT: 'relay'
_CHANNEL_MODE: 'Q'
_IECADR: %QX1.0
_END_CHANNEL
_END_MODULE
_MODULE: '3S'
_SECTION_NAME: 'ID102'
_INDEX_IN_PARENT: '4'
_MODULE_NAME: 'Discrete output - relay'
_NODE_ID: 2
_IECIN: %IB2
_IECOUT: %QB2
_IECDIAG: %MB2
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_PARAMETER
_PARAM 1: 0, '1'
_PARAM 2: 0, 'FALSE'
_PARAM 3: 0, 'No'
_END_PARAMETER
_CHANNEL
_SECTION_NAME: 'BitOutput'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: ''
_COMMENT: 'relay'
_CHANNEL_MODE: 'Q'
_IECADR: %QX2.0
_END_CHANNEL
_END_MODULE
_MODULE: '3S'
_SECTION_NAME: 'ID102'
_INDEX_IN_PARENT: '6'
_MODULE_NAME: 'Discrete output - relay'
_NODE_ID: 3
_IECIN: %IB3
_IECOUT: %QB3
_IECDIAG: %MB3
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_PARAMETER
_PARAM 1: 0, '1'
_PARAM 2: 0, 'FALSE'
_PARAM 3: 0, 'No'
_END_PARAMETER
_CHANNEL
_SECTION_NAME: 'BitOutput'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: ''
_COMMENT: 'relay'
_CHANNEL_MODE: 'Q'
_IECADR: %QX3.0
_END_CHANNEL
_END_MODULE
скорее всего у Вас таргет для 100R-L на ПК не установлен поэтому проект и не импортируется
Владимир Ситников
29.06.2016, 14:29
Я вчера еще посмотрел.
Но он у меня в таком вот виде...
И мне пока далеко не все понятно там...
_CHANNEL
_SECTION_NAME: 'BitOutput'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: ''
_COMMENT: 'relay'
_CHANNEL_MODE: 'Q'
_IECADR: %QX1.0
_END_CHANNEL
_END_MODULE
EXP файлы нужно импортировать в codesys. Конкретный фрагмент -- это фрагмент "конфигурации ПЛК" (но в таком текстовом виде крайне редко кто смотрит)
В общем, импортируйте EXP (где-то в меню должно быть import) -- будет счастье.
Ну или смотрите только на ST часть -- там как раз пример "классического CASE"
Нет счастья :)
Не хочет импортировать
25190 25191 Естественно я его достал из архива...
так это же 3.5, такой экспорт не сработает, только ручками переносить себе в проект из текстового редактора. зачем Вы пишите тогда в теме про кдс2.3
Владимир Ситников
29.06.2016, 15:01
Нет счастья :)
Не хочет импортировать
25190 25191 Естественно я его достал из архива... Так у вас какая версия Codesys? Тема про v2, а картинка от третьей
Так у вас какая версия Codesys? Тема про v2, а картинка от третьей
а..... ну так искал похожие темы на форуме - почитал тут... и даже не посмотрел что это v2... я то весь материал штудировал в v2....
Да и особой разницы я и не заметил... в принципе...
запарился... а разница в версиях принципиальна?
Вроде операторы что в 2 что в 3 одинаковые...
Владимир Ситников
29.06.2016, 17:08
запарился... а разница в версиях принципиальна?
Вроде операторы что в 2 что в 3 одинаковые...
Разницы никакой за исключением того, что
1) Контроллер работает с одной конкретной версией
2) Форматы файлов слабо совместимы. Вам пример проекта показывают, а по факту в "не той" версии он не откроется
3) В v3 язык богаче (т.е. там есть операторы, которых в v2 нет)
Powered by vBulletin® Version 4.2.3 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot