PDA

Просмотр полной версии : Управление работой вентиляторов



alexval2006
07.09.2011, 13:38
Посоветуйте как реализовать на ST управление вентиляторами есть 4 механизма Механизм №1, Механизм №2, Механизм №3 и Механизм №4 и несколько вентиляторов Вентилятор №1, Вентилятор №2, Вентилятор №3. Если включён Механизм №1 должен включится Вентилятор №1 и Вентилятор №2. Если включён Механизм №2 должен включится Вентилятор №1 и Вентилятор №3 и т.п. Если включается Механизм №1 а Вентилятор №1 или Вентилятор №2 используются другим механизмом и уже включены то не трогаем их. Если выключается Механизм №1 а Вентилятор №1 или Вентилятор №2 используются ещё и другим механизмом то не трогаем их пусть работают они выключатся когда последний механизм будет выключатся. Ну вот такая хитрая логика как включить я представляю простое условие а вот как контролировать выключение чтобы не выключить вентилятор использующийся параллельно и другим механизмом.

swerder
07.09.2011, 14:37
vent1 := false;
vent2 := false;
vent3 := false;
if mech1 then
vent1 := true;
vent2 := true;
end_if;
if mech2 then
vent1 := true;
vent3 := true;
end_if;
...

swerder
07.09.2011, 14:42
#2
vent1 := mech1 or mech2;
vent2 := mech1 or ...
vent3 := mech1 or ...

alexval2006
07.09.2011, 14:47
да еще хочу сказать что каждый механизм имеет входы пуск и стоп так что тут немного сложнее

swerder
07.09.2011, 15:00
отнюдь, воспользуйтесь переключающим реле

swerder
07.09.2011, 18:28
Var
Mech1 :byte:= 2#0011;
Mech2 :byte:= 2#0101;
..


Fan:= Mech1 or Mech2 or Mech3 or Mech4;
Do1 := Fan.0;
Do2 := Fan.1;
Do3 := Fan.2;
Do4 := Fan.3;


т.к. в разделе объявлений уже заданы "параметры" по F5 первые 3 фана сразу вкл. не вкурил пока идею...

Николаев Андрей
07.09.2011, 19:29
НЕ совсем может ответ - но Ваш выбор совсем другой язык.
На LD - это всего несколько строк.

alexval2006
08.09.2011, 07:39
благадарю вас товарищи за свежие идеи и помощ буду пробовать

swerder
08.09.2011, 09:57
кстати очень интересный финт "byte or byte" - изучается еще на первых уроках логики/программирования, а вспомнился только сейчас

alexval2006
08.09.2011, 14:03
А можно немного пояснений по коду что то я не в курю что делает таймер Stop4 : TP := ( PT := T#..); какое время выставлять и зачем далее

Start1,
Stop1,
в объявлениях как понять или подразумеваете объявить их BOOL
да и в обще общая логика

ну вот что получилось



PROGRAM PRG_3
VAR
Mech1 :BYTE:= 2#0001;
Mech2 :BYTE:= 2#0011;
Mech3 :BYTE:= 2#0111;
Mech4 :BYTE:= 2#1111;
Stop1 : TP:= ( PT := T#1s);
Start1 : TP:= ( PT := T#1s);
Stop2 : TP:= ( PT := T#1s);
Start2 : TP:= ( PT := T#1s);
Stop3 : TP:= ( PT := T#1s);
Start3 : TP:= ( PT := T#1s);
Stop4 : TP:= ( PT := T#1s);
Start4 : TP:= ( PT := T#1s);
Fan: WORD;
Do1: BOOL;
Do2: BOOL;
Do3: BOOL;
Do4: BOOL;
END_VAR
(************************************************* **********)
Fan:= Mech1 OR Mech2 OR Mech3 OR Mech4;
Start1(IN:=Fan.0,Q=>Do1 );
Stop1(IN:=NOT Fan.0,Q=>Do1 );

работает как то не так точнее хз как

swerder
08.09.2011, 15:15
mech1, mech2... сигнал включения механизмов, bool
vent1, vent2... выходные с контроллера, тоже bool
в теле программы:
vent1 := mech1 or mech2;
vent2 := mech1 or ...
vent3 := mech2 or ...

таймеры предложены были на случай импульсного управления двигателями

alexval2006
08.09.2011, 15:41
вот наверно так но не сосем еще понял


PROGRAM PRG_3
VAR
Stop1 : TP:= ( PT := T#1s);
Start1 : TP:= ( PT := T#1s);
Stop2 : TP:= ( PT := T#1s);
Start2 : TP:= ( PT := T#1s);
Stop3 : TP:= ( PT := T#1s);
Start3 : TP:= ( PT := T#1s);
Stop4 : TP:= ( PT := T#1s);
Start4 : TP:= ( PT := T#1s);
fan: WORD;

Do1: BOOL;
Do2: BOOL;
Do3: BOOL;
Do4: BOOL;

setmech : ARRAY[1..4] OF BYTE := 2#0001, 2#0011, 2#0111, 2#1111;
mech : ARRAY[1..4] OF BOOL;
fan:=0;
FOR i :=1 TO 4 DO
fan:=SEL( mech[i], fan, fan OR setmech[i] );
END_FOR
END_VAR
(************************************************* ****)
Fan:= Mech1 OR Mech2 OR Mech3 OR Mech4;
Start1(IN:=Fan.0,Q=>Do1 );
Stop1(IN:=NOT Fan.0,Q=>Do1 );

но еще 4 ошибки пр компиляции наверно я еще не до конца понял что где дописать нужно


да еще это все будет работать с таким ФБ


VAR_GLOBAL CONSTANT(* Для хранения аварий механизмов *)
Ok : WORD := 0;
xReidi : BYTE := 0; (* Номера битов флага аварий *)
xSped : BYTE := 1;
xPodpor : BYTE := 2;
xTok : BYTE := 3;
END_VAR
(************************************************* ***********)


FUNCTION_BLOCK CULER (*Функциональный блок для управления ВЕНТИЛЯТОРОМ*)
VAR_INPUT
auto : BOOL; (* Автоматический режим работы *)
man_start,
man_stop : BOOL; (* Экранные кнопки СТАРТ и СТОП *)
auto_start,
auto_stop : BOOL; (* Сигналы в режиме автомат СТАРТ и СТОП *)
sens_reidi : BOOL; (* Включение (обратная связь ?) *)
reset : BOOL; (* Сигнал сброса аварии *)
END_VAR
VAR_OUTPUT
out : BOOL; (* Выходы на пускатель *)
fAlarm : WORD; (* Флаг аварий *)
END_VAR
VAR
step : (stop, start, alarm); (* Состояние управляющего процесса *)
timer_reidi : TON; (* Контроль включения *)
RTRIG_auto_start: R_TRIG;
RTRIG_auto_stop: R_TRIG;
END_VAR
(************************************************* *******)
CASE step OF

stop:
timer_reidi(in:=FALSE);
fAlarm := Ok;
RTRIG_auto_start(CLK:=auto_start);
step := SEL( SEL( auto, RTRIG_auto_start.Q, man_start), step, start);

start:
timer_reidi(in:= NOT sens_reidi, pt:=T#2s, Q=> fAlarm.xReidi );
RTRIG_auto_stop(CLK:=auto_stop);
step := SEL(man_stop OR RTRIG_auto_stop.Q, step, stop);
step := SEL(fAlarm <> Ok, step, alarm);

alarm :
step := SEL(reset, step, stop);
END_CASE
out := step=start;

swerder
08.09.2011, 16:38
у вас вентили как управляться то должны, импульсом/постоянно?

swerder
08.09.2011, 16:56
вот наверно так

PROGRAM PRG_3
VAR
Stop1 : TP:= ( PT := T#1s);
Start1 : TP:= ( PT := T#1s);
Stop2 : TP:= ( PT := T#1s);
Start2 : TP:= ( PT := T#1s);
Stop3 : TP:= ( PT := T#1s);
Start3 : TP:= ( PT := T#1s);
Stop4 : TP:= ( PT := T#1s);
Start4 : TP:= ( PT := T#1s);
fan: WORD;

Do1: BOOL;
Do2: BOOL;
Do3: BOOL;
Do4: BOOL;
Do5: BOOL;
Do6: BOOL;

setmech : ARRAY[1..4] OF BYTE := 2#0011, 2#0101, 2#0110, 2#0111;
mech : ARRAY[1..4] OF BOOL;
trig1_start: r_trig;
trig1_stop: f_trig;
trig2_start: r_trig;
trig2_stop: f_trig;
trig3_start: r_trig;
trig3_stop: f_trig;
END_VAR

fan:=0;
FOR i :=1 TO 4 DO
fan:=SEL( mech[i], fan, fan OR setmech[i] );
END_FOR

trig1_start(clk := fan.0);
trig1_stop(clk := fan.0);
trig1_start(clk := fan.1);
trig1_stop(clk := fan.1);
trig1_start(clk := fan.2);
trig1_stop(clk := fan.2);

Start1(IN := trig1_start.q, Q => Do1);
Stop1(IN := trig1_stop.q, Q => Do2 );
Start2(IN := trig2_start.q, Q => Do3);
Stop2(IN := trig2_stop.q, Q => Do4);
Start3(IN := trig3_start.q, Q => Do5);
Stop3(IN := trig3_stop.q, Q => Do6);

запуск вентилей секундным импульсом с нечетных выходов, остановка с четных
это если у вас надо подключиться параллельно коробочке включения вентиля с 2мя кнопками "вкл и выкл"

swerder
08.09.2011, 18:29
если со входа in этого TP не снять true то он будет продолжать выдавать true на выходе. задание pt = 1s теряет смысл

swerder
08.09.2011, 21:16
да, перепутал, триггеры излишни


Stop1,Start1,
Stop2,Start2,
Stop3,Start3,
Stop4,Start4 : TP:= ( PT := T#1s);
Дося так же хорошо стирает. Зачем платить больше ? :)
дело вкуса, мне больше нравится первый вариант

alexval2006
09.09.2011, 07:56
товарищи яж писал управляем функциональными блоками включения вентиляторов а уже он запускает пускатель суть аналогична обычному пуск стоп толь с защитами и выбором режима автомат ручное

swerder
09.09.2011, 09:46
если надо только управлять блоком из поста 14, то пользуйте решение из #3 привязав
auto_start := vent*;
auto_stop := not vent*;

alexval2006
09.09.2011, 12:43
не рещение валенка полностью устраевает работает на отлично сейча прилажую его к маршутам запуска элеватора

alexval2006
13.09.2011, 13:56
продолжу тему вот прилаживаю к маршрутам ниже переведён код суть такая чтобы маршруты работающие параллельно могли использовать одновременно одни и те же вентиляторы у меня получилось с 16 вентиляторами но мне этого мало хотел сделать на 32 но что то не выходит возможно нельзя в массиве использовать 32битные двоичные числа а только 16битные


FUNCTION_BLOCK set_cul_march_EL
VAR_INPUT
in: WORD;
END_VAR

VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10,
Do11, Do12, Do13, Do14, Do15, Do16, Do17, Do18,
Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32: BOOL;
END_VAR

VAR
Stop1, Start1, Stop2, Start2, Stop3, Start3, Stop4, Start4, Stop5, Start5, Stop6, Start6,
Stop7, Start7, Stop8, Start8, Stop9, Start9, Stop10, Start10, Stop11, Start11, Stop12,
Start12, Stop13, Start13, Stop14, Start14, Stop15, Start15, Stop16, Start16, Stop17,
Start17, Stop18, Start18, Stop19, Start19, Stop20, Start20, Stop21, Start21, Stop22,
Start22, Stop23, Start23, Stop24, Start24, Stop25, Start25, Stop26, Start26, Stop27,
Start27, Stop28, Start28, Stop29, Start29, Stop30, Start30, Stop31, Start31, Stop32,
Start32, Stop33, Start33, Stop34, Start34, Stop35, Start35, Stop36, Start36, Stop37,
Start37, Stop38, Start38, Stop39, Start39, Stop40, Start40, Stop41, Start41, Stop42,
Start42, Stop43, Start43, Stop44, Start44, Stop45, Start45, Stop46, Start46, Stop47,
Start47, Stop48, Start48, Stop49, Start49, Stop50, Start50, Stop51, Start51, Stop52,
Start52, Stop53, Start53, Stop54, Start54, Stop55, Start55, Stop56, Start56, Stop57,
Start57, Stop58, Start58, Stop59, Start59, Stop60, Start60, Stop61, Start61, Stop62,
Start62, Stop63, Start63, Stop64, Start64, Stop65, Start65, Stop66, Start66, Stop67,
Start67, Stop68, Start68, Stop69, Start69, Stop70, Start70, Stop71, Start71, Stop72,
Start72, Stop73, Start73, Stop74, Start74, Stop75, Start75, Stop76, Start76, Stop77,
Start77, Stop78, Start78, Stop79, Start79, Stop80, Start80, Stop81, Start81, Stop82,
Start82, Stop83, Start83, Stop84, Start84, Stop85, Start85, Stop86, Start86, Stop87,
Start87, Stop88, Start88, Stop89, Start89, Stop90, Start90, Stop91, Start91, Stop92,
Start92, Stop93, Start93, Stop94, Start94, Stop95, Start95, Stop96, Start96, Stop97,
Start97, Stop98, Start98, Stop99, Start99, Stop100, Start100, Stop101, Start101,
Stop102, Start102, Stop103, Start103, Stop104, Start104, Stop105, Start105, Stop106,
Start106, Stop107, Start107, Stop108, Start108, Stop109, Start109, Stop110, Start110,
Stop111, Start111, Stop112, Start112, Stop113, Start113, Stop114, Start114, Stop115,
Start115, Stop116, Start116, Stop117, Start117, Stop118, Start118, Stop119, Start119,
Stop120, Start120, Stop121, Start121, Stop122, Start122, Stop123, Start123, Stop124,
Start124, Stop125, Start125, Stop126, Start126, Stop127, Start127, Stop128, Start128,
Stop129, Start129, Stop130, Start130, Stop131, Start131, Stop132, Start132, Stop133,
Start133, Stop134, Start134, Stop135, Start135, Stop136, Start136, Stop137, Start137,
Stop138, Start138, Stop139, Start139, Stop140, Start140, Stop141, Start141, Stop142,
Start142, Stop143, Start143, Stop144, Start144, Stop145, Start145, Stop146, Start146,
Stop147, Start147, Stop148, Start148, Stop149, Start149, Stop150, Start150, Stop151,
Start151, Stop152, Start152, Stop153, Start153, Stop154, Start154, Stop155, Start155,
Stop156, Start156, Stop157, Start157, Stop158, Start158, Stop159, Start159, Stop160,
Start160
:TP:= ( PT := T#2s);

fan: WORD;(*32 bita*)
i: WORD;(*32 bita*)

mech : ARRAY[1..160] OF BOOL;
setmech : ARRAY[1..160] OF BYTE :=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
(*32*)
далее одно и тоже непоказано для экономии места
(*160*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000;
END_VAR
(***********************************************)

fan:=0;
FOR i :=1 TO 160 DO
fan:=SEL( mech[i], fan, fan OR setmech[i] );
END_FOR
(*
mech[0]:=in.0;
mech[1]:=in.1;
mech[2]:=in.2;
mech[3]:=in.3;
*)
Start1(IN := fan.0 OR fan.2, Q =>Do1);
Stop1(IN := NOT fan.0 OR fan.2, Q => Do2);
Start2(IN := fan.1 OR fan.3, Q => Do3);
Stop2(IN := NOT fan.1 OR fan.3, Q => Do4);

swerder
13.09.2011, 14:37
интересно, как вы собираетесь в ворд 32 бита записать?

alexval2006
13.09.2011, 14:46
я менял тип на UDINT материтса меня беспокоит как мне засунь все 160 маршрутов переменная fan даже с типом UDINT это 32 бита

swerder
13.09.2011, 15:28
как матерится? почему даже? переменная фан будет иметь в себе 32 бита только в 3х целочисленных случаях

alexval2006
13.09.2011, 15:39
теперь компилируется теперь нужно только заставить работать как надо


FUNCTION_BLOCK set_cul_march_EL
VAR_INPUT
in: DWORD;
END_VAR

VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10, Do11, Do12, Do13, Do14,
Do15, Do16, Do17, Do18, Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32, Do33, Do34, Do35, Do36, Do37, Do38,
Do39, Do40, Do41, Do42, Do43, Do44, Do45, Do46, Do47, Do48, Do49, Do50,
Do51, Do52, Do53, Do54, Do55, Do56, Do57, Do58, Do59, Do60, Do61, Do62,
Do63, Do64: BOOL;
END_VAR

VAR
Stop1, Start1, Stop2, Start2, Stop3, Start3, Stop4, Start4, Stop5, Start5, Stop6, Start6,
Stop7, Start7, Stop8, Start8, Stop9, Start9, Stop10, Start10, Stop11, Start11, Stop12,
Start12, Stop13, Start13, Stop14, Start14, Stop15, Start15, Stop16, Start16, Stop17,
Start17, Stop18, Start18, Stop19, Start19, Stop20, Start20, Stop21, Start21, Stop22,
Start22, Stop23, Start23, Stop24, Start24, Stop25, Start25, Stop26, Start26, Stop27,
Start27, Stop28, Start28, Stop29, Start29, Stop30, Start30, Stop31, Start31, Stop32,
Start32, Stop33, Start33, Stop34, Start34, Stop35, Start35, Stop36, Start36, Stop37,
Start37, Stop38, Start38, Stop39, Start39, Stop40, Start40, Stop41, Start41, Stop42,
Start42, Stop43, Start43, Stop44, Start44, Stop45, Start45, Stop46, Start46, Stop47,
Start47, Stop48, Start48, Stop49, Start49, Stop50, Start50:TP:= ( PT := T#5s);
Stop51, Start51, Stop52, Start52, Stop53, Start53, Stop54, Start54, Stop55, Start55,
Stop56, Start56, Stop57, Start57, Stop58, Start58, Stop59, Start59, Stop60, Start60,
Stop61, Start61, Stop62, Start62, Stop63, Start63, Stop64, Start64, Stop65, Start65,
Stop66, Start66, Stop67, Start67, Stop68, Start68, Stop69, Start69, Stop70, Start70,
Stop71, Start71, Stop72, Start72, Stop73, Start73, Stop74, Start74, Stop75, Start75,
Stop76, Start76, Stop77, Start77, Stop78, Start78, Stop79, Start79, Stop80, Start80,
Stop81, Start81, Stop82, Start82, Stop83, Start83, Stop84, Start84, Stop85, Start85,
Stop86, Start86, Stop87, Start87, Stop88, Start88, Stop89, Start89, Stop90, Start90,
Stop91, Start91, Stop92, Start92, Stop93, Start93, Stop94, Start94, Stop95, Start95,
Stop96, Start96, Stop97:TP:= ( PT := T#5s);
Start97, Stop98, Start98, Stop99, Start99, Stop100, Start100, Stop101, Start101,
Stop102, Start102, Stop103, Start103, Stop104, Start104, Stop105, Start105, Stop106,
Start106, Stop107, Start107, Stop108, Start108, Stop109, Start109, Stop110, Start110,
Stop111, Start111, Stop112, Start112, Stop113, Start113, Stop114, Start114, Stop115,
Start115, Stop116, Start116, Stop117, Start117, Stop118, Start118, Stop119, Start119,
Stop120, Start120, Stop121, Start121, Stop122, Start122, Stop123, Start123, Stop124,
Start124, Stop125, Start125, Stop126, Start126, Stop127, Start127, Stop128, Start128
:TP:= ( PT := T#5s);
Stop129, Start129, Stop130, Start130, Stop131, Start131, Stop132, Start132, Stop133,
Start133, Stop134, Start134, Stop135, Start135, Stop136, Start136, Stop137, Start137,
Stop138, Start138, Stop139, Start139, Stop140, Start140, Stop141, Start141, Stop142,
Start142, Stop143, Start143, Stop144, Start144, Stop145, Start145, Stop146, Start146,
Stop147, Start147, Stop148, Start148, Stop149, Start149, Stop150, Start150, Stop151,
Start151, Stop152, Start152, Stop153, Start153, Stop154, Start154, Stop155, Start155,
Stop156, Start156, Stop157, Start157, Stop158, Start158, Stop159, Start159, Stop160,
Start160:TP:= ( PT := T#5s);

fan: DWORD;(*32 bita*)
i: DWORD;(*32 bita*)

mech : ARRAY[1..160] OF BOOL;
setmech : ARRAY[1..160] OF BYTE :=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
остальные одинаковы непоказаны
(*160*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000;
END_VAR
(************************************************* ***)
fan:=0;
FOR i :=1 TO 160 DO
fan:=SEL( mech[i], fan, fan OR setmech[i] );
END_FOR

mech[1]:=in.0;
mech[2]:=in.1;
mech[3]:=in.2;
mech[4]:=in.3;

Start1(IN := fan.0 OR fan.2, Q =>Do1);
Stop1(IN := NOT fan.0 OR fan.2, Q => Do2);
Start2(IN := fan.1 OR fan.3, Q => Do3);
Stop2(IN := NOT fan.1 OR fan.3, Q => Do4);

alexval2006
14.09.2011, 08:55
так не компилируется Do1..Do64 : BOOL; пришлось по старинке писать

материтса на Fan:ARRAY[0..31] OF TFan:=(PT:=T#5s);
неверное начальное значение и неизвестный тип массива
ошибки 3760, 3740


FUNCTION_BLOCK TFans32
VAR_INPUT
(*Если на вход можно массив пихнуть, то даже проще.*)
Di1, Di2, Di3, Di4, Di5, Di6, Di7, Di8, Di9, Di10, Di11, Di12, Di13, Di14,
Di15, Di16, Di17, Di18, Di19, Di20, Di21, Di22, Di23, Di24, Di25, Di26,
Di27, Di28, Di29, Di30, Di31, Di32, Di33, Di34, Di35, Di36, Di37, Di38,
Di39, Di40, Di41, Di42, Di43, Di44, Di45, Di46, Di47, Di48, Di49, Di50,
Di51, Di52, Di53, Di54, Di55, Di56, Di57, Di58, Di59, Di60, Di61, Di62,
Di63, Di64: BOOL;
Di65, Di66, Di67, Di68, Di69, Di70, Di71, Di72, Di73, Di74, Di75, Di76,
Di77, Di78, Di79, Di80, Di81, Di82, Di83, Di84, Di85, Di86, Di87, Di88,
Di89, Di90, Di91, Di92, Di93, Di94, Di95, Di96, Di97, Di98, Di99, Di100,
Di101, Di102, Di103, Di104, Di105, Di106, Di107, Di108, Di109, Di110,
Di111, Di112, Di113, Di114, Di115, Di116, Di117, Di118, Di119, Di120,
Di121, Di122, Di123, Di124, Di125, Di126, Di127, Di128: BOOL;
Di129, Di130, Di131, Di132, Di133, Di134, Di135, Di136, Di137, Di138,
Di139, Di140, Di141, Di142, Di143, Di144, Di145, Di146, Di147, Di148,
Di149, Di150, Di151, Di152, Di153, Di154, Di155, Di156, Di157, Di158,
Di159, Di160: BOOL;
END_VAR
VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10, Do11, Do12, Do13, Do14,
Do15, Do16, Do17, Do18, Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32, Do33, Do34, Do35, Do36, Do37, Do38,
Do39, Do40, Do41, Do42, Do43, Do44, Do45, Do46, Do47, Do48, Do49, Do50,
Do51, Do52, Do53, Do54, Do55, Do56, Do57, Do58, Do59, Do60, Do61, Do62,
Do63, Do64: BOOL;
END_VAR
VAR
Set:ARRAY[1..160] OF DWORD:=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
(*32*)
..................................................
(*160*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
2#00000000000000000000000000000000;

Fan:ARRAY[0..31] OF TFan:=(PT:=T#5s);
i:INT;
State: DWORD;
PDi, PStart, PStop:POINTER TO BOOL;
END_VAR
(*******************************************)
State:=0;
PDi:=ADR(Di1);
FOR i:=1 TO 160 DO
State:= SEL(PDi^,State,State OR Set[i);
PDi:=PDi+1;
END_FOR

PStart:=ADR(Do1);
PStop:=ADR(Do2);
FOR i:=0 TO 31 DO
Fan[i](
State:=EXTRACT(State,i),
Start=> PStart^,
Stop=>PStop^
);
PStart:=PStart+2;
PStop:=PStop+2;
END_FOR

swerder
14.09.2011, 10:36
Fan: ARRAY[0..31] OF TFan := (PT := T#5s);
у меня тоже на это не матерится, может просто не сделали первый ФБ?

alexval2006
14.09.2011, 11:05
изменил строку на Fan:ARRAY[0..31] OF TFan; осталась только одна ошибка неизвестный тип массива. еще скобка квадратная на одном массиве отсутствовала добавил а как сунуть это немного не понял
Fan[i](
PT := T#?, //при вызове пихнете PT
..
);


FUNCTION_BLOCK TFans32
VAR_INPUT
(*Если на вход можно массив пихнуть, то даже проще.*)
Di1, Di2, Di3, Di4, Di5, Di6, Di7, Di8, Di9, Di10, Di11, Di12, Di13, Di14,
Di15, Di16, Di17, Di18, Di19, Di20, Di21, Di22, Di23, Di24, Di25, Di26,
Di27, Di28, Di29, Di30, Di31, Di32, Di33, Di34, Di35, Di36, Di37, Di38,
Di39, Di40, Di41, Di42, Di43, Di44, Di45, Di46, Di47, Di48, Di49, Di50,
Di51, Di52, Di53, Di54, Di55, Di56, Di57, Di58, Di59, Di60, Di61, Di62,
Di63, Di64: BOOL;
Di65, Di66, Di67, Di68, Di69, Di70, Di71, Di72, Di73, Di74, Di75, Di76,
Di77, Di78, Di79, Di80, Di81, Di82, Di83, Di84, Di85, Di86, Di87, Di88,
Di89, Di90, Di91, Di92, Di93, Di94, Di95, Di96, Di97, Di98, Di99, Di100,
Di101, Di102, Di103, Di104, Di105, Di106, Di107, Di108, Di109, Di110,
Di111, Di112, Di113, Di114, Di115, Di116, Di117, Di118, Di119, Di120,
Di121, Di122, Di123, Di124, Di125, Di126, Di127, Di128: BOOL;
Di129, Di130, Di131, Di132, Di133, Di134, Di135, Di136, Di137, Di138,
Di139, Di140, Di141, Di142, Di143, Di144, Di145, Di146, Di147, Di148,
Di149, Di150, Di151, Di152, Di153, Di154, Di155, Di156, Di157, Di158,
Di159, Di160: BOOL;
END_VAR
VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10, Do11, Do12, Do13, Do14,
Do15, Do16, Do17, Do18, Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32, Do33, Do34, Do35, Do36, Do37, Do38,
Do39, Do40, Do41, Do42, Do43, Do44, Do45, Do46, Do47, Do48, Do49, Do50,
Do51, Do52, Do53, Do54, Do55, Do56, Do57, Do58, Do59, Do60, Do61, Do62,
Do63, Do64: BOOL;
END_VAR
VAR
Set:ARRAY[1..160] OF DWORD:=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
.................................................. ................
2#00000000000000000000000000000000;

Fan:ARRAY[0..31] OF TFan;

i:INT;
State: DWORD;
PDi, PStart, PStop:POINTER TO BOOL;
END_VAR
(***********************************************)
State:=0;
PDi:=ADR(Di1);
FOR i:=1 TO 160 DO
State:= SEL(PDi^,State,State OR Set[i]);
PDi:=PDi+1;
END_FOR

PStart:=ADR(Do1);
PStop:=ADR(Do2);
FOR i:=0 TO 31 DO
Fan[i](
State:=EXTRACT(State,i),
Start=> PStart^,
Stop=>PStop^
);
PStart:=PStart+2;
PStop:=PStop+2;
END_FOR

swerder
14.09.2011, 11:12
вы создали ФБ TFan?
при вызове блока тфанс32 пропишете необходимое значение входа pt

alexval2006
14.09.2011, 13:34
вы создали ФБ TFan?
при вызове блока тфанс32 пропишете необходимое значение входа pt что то его невидно

да всё объявил вызвал
Почему у этого массива Fan:ARRAY[0..31] OF TFan; вместо базового типа написано TFan возможно в этом ошибка? может надо так Fan:ARRAY[0..31] OF INT; ? тогда ругаетса на это
Fan[i](
State:=EXTRACT(State,i),
Start=> PStart^,
Stop=>PStop^
); вызывать можно только экземпляр функционального блока


FUNCTION_BLOCK TFans32
VAR_INPUT
PT:TIME;
(*Если на вход можно массив пихнуть, то даже проще.*)
Di1, Di2, Di3, Di4, Di5, Di6, Di7, Di8, Di9, Di10, Di11, Di12, Di13, Di14,
Di15, Di16, Di17, Di18, Di19, Di20, Di21, Di22, Di23, Di24, Di25, Di26,
Di27, Di28, Di29, Di30, Di31, Di32, Di33, Di34, Di35, Di36, Di37, Di38,
Di39, Di40, Di41, Di42, Di43, Di44, Di45, Di46, Di47, Di48, Di49, Di50,
Di51, Di52, Di53, Di54, Di55, Di56, Di57, Di58, Di59, Di60, Di61, Di62,
Di63, Di64: BOOL;

Di65, Di66, Di67, Di68, Di69, Di70, Di71, Di72, Di73, Di74, Di75, Di76,
Di77, Di78, Di79, Di80, Di81, Di82, Di83, Di84, Di85, Di86, Di87, Di88,
Di89, Di90, Di91, Di92, Di93, Di94, Di95, Di96, Di97, Di98, Di99, Di100,
Di101, Di102, Di103, Di104, Di105, Di106, Di107, Di108, Di109, Di110,
Di111, Di112, Di113, Di114, Di115, Di116, Di117, Di118, Di119, Di120,
Di121, Di122, Di123, Di124, Di125, Di126, Di127, Di128: BOOL;
Di129, Di130, Di131, Di132, Di133, Di134, Di135, Di136, Di137, Di138,
Di139, Di140, Di141, Di142, Di143, Di144, Di145, Di146, Di147, Di148,
Di149, Di150, Di151, Di152, Di153, Di154, Di155, Di156, Di157, Di158,
Di159, Di160: BOOL;
END_VAR
VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10, Do11, Do12, Do13, Do14,
Do15, Do16, Do17, Do18, Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32, Do33, Do34, Do35, Do36, Do37, Do38,
Do39, Do40, Do41, Do42, Do43, Do44, Do45, Do46, Do47, Do48, Do49, Do50,
Do51, Do52, Do53, Do54, Do55, Do56, Do57, Do58, Do59, Do60, Do61, Do62,
Do63, Do64: BOOL;
END_VAR
VAR
Set:ARRAY[1..160] OF DWORD:=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
.................................................. ...........
2#00000000000000000000000000000000;

Fan:ARRAY[0..31] OF TFan;
i:INT;
State: DWORD;
PDi, PStart, PStop:POINTER TO BOOL;
tStart, tStop:TP;
END_VAR
(*******************************************)
State:=0;
PDi:=ADR(Di1);
FOR i:=1 TO 160 DO
State:= SEL(PDi^,State,State OR Set[i]);
PDi:=PDi+1;
END_FOR

PStart:=ADR(Do1);
PStop:=ADR(Do2);
FOR i:=0 TO 31 DO
Fan[i](
State:=EXTRACT(State,i),
Start=> PStart^,
Stop=>PStop^
);
PStart:=PStart+2;
PStop:=PStop+2;
END_FOR

swerder
14.09.2011, 14:40
вы создали ФБ TFan?



да всё объявил вызвал


в итоге имеем что имеем - никаких ФБ TFan не создано, но мы продолжаем утверждать что КДС виноват...

Филоненко Владислав
14.09.2011, 14:50
Fan:ARRAY[0..31] OF TFan;
TFAN - это тип или экземпляр. Должен быть тип

alexval2006
14.09.2011, 14:58
был неправ не понял что нужно создать два Фб создал TFan
но сейчас ругаться вот на что ошибка 4012 несоответствие параметра N в EXTRACT невозможно преобразовать INT в BYTE.



FUNCTION_BLOCK TFan
VAR_INPUT
State:BOOL;
PT:TIME;
END_VAR
VAR_OUTPUT
Start,Stop:BOOL;
END_VAR
VAR
tStart,tStop:TP;
END_VAR
(*************************)
tStart(IN:=State,PT:=PT,Q=>Start);
tStop(IN:=NOT State,PT:=PT,Q=>Stop);




FUNCTION_BLOCK TFans32
VAR_INPUT
(*Если на вход можно массив пихнуть, то даже проще.*)
Di1, Di2, Di3, Di4, Di5, Di6, Di7, Di8, Di9, Di10, Di11, Di12, Di13, Di14,
Di15, Di16, Di17, Di18, Di19, Di20, Di21, Di22, Di23, Di24, Di25, Di26,
Di27, Di28, Di29, Di30, Di31, Di32, Di33, Di34, Di35, Di36, Di37, Di38,
Di39, Di40, Di41, Di42, Di43, Di44, Di45, Di46, Di47, Di48, Di49, Di50,
Di51, Di52, Di53, Di54, Di55, Di56, Di57, Di58, Di59, Di60, Di61, Di62,
Di63, Di64: BOOL;

Di65, Di66, Di67, Di68, Di69, Di70, Di71, Di72, Di73, Di74, Di75, Di76,
Di77, Di78, Di79, Di80, Di81, Di82, Di83, Di84, Di85, Di86, Di87, Di88,
Di89, Di90, Di91, Di92, Di93, Di94, Di95, Di96, Di97, Di98, Di99, Di100,
Di101, Di102, Di103, Di104, Di105, Di106, Di107, Di108, Di109, Di110,
Di111, Di112, Di113, Di114, Di115, Di116, Di117, Di118, Di119, Di120,
Di121, Di122, Di123, Di124, Di125, Di126, Di127, Di128: BOOL;
Di129, Di130, Di131, Di132, Di133, Di134, Di135, Di136, Di137, Di138,
Di139, Di140, Di141, Di142, Di143, Di144, Di145, Di146, Di147, Di148,
Di149, Di150, Di151, Di152, Di153, Di154, Di155, Di156, Di157, Di158,
Di159, Di160: BOOL;
END_VAR
VAR_OUTPUT
Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do8, Do9, Do10, Do11, Do12, Do13, Do14,
Do15, Do16, Do17, Do18, Do19, Do20, Do21, Do22, Do23, Do24, Do25, Do26,
Do27, Do28, Do29, Do30, Do31, Do32, Do33, Do34, Do35, Do36, Do37, Do38,
Do39, Do40, Do41, Do42, Do43, Do44, Do45, Do46, Do47, Do48, Do49, Do50,
Do51, Do52, Do53, Do54, Do55, Do56, Do57, Do58, Do59, Do60, Do61, Do62,
Do63, Do64: BOOL;
END_VAR
VAR
Set:ARRAY[1..160] OF DWORD:=
(*В этом массиве хранитса состояние вентиляторов
для каждого из 160 маршрутов норий №1-4*)
(*16*)
2#00000000000000000000000000000000,
2#00000000000000000000000000000000,
.................................................. ..............
2#00000000000000000000000000000000;

Fan:ARRAY[0..31] OF TFan:=(PT:=T#5s);
i:INT;
State: DWORD;
PDi, PStart, PStop:POINTER TO BOOL;
END_VAR
(***********************************************)
State:=0;
PDi:=ADR(Di1);
FOR i:=1 TO 160 DO
State:= SEL(PDi^,State,State OR Set[i]);
PDi:=PDi+1;
END_FOR

PStart:=ADR(Do1);
PStop:=ADR(Do2);
FOR i:=0 TO 31 DO
Fan[i](
State:=EXTRACT(State,i),
Start=> PStart^,
Stop=>PStop^
);
PStart:=PStart+2;
PStop:=PStop+2;
END_FOR

Валенок
14.09.2011, 15:27
ну сделайте i типа int.
У Вас всего 160 наборов. Пока еще. :)

alexval2006
14.09.2011, 15:45
ну в обще то уже сделано
i:INT;

Валенок
14.09.2011, 17:52
пардон. byte.

swerder
14.09.2011, 18:06
У Вас всего 160 наборов. Пока еще. :)

пардон. byte.

байта в будущем может и не хватить:)

alexval2006
15.09.2011, 09:32
как то работает не так хоть и скомпилировалось взгляните пожалуйста на проект

swerder
15.09.2011, 09:48
куда конкретно то смотреть? проект не 2+2=4
в FUNCTION_BLOCK TFans32
Set:ARRAY[1..160] OF DWORD:=
все должны быть нулевыми?

alexval2006
15.09.2011, 10:42
Если на входе ФБ TFans32 все сигналы EL1_START1 EL1_START2 и тп в FALSE то на выходах ФБ TFans32 ничего не должно быть а там какая то свето музыка если на входе ФБ TFans32 EL1_START1 или EL1_START2 TRUE тогда выбираем нужный элемент из массива Set:ARRAY[1..160] OF DWORD:= в котором записано состояние 32 вентиляторов нулями и единицами далее необходимо чтобы если маршрут нории №1 EL1_START1 к примеру включил вентиляторы CUL1_AUTO_START и CUL2_AUTO_START а потом запустили маршрут нории №2 EL2_START2 к примеру включил вентиляторы CUL1_AUTO_START, CUL2_AUTO_START и CUL3_AUTO_START поработали немного выключили маршрут нории №2 EL2_START2 он выключил вентилятор CUL3_AUTO_START а вентиляторы CUL1_AUTO_START и CUL2_AUTO_START оставил включёнными потому что они используются маршрутом нории №1 EL1_START1 ну вот как то так оно должно работать.

swerder
15.09.2011, 11:48
Если на входе ФБ TFans32 все сигналы EL1_START1 EL1_START2 и тп в FALSE то на выходах ФБ TFans32 ничего не должно быть а там какая то свето музыка если на входе ФБ TFans32 EL1_START1 или EL1_START2 TRUE тогда выбираем нужный элемент из массива Set:ARRAY[1..160] OF DWORD:= в котором записано состояние 32 вентиляторов нулями и единицами далее необходимо чтобы если маршрут нории №1 EL1_START1 к примеру включил вентиляторы CUL1_AUTO_START и CUL2_AUTO_START а потом запустили маршрут нории №2 EL2_START2 к примеру включил вентиляторы CUL1_AUTO_START, CUL2_AUTO_START и CUL3_AUTO_START поработали немного выключили маршрут нории №2 EL2_START2 он выключил вентилятор CUL3_AUTO_START а вентиляторы CUL1_AUTO_START и CUL2_AUTO_START оставил включёнными потому что они используются маршрутом нории №1 EL1_START1 ну вот как то так оно должно работать.

не могу осилить этот поток сознания без знаков препинания:)
если проще - что-то включает у вас механизм, параллельно ему должны вкл определенные пропеллеры. номера этих определенных пропеллеров прописываются в массиве set. он у вас полностью нулевой. копайте тут.

p.s. напоминает
"Вместе с тем ясно также, что если при наличии А необходимо существует Б, то и при наличии возможности существования А необходима и возможность существования Б. В самом деле, если возможность Б не необходима, то ничто не мешает, чтобы было возможно, что Б не существует. Допустим, что А возможно. Стало быть, если А возможно, то не вытекало бы ничего не возможного, если бы было принято, что А есть. Тогда и Б необходимо есть. Между тем было предположено, что оно невозможно. Допустим, что Б невозможно. Если же невозможно, чтобы Б было, то необходимо, чтобы и А было невозможно. Но ведь А было возможно, значит, и Б. Итак, если А возможно, то и Б будет возможно, если только отношение между ними таково, что при существовании А необходимо существование Б. Стало быть, если при таком отношении между А и Б существование Б невозможно, если А возможно, то значит, А и Б не будут находиться в том отношении, как было принято; и если при наличии возможности А необходима и возможность Б, то, если есть А, необходимо есть и Б. Ибо утверждение, что необходимо, чтобы Б было возможно, если возможно А, означает, что если, когда и каким образом возможно существование А, тогда и таким же образом необходимо и существование Б."

alexval2006
15.09.2011, 13:11
да я выставлял там состояния нужных мне вентиляторов но выходы управляющие вентиляторами самопроизвольно включаются и мигают без какого либо сигнала на входе ФБ TFans32

swerder
15.09.2011, 13:20
скажу глупую вещь - значит в алгоритме где-то косяк

Валенок
15.09.2011, 13:22
Уважаемый alexval2006
Начните с 2 вентиляторов и 2 наборов.
Если предложенный алгоритм будет работать правильно, то вышеприведенное будет работать абсолютно так же.


FUNCTION_BLOCK TFan
...//тоже самое


FUNCTION_BLOCK TFans2
VAR_INPUT
Di1,Di2:BOOL; //!!кол-во выходов=CNTSET
END_VAR
VAR_OUTPUT
Do1,Do2,Do3,Do4 : BOOL; //!!кол-во выходов=CNTFAN*2
END_VAR
VAR_CONST
CNTSET:byte:=2;
CNTFAN:byte:=2;
END_VAR
VAR
Set:ARRAY[1..CNTSET] OF DWORD:= 2#??, 2#?? // 2 набора
Fan:ARRAY[1..CNTFAN] OF TFan;
i:byte;
State: DWORD;
PDi,PStart,PStop:POINTER TO BOOL;
END_VAR
*************
State:=0;
PDi:=ADR(Di1);
FOR i:=1 TO CNTSET DO
State:= SEL(PDi^,State,State OR Set[i]);
PDi:=PDi+1;
END_FOR


PStart:=ADR(Do1);
PStop:=ADR(Do2);
FOR i:=1 TO CNTFAN DO
Fan[i](
PT:=T#5s,
State:=EXTRACT(State,i-1),
Start=> PStart^,
Stop=>PStop^
);
PStart:=PStart+2;
PStop:=PStop+2;
END_FOR


Так вообще надо ?
Откуда берутся 160 входов ?

alexval2006
15.09.2011, 14:19
есть 4 механизма нории у каждого есть определенное количество маршрутов например EL1_START1 - EL1_START36 EL2_START1 - EL2_START54 и тп общее количество всех маршрутов 160штук в разных маршрутах участвует разные механизмы и разные вентиляторы при этом одни и те же вентиляторы могут использоваться одновременно в маршрутах двух механизмов к примеру EL1_START1 и EL2_START3 то есть 1й маршрут нории №1 и 3й маршрут нории №2

swerder
15.09.2011, 14:36
есть 4 механизма ... общее количество всех маршрутов 160штук

чувствуется отлаживать код вы будете несколько месяцев
действительно, начните с малого, разберитесь в алгоритме тов. Валенка на примере 2х устройств. когда поймете для чего каждая запятая, переходите на ваши 160 штук

alexval2006
15.09.2011, 14:39
все нормально, огромное спасибо товарищу Валенку то что доктор прописал. Абсолютно точно уловили смысл того что мне было нужно. Теперь просто увеличу значения констант и получаю нужное количество входов и выходов красота.

Валенок
15.09.2011, 17:03
За спасибо - спасибо.
Откуда 160 входов физически берется ? :eek:
И куда 64 выхода физически улетает ?
Может передать указатели на массивы и их размеры ?

просто увеличу значения констант
Аккуратно, если будете вручную набивать Di/о ;)

alexval2006
16.09.2011, 08:46
Откуда 160 входов физически берется ?
И куда 64 выхода физически улетает ?
Ну попробую объяснить еще раз. Есть 4 основных механизма нории (вертикальные транспортёры) с каждым из них может работать любой механизм элеватора то есть ленточные транспортеры перекидные клапана и задвижки допустим зерно поступает с авто приёма по ленточному транспортёру №1 через перекидной клапан №4 на норию №1 далее через перекидной клапан №1 на поворотный круг №1 далее на ленточный транспортер №15 и с него в силос №256 вот это пример одного маршрута также с маршрутом включаться соответствующие вентиляторы аспирации. В зависимости от маршрута выбранного в данный момент могут меняться механизмы используемые в нем допустим если будем брать с жд приемки то номер начального транспортера поменяться на 9 ну или сыпать на другой верхний транспортер например тр №12 чтобы попасть в другой силос нория являвшийся основным механизмом вокруг которого собирается маршрут. Маршрутов у нории много например у нории №2 их 54 штуки сигналы к запуску аспирации это программные переменённые говорящие о запуске выбранного маршрута у нории №2 это EL2_START1-EL2_START54. Ну а выходы это вентиляторы их довольно много на этажах с 1 по 3 их 17 штук на этажах с 4-8 их 20 штук почему 32 выхода а не 20 или 17 запас на расширение позже думают добавить несколько штук вентиляторов ну как то так.
Да ещё одновременно могут работать до 4х маршрутов потому что нории всего 4 штуки.

Может передать указатели на массивы и их размеры ? какие это даст преимущества?


Аккуратно, если будете вручную набивать Di/о всё уже работает

Валенок
16.09.2011, 12:58
Ну попробую объяснить еще раз..
Извините - не догоняю.

Так ? :

1.Есть N (4) норий
Как они включаются ?
Нории автономны друг от друга ?


2.Есть M (32) вентиляторов (?)
Пуск/стоп - раздельные импульсы.
Нужен режим авто(см.ниже) и ручной.


3.Для каждой нории есть набор маршрутов из K (160) вариантов (?)
Как активируются маршруты ? В каком порядке ?


4.Каждый маршрут - это список необходимых ему вентиляторов (?)
Есть обратная связь по аварии от вентиляторов ? Аварийные действия ?
Где и как расположены физические реле для пуска/стопа вентиляторов ?


Наборы маршрутов и списки вентиляторов - оперативные ?

alexval2006
16.09.2011, 15:30
1.Есть N (4) норий
Как они включаются ?
Нории автономны друг от друга ?

Нории автономны друг от друга это 4 отдельных механизма (вертикальных транспортёра)
включаться они функциональным блоком кстати к созданию которого вы приложили свою руку


FUNCTION_BLOCK EL (* Управление Норией *)
VAR_INPUT
auto : BOOL; (* Автоматический режим работы *)
man_start,
man_stop : BOOL; (* Экранные кнопки СТАРТ и СТОП *)
auto_start,
auto_stop : BOOL; (* Сигналы в режиме автомат СТАРТ и СТОП *)
sens_reidi : BOOL; (* Включение (обратная связь ?) *)
sens_sped : BOOL; (* Контроль скорости *)
sens_podpor : BOOL; (* Подпор продуктом *)
sens_tok : BOOL; (* Контроль токовой нагрузки электродвигателя *)
reset : BOOL; (* Сигнал сброса аварии *)
time_sped : TIME; (* уставка времени для таймера аварии скорости механизма *)
time_podpor : TIME; (* уставка времени для таймера аварии подпора механизма *)
END_VAR
VAR_OUTPUT
out : BOOL; (* Выходы на пускатель *)
fAlarm : WORD; (* Флаг аварий *)
END_VAR
VAR
step : (stop, start, alarm); (* Состояние управляющего процесса *)
timer_reidi : TON; (* Контроль включения *)
timer_sped : TON; (* Контроль скорости *)
timer_podpor : TON; (* Контроль по подпору продуктом *)
RTRIG_auto_start: R_TRIG;
RTRIG_auto_stop: R_TRIG;
END_VAR
(*********************************************)
CASE step OF

stop:
timer_reidi(in:=FALSE);
timer_sped(in:=FALSE);
timer_podpor(in:=FALSE);
fAlarm := Ok;
RTRIG_auto_start(CLK:=auto_start);
step := SEL( SEL( auto, RTRIG_auto_start.Q, man_start), step, start);

start:
timer_reidi(in:= NOT sens_reidi, pt:=T#1s, Q=> fAlarm.xReidi );
timer_sped(in:=NOT sens_sped, pt:=time_sped, Q=> fAlarm.xSped );
timer_podpor(in:=sens_podpor, pt:=time_podpor, Q=> fAlarm.xPodpor );
fAlarm.xTok := sens_tok;
RTRIG_auto_stop(CLK:=auto_stop);
step := SEL(man_stop OR RTRIG_auto_stop.Q, step, stop);
step := SEL(fAlarm <> Ok, step, alarm);

alarm :
step := SEL(reset AND NOT sens_tok, step, stop);
END_CASE
out := step=start;




2.Есть M (32) вентиляторов (?)
Пуск/стоп - раздельные импульсы.
Нужен режим авто(см.ниже) и ручной.

опять же функциональный блок


FUNCTION_BLOCK CULER (*Функциональный блок для управления ВЕНТИЛЯТОРОМ*)
VAR_INPUT
auto : BOOL; (* Автоматический режим работы *)
man_start,
man_stop : BOOL; (* Экранные кнопки СТАРТ и СТОП *)
auto_start,
auto_stop : BOOL; (* Сигналы в режиме автомат СТАРТ и СТОП *)
sens_reidi : BOOL; (* Включение (обратная связь ?) *)
reset : BOOL; (* Сигнал сброса аварии *)
END_VAR
VAR_OUTPUT
out : BOOL; (* Выходы на пускатель *)
fAlarm : WORD; (* Флаг аварий *)
RTRIG_auto_start: R_TRIG;
RTRIG_auto_stop: R_TRIG;
END_VAR
VAR
step : (stop, start, alarm); (* Состояние управляющего процесса *)
timer_reidi : TON; (* Контроль включения *)
END_VAR
(***********************************)
CASE step OF

stop:
timer_reidi(in:=FALSE);
fAlarm := Ok;
RTRIG_auto_start(CLK:=auto_start);
step := SEL( SEL( auto, RTRIG_auto_start.Q, man_start), step, start);

start:
timer_reidi(in:= NOT sens_reidi, pt:=T#2s, Q=> fAlarm.xReidi );
RTRIG_auto_stop(CLK:=auto_stop);
step := SEL(man_stop OR RTRIG_auto_stop.Q, step, stop);
step := SEL(fAlarm <> Ok, step, alarm);

alarm :
step := SEL(reset, step, stop);
END_CASE
out := step=start;

а фб уже даёт команду на модули Вывода и получает информацию о механизме из модулей ввода все режимы ручной автомат есть в ФБ.


3.Для каждой нории есть набор маршрутов из K (160) вариантов (?)
Как активируются маршруты ? В каком порядке ?
Немного не так в массиве лежат варианты для всех норий для каждой свои



(*нория №1-1*)
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
2#00000000000000000001000000000001,
(*нория №1-11*)
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,
2#00000000000000000001000000001000,


(*нория №2-1*)
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
2#00000000000000000010000000000001,
(*нория №2-19*)
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,
2#00000000000000000010000000000010,


маршруты запускаться из скады. В скаде выбираем нужный маршрут из выпадающего списка в результате получаем его номер и отправляем его в ПЛК там он попадает в программу обработки маршрутов там смотрим какой нории это маршрут и по cese выбираем нужный псле того как получили сигнал старт маршрута из скады запускаем маршрут после предпускового сигнала.



4.Каждый маршрут - это список необходимых ему вентиляторов (?)
Есть обратная связь по аварии от вентиляторов ? Аварийные действия ?
Где и как расположены физические реле для пуска/стопа вентиляторов ?

каждый маршрут это не только список вентиляторов но и список транспортеров перекидных клапанов и задвижек.
По аварии есть обратные связи их обрабатывает Фб вентилятора приводил выше

реле расположены в щитовых на этажах ими управляют модули вывода му110-16к сигнал о работе собирают модули ввода мв110-16дн

Валенок
17.09.2011, 10:03
Итак.
Оператор и не слыхивал о нориях,вентиляторах,клапанах...
Оператор выбирает Маршрут из списка возможных и передает его на обработку.
?

PS
Не смотрю в существующий проект чтобы чаша осталась пустой..

alexval2006
17.09.2011, 20:53
ну оператор слыхал о всех этих механизмах там есть ведь и ручной режим
а в автомате выбирает маршрут из списка для каждой нории. Там 4 выпадающих списка для каждой нории свой. выбрал маршрут нажал старт далее плк запускает все что положено по программе

Валенок
17.09.2011, 21:25
ну оператор слыхал о всех этих механизмах там есть ведь и ручной режим
Часто о существовании чего-нить мы узнаем тогда, когда оно сломалось.
У нас идеальные неломающиеся устройства (вентиляторы и др..)
Мы ничего не знаем о них. Работают - и ладно.


1.

В скаде выбираем нужный маршрут из выпадающего списка ...и отправляем его в ПЛК .... там смотрим какой нории это маршрут

2.

выбирает маршрут из списка для каждой нории. Там 4 выпадающих списка для каждой нории свой.
1. несколько отличается от 2.

Чуется что все-таки 2 ?

alexval2006
18.09.2011, 12:43
ну возможно первый раз я немного не корректно сформулировал свою мысль но я думаю мне можно простить это маленькое прегрешение я все таки начинающий.

Валенок
18.09.2011, 18:57
начинающий - за 10000 строк. :) Я за жисть столько не писал.

Я туплю, и потому хочу лишь атомизировать задачу. Свести ее к простым безусловным утверждениям.

Итак (снова)

1.Есть 4 девайса (далее - Нории)

2.Для каждой есть свой набор задач (далее Маршрутов)

3.Кол-во Маршрутов в наборах - побоку

4.Содержимое Маршрута - побоку

5.То что сейчас, в ПЛК, наборы сложены в один непрерывный массив - это просто удобство хранения, т.е. в принципе это могут быть и разные массивы

6.Каждая Нория, в один момент времени, может выполнять только один Маршрут (занята/незанята)

7.Оператор может в любое время, для любой незанятой Нории, выбрать любой Маршрут из её собственного набора, и передать его ей для исполнения

?

alexval2006
19.09.2011, 07:59
вы абсолютно правы.

Валенок
19.09.2011, 10:10
Небольшое отвлечение.
От чего зависит выбор маршрута оператором ?
[от балды/от погоды/...]

8.Результат или факт исполнения Маршрута [является/не является] какой-либо автоматической командой.
(Не является - Нория исполнила Маршрут, сказала об этом оператору, и прилегла на диван)
(Является - активирует другой Маршрут/включает мультики...)
?

9.Что есть Маршрут ?
Указание для включения (по окончании - выключения) :
9.1 Группы устройств А (далее Вентиляторы)
9.1.1 Все вентиляторы включаются на все время исполнения Маршрута.
9.2 Группы устройств Б (...какие-то клапана..)
9.3 Группы устройств В (...какие-то ..)
9.4 .....


10.1 Вентилятор включается раздельными импульсами ПУСК и СТОП
Отвлечение - почему ? [патамучтотакполучилось/..]
10.2 Работающий Вентилятор может одновременно обслуживать несколько Маршрутов.

alexval2006
19.09.2011, 13:23
Небольшое отвлечение.
От чего зависит выбор маршрута оператором ?
[от балды/от погоды/...]

Выбор зависит от производственного процесса смотря в какой бункер нужно подать продукт из этого расчёта выбирается тот или другой маршрут к примеру 101 бункер по транспортёру №12 а 303 бункер по транспортёру №15 и т.п.


8.Результат или факт исполнения Маршрута [является/не является] какой-либо автоматической командой.
(Не является - Нория исполнила Маршрут, сказала об этом оператору, и прилегла на диван)
(Является - активирует другой Маршрут/включает мультики...)
?

если маршрут готов к исполнению и механизмы участвующие в нем не задействованы негде и не находиться в аварийном состояние то маршрут запускается и дает индикацию в скаду в виде мнемолампы маршрут нории №1 ВКЛ. В случаее аварии во время работы маршрута все останавливаться и выводиться индикация об аварии маршрута.


9.Что есть Маршрут ?
Указание для включения (по окончании - выключения) :
9.1 Группы устройств А (далее Вентиляторы)
9.1.1 Все вентиляторы включаются на все время исполнения Маршрута.
9.2 Группы устройств Б (...какие-то клапана..)
9.3 Группы устройств В (...какие-то ..)
9.4 .....

Маршрут это совокупность механизмов которые запускаютса совместно с главным маршруто образующим механизмом у нас это нория. В маршрут входят Транспортеры, перекидные клапана и задвижки, вентиляторы, нория, поворотный круг. Вентиляторы должны работать на протяжении работы всего маршрута потому что это аспирация (обеспыливание) задохнуться можно там короче. Все механизмы выключаться по нажатию кнопки стоп маршрута в порядке от начала маршрута к концу с временем зачистки каждого механизма для удаления продукта с механизма.


10.1 Вентилятор включается раздельными импульсами ПУСК и СТОП
Отвлечение - почему ? [патамучтотакполучилось/..]
10.2 Работающий Вентилятор может одновременно обслуживать несколько Маршрутов.

10,1 это необходимо чтобы управлять ФБ вентилятора в ручном режиме это кнопки из скады в автомате это команды из программы.
10,2 Работающий вентилятор может использоваться одновременно с норией №3 и №4 для примера или с транспортером №5 и №7 а эти транспортёры могут быть задействованы в разных маршрутах одновременно значит и вентилятор также может использоваться с разными маршрутами одновременно.

alexval2006
19.09.2011, 23:11
Ну что же раз вас так заинтересовало устройство элеватора и не довелось в живую наблюдать это то немного теории. Обычный типовой элеватор имеет рабочую башню из 8 этажей и крылья левое и правое в крыльях находятся бункеры (далее силоса, высота 30метров). И так на первом этаже расположены 4 основных рабочих нории которые проходят через всю рабочую башню и подымают продукт на 8й этаж. На нории продукт поступает через перекидные клапана с различных транспортеров есть 4 основных транспортера по два на крыло. На каждый транспортер примерно от 20 до 30 силосов. Еще есть авто приём 3ямы оттуда идут 3 транспортёра и через перекидные клапана сыпят на нории. Также в рабочей башне есть небольшие бункеры высотой примерно 10м для перекачки продукта, хранения отходов и прочих надобностей с электро задвижками. На втором этаже разгром там был цех отходов на 3ем сепараторы (очистка продукта от примесей). На 4м этаже еще 4 основных транспортера по которым ездят тележки которые сыпят продукт в выбранный силос. На 5м этаже поворотные круга 4штуки каждая нория через перекидные клапаны на 8м этаже может сыпать на выбранный круг к примеру 4я нория через клапан ПК3 может сыпать на 3й и 4й круги. Круги вращаясь поворачивают трубу по которой идет продукт на разные трубы которые идут на разные транспортеры или бункера 4го этажа. Ну еще на 1м и 4м этажах примерно по 14 вентиляторов. Да еще есть ЖД приём и ЖД выгрузка.
Обычно оператор принимает зерно в элеватор с авто приёма или жд приёма но может также перегонять из силоса в силос для охлаждения зерно не должно долго лежать без движения гниёт. Почему номера силосов и т.п. 300 а силосов около 150 а бог его знает это ни я придумал там и 1001 силос есть. Почему в маршрутах не участвуют номера силосов а только транспортеры? да потому что так проще если все вариации возможных перемещений учесть выйдет около 150 вариантов а может и больше на норию оператор запутаться. Ну и в довершение на некоторые транспортеры можно выйти с разных норий.

alexval2006
19.09.2011, 23:18
Маршрут это список любых элементов из этих наборов
Основные состояния всех механизмов - свободен/занят/авария
В аварию элемент может перейти в любой момент
Маршрут может запустится только если все его элементы свободны (кроме Вентиляторов - только они могут использоваться совместно ?)
да совместно только вентиляторы


Исполнение Маршрута может быть прервано в любой момент – авария любого элемента/принудительный останов.
Цитата:
Маршрут …запускаются совместно с главным маршруто образующим механизмом..
Сразу всё ?
Да запускается сразу всё


Все механизмы выключаться по нажатию кнопки стоп маршрута
Кто жмет стоп ?
оператор в скаде


в порядке от начала маршрута к концу с временем зачистки каждого механизма для удаления продукта с механизма.
Типа отработка элементами некоторого времени (др.условия?) с передачей разрешения на останов следующему по списку элементу ?да отработка по времени далее стоп отработка следующего потом стоп и тп

Валенок
20.09.2011, 00:33
На LD - это всего несколько строк.
:D :D :D
(Извините Андрей)

Интересная задача.
Релиз оконтуривается. Структура данных что-то решетчатое. Массивы вдоль и списки указателей поперёк. Или наоборот. А обработка данных - сквозные проходы вдоль и поперёк. Думаю как покомпактнее элементы описать. И почеловечнее сами маршруты -например прям текстом : 'Вентилятор#1;Клапан#7,3сек;Транспортер#23,7сек... ' ?? (но не факт)

PS
Эх. Лисп бы.
Покумекаю.Выложу в личку

alexval2006
20.09.2011, 08:48
Вот технологическая схема элеватор и список маршрутов извините схема с фотика.
технологическая схема элеватора (http://alexval2007.ucoz.ru/dowanloads/tekhnologicheskaja_skhema_starogo_ehlevattora.jpg)

SBER
20.09.2011, 19:18
С 2009 года занимаюсь практически исключительно элеваторами, посему имею сказать следующее:
1. Для нормальной работы комплекса необходимо два режима:

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

автоматический - запуск устройств по маршрутам. Запуск должен производится постепенно, начиная с точки высыпания зерна (конца маршрута), на случай если линия стоит с зерном (пьяных операторов никто не отменял). Остановка должна начинаться с начала маршрута, - точкой откуда зерно поступает. Для выгрузки можно завязать на таймер и датчик закрытия задвижки под силосом (надо думать ручной). В случае аварии на маршруте устройства находящиеся перед аварийным должны выключаться, после аварийного выкручиваться по таймеру.

2. Программная индивидуальная блокировка каждого датчика (вращения, подпора, схода ленты) обязательна, т.к. некоторые датчики обязательно сломают, а некоторые и в далекой молодости не работали.

3. Для Биса настоятельно рекомендую сделать блокировку повторного пуска (блокировать на 90с пуск БИСа после его остановки). Слишком часто несознательные граждане пытаются запустить станину БИСа на Луну. Дальше стенки ЗАВа полет пока не продлился, но энтузиасты надежд не теряют.

4. Определится как переключение устройства в режим местного управления должно расцениваться автоматикой.


Маршруты лучше писать не относительно устройств, а относительно точек загрузки/выгрузки зерна (силосов завальной ямы и т.п.). Особенно актуально это если в силосах стоит датчик переполнения, по которому должна отключаться загрузка. Больше внимания уделите технологии процесса, там не так все тривиально как кажется на первый взгляд.

Функциональные блоки для устройств я пишу большей частью на LD (хотя это может привычка, начинал на TWIDO там больше нет ничего), маршруты и PLC_PRG на ST. Массивов не использую, у меня маршруты слишком разные, на одном может 2 устройства быть задействовано, на другом 20. Плюс одновременно может работать до 5 разных маршрутов и полуавтомат каждый контролирует свою линию. Но это на новых элеваторах, на советских технологическая линия проще.

alexval2006
20.09.2011, 21:35
У меня типовой советский 72 года розлива. Датчики подпора по силосам сгнили давно там дузы стояли менять на емкостные накладно руководство не хочет решили поставить подпоры только на тележки то есть там где конкретно загружаетса продукт в данный момент. Автоматических задвижек под силосами нет только индикация (концевики) Если писать конкретно не по механизмам а по силосам слишком много маршрутов выходит на одну норию оператор будет в ужасе будет от 150 и выше а так самое большее 54 самое меньшее 24 по моему. За советы специалиста спасибо учту.
БИСа что это за агрегат у нас вроде такого нет.
Ну и если будет желание поделиться какими то наработками или примерами в области элеваторов буду признателен.

Валенок
21.09.2011, 02:05
Элеваторами вообще не занимался

Кол-во маршрутов - побоку
Кол-во устройств в маршруте - побоку
Кол-во типов устройств - можно прилепить любое
Поведение устройств - как сказали
/////

alexval2006
21.09.2011, 08:22
Выглядит классно.

Релиз б-ки valuiki - 140..150 строк. Можно и поджать.:) а что внутри ?

SBER
21.09.2011, 09:43
Чтобы оператор не сходил с ума надо сделать всю работу за него. Ну и это дружелюбный интерфейс АСУ и все такое.
Остановку маршрута можно привязать к срабатыванию концевика задвижки. Оператор запустил маршрут все машины заработали маршрут в статусе запуска, после открыли ручную задвижку, маршрут переходит в статус работы. Задвижку закрыли маршрут переходит в статус остановки, машины выкручиваются. Запуск и остановка происходит постепенно, а не все машины разом, чтобы сеть не просаживать. Хотя для старых элеваторов это возможно не так актуально, там линии как правило нормальные.
Выкладываю фото как у меня выглядит запуск автоматических маршрутов. Фото прошлогодние нынче все красивше, но принцип формирования маршрутов сохранился.
АСУ осваивается за один день гражданами из колхозов, некоторые компьютер до этого только издали видели.
Для маленьких объектов (до 150 маршрутов) каждый маршрут прописывается отдельно. Для больших объектов маршруты собираются по сегментам, т.е. формируются из секций устройств, каждая секция отдельная подпрограмма (вам такое наверно рано еще:) ).

Примеры программ выкладывать не буду, ибо денег стоят:cool:

Валенок
21.09.2011, 10:24
а что внутри ?
150 строк.:)

Тут коллеги предлагают и пуск сделать поплавней. Надо ? Нивапрос.
Маршрут не надо программировать. Их надо описать. И все. Как - предполагаю что ясно из примера. Это вариант описания, в принципе можно еще как-нить.
Пуск/стоп можно привязать к чему угодно.

На днях аварии прилеплю и ручное управление для вентиляторов. Постараюсь устройства/маршруты научить по-русски разговаривать.

alexval2006
21.09.2011, 10:37
Тут коллеги предлагают и пуск сделать поплавней. Надо ? Нивапрос.конечно желательно если это не слишком сложно.

150 строк.хотелось бы взглянуть для понимания как это работает
Буду с интересом ждать вашей версии всего этого безобразия :)

SBER
21.09.2011, 14:14
На технологической схеме наличествует устройство БИС-100. БИС-100 - это машина предназначенная для вторичной очистки зерна. Представляет из себя вибрирующий стан с набором решет. Ежели его несколько раз включить и выключить не дожидаясь остановки стана, то стан со всеми решетами пытается куда нибудь улететь. Особенно этот аттракцион увлекателен если машина загружена зерном (масса стана больше).
ЗАВ расшифровывается как зерноочистительный автомат воронежский, состоит из комплекса предварительной очистки МПО-50 и БИС-100, в советские годы устанавливался на все элеваторы и пункты зерноочистки. Сейчас ЗАВом по привычке обзывают любой пункт зерноочистки.
Ограничивает движение своими стенами, когда стан БИСа срывает с фиксаторов он закономерно финиширует в стене (правда для такого полета оператору необходимо приложить изрядные усилия и выпить не менее литра водки). К сожалению в наших селениях достаточно граждан способных на такой подвиг.
Вобще сделав АСУ необходимо выпить минимум 0,5 водки и попытаться сломать комплекс, если вам это удалось, автоматику надо переделывать.

swerder
21.09.2011, 14:51
защита от пьяного в стельку дурака? :)

alexval2006
21.09.2011, 21:39
Так значит БИС это сепаратор не знал что они летают у нас ещё не разу не было хотя у нас он не оригинальный, еще в 2003 году выкинули и поставили другие.