Мне хотелось бы рассказать о своём опыте пусконаладки и разработки промышленного программного обеспечения. При чтении статьи просьба учитывать, что дело происходило почти два года назад, и с того времени уже многое поменялось.
Итак, ранней весной 2014 года я поднялся на третий этаж бетоносмесительного узла одного завода. В моём распоряжении были два планетарных бетоносмесителя фирмы Wiggert, линия адресной подачи Kubat на два монорельса и полностью разбомбленный цех внизу, в который надо было выдавать бетон. В перспективе.
В чём заключался хитрый план? Мы должны были с нуля наладить производство пустотного настила в одном пролёте цеха и стеновых панелей — в другом.
Вот так выглядит пустотный настил в разрезе:
Фото с сайта echo.co.za
Итак, для опробования бетоносмесителя нужно куда-то девать удачно (или не очень) произведённый бетон. Вариант с десятью джамшутами не рассматривался, поэтому нужно подключать адресную подачу (АП). Механическая часть АП включает в себя пару специально обученных шаттлов (кюбелей), катающихся по монорельсу, и бетонораздатчик, управляющийся в полуавтоматическом режиме:
Начинаем вкуривать документацию на Kubat: электрическая часть состоит из центрального шкафа управления на 314-2DP, двух станций ET200S (шаттлы) и CPU 313-2DP IFM (раздатчик), общающихся по Powercom (аналог сименсовского PowerRail, т.е. RS-485 по троллеям 220/380В).
Упс, а вот и первые грабли: исходников ПО нет и не предвидится. Ладно, вскрываем пароли контроллеров специальной утилитой. С раздатчиком всё более-менее нормально, а вот центральный рэк декомпилируется в ядрёную кашу на STL, т.к. большая часть программы написана на SFC непонятно какой версии.
Ладно, не вопрос. Для начала отправляю монтажников прокидывать коммуникации вдоль монорельсов, подключать питание и ставить датчики, сам в это время смотрю схему:
Итак, инвертор фирмы Nord, управляемый по Profibus. В нашем случае используется для питания приводов движения и вращения. Скачиваем документацию, раскуриваем регистры управления и пишем код:
FUNCTION_BLOCK nord_control
VAR_INPUT
cmd:INT; //0 - fast stop
//1 - smooth stop
//2 - run to setpoint
//3 - get info;
FUNCTION_BLOCK nord_control
VAR_INPUT
cmd:INT; //0 - fast stop
//1 - smooth stop
//2 - run to setpoint
//3 - get info;
setpoint:REAL;
hw_addr:INT;
END_VAR
VAR_OUTPUT
state:TNordInfo;
END_VAR
VAR_TEMP
// Temporary Variables
d: ARRAY [0..5] OF WORD;
setpoint1:REAL;
END_VAR
VAR
t:INT;
c: WORD;
s: WORD;
cw AT c: TNord_CW;
sw AT s: TNOrd_SW;
st:WORD;
END_VAR
s:=IW[hw_addr]; //256 257 state word *
state.sw:=sw;
state.act_value1:=INT_TO_REAL(WORD_TO_INT(IW[hw_addr+2]))*50/16384;//258 259
state.act_value2:=INT_TO_REAL(WORD_TO_INT(IW[hw_addr+4]))*50/16384;//260 261
state.act_value3:=INT_TO_REAL(WORD_TO_INT(IW[hw_addr+6]))*50/16384;//262 263
state.w0:=IW[hw_addr+8];//264 265
state.w1:=IW[hw_addr+10];//266 267
// Statement Section
CASE cmd OF
0: c:=0;
cw.ack_err:=TRUE; //SWITCH OFF;
cw.enable_op:=FALSE;
cw.on1:=FALSE;
cw.on2:=FALSE;
cw.on3:=FALSE;
cw.enable_op:=FALSE;
cw.enable_ramp:=FALSE;
cw.unfreeze_ramp:=FALSE;
cw.en_setpoint:=FALSE;
cw.pzd_valid:=FALSE;
setpoint1:=0;
t:=0;
1: cw.on1:=FALSE;
2: setpoint1:=setpoint;
CASE t OF //run to setpoint
0: IF (sw.start_disabled=TRUE) THEN //wait for mains voltage
t:=1;
END_IF;
1: cw.on2:=TRUE; //switch to standby
cw.on3:=TRUE;
cw.enable_op:=TRUE;
cw.enable_ramp:=TRUE;
cw.unfreeze_ramp:=TRUE;
cw.en_setpoint:=TRUE;
cw.pzd_valid:=TRUE;
cw.ack_err:=FALSE;
IF (sw.ready=TRUE) AND //Wait for standby
(sw.no_off2=TRUE) AND
(sw.no_off2=TRUE) THEN //change to no_off3
t:=2;
END_IF;
2: cw.on1:=TRUE;
t:=3;
END_CASE;
END_CASE;
IF cmd<3 THEN //Write data
QW[hw_addr]:=c;
st:=INT_TO_WORD(REAL_TO_INT((setpoint1*16384.0/50.0)));
QW[hw_addr+2]:=INT_TO_WORD(REAL_TO_INT((setpoint1*16384.0/50.0)));
END_IF;
END_FUNCTION_BLOCK
О, кажется шаттл поехал, но, вроде бы, снизу слышны какие-то радостные крики. С матерными воплями монтажники пытаются убежать по подкрановым путям от мчащейся пятитонной железки. Аварийно выключаем питание и делаем перерыв на подсчёт личного состава.
Уже было бы неплохо иметь хоть какую-то визуализацию. ОК, делаем небольшой проектик для тач-панели.
В течении пары недель допиливаю остальную часть программы (тут должна быть картинка про сову), что бы можно было развозить бетон… которого ещё нет.
Тем временем внизу заканчивается бетонирование термостендов и можно расконсервировать линию Echo. Тут всё просто. Или почти просто. Машины простояли под дождём и голубиными фекалиями с 2008 года, вагонетка и слип-формер после заправки маслом и очистки начинают работать нормально, а вот пила накидывает полный экран ошибок и говорит, что никуда не поедет.
Добрые товарищи из дойчланда горят желание помочь, но исключительно за несколько десятков тысяч евро. Рубли не принимают.
Хорошо, скачиваем программу из контроллера, пытаемся понять что ей надо. Всё выглядит так, как будто две оси позиционирования заклинило. В принципе, это не удивительно: силовые модули в двух инверторах выгорели полностью. Хорошо, заказываем новые Emerson Unidrive и, чтобы не терять время, возвращаемся на БСУ для секаса с планетарными бетоносмесителями.
Один Wiggert уже смонтирован, подключён и вроде бы даже опробован. Однако, как всегда, дьявол кроется в мелочах (ну, это, конечно, если не считать крайне кривого подключения воздуха и разводки электрики).
Дозирование инертных идёт хорошо, весело, с погрешность килограмм в 500. Регулирую датчики открытия дозаторов, выставляю величину дозагруза, погрешность уменьшается до 2-10 кг.
Через пару недель приезжают частотники. Ставим их в шкаф, выполняем перенос настроек (да, там ещё есть модули SM-Applications Plus со своими программами) и референцирование осей.
Profit! Можно начинать выпускать продукцию. Конечно, если сначала подобрать состав бетона.
В общем, всё закончилось хэппи эндом и линия благополучно работает по сей день.
Автор: firez