первые 4 строки - в раздел объявлений, последнюю - в код программы
Вид для печати
первые 4 строки - в раздел объявлений, последнюю - в код программы
К сообщению от S.A.D
Но не все так просто...эпизодически пытаюсь это делать на протяжении 3-х лет, все больше убеждаюсь, что все-таки, для написания более-менее грамотного проекта нужно очччень! много знать и быть программистом (без базы в этой области ну очень тяжко),... Конечно если нужно включить две лампочки после того как нажата кнопка, можно и без этих знаний обойтись, только зачем тогда ПЛК приобретать и изучать КДС и многое многое другое? можно и обычными реле обойтись. Чтобы освоить программирование ПЛК, нужно, во всяком случае мне, работать над реальными проектами (теорией не обойтись, быстро навевает тоску), желательно без перерывов на другие текущие дела, хорошо бы связаться с лояльными корефеями в этой области которые смогут находить время и желание для разбора Ваших проектов и направления на путь истинный, читать и перечитывать форум!(возможно многое прояснится), вообщем нужно очень много потрудиться и иметь огромное желание ..., но есть один нюанс-стилю программирования( написания исходника в понятном самому и другим людям виде), все-таки кто-то должен учить, этому самостоятельно не натыкаешься, одним задором не обойтись.
Пишу вовсе не для того, чтобы отбить охоту, просто собственный жизненый опыт...
Одна мысль у Вас совершенно правильная - нужна реальная задача.
Для того, чтобы научится программировать надо:
1. Конктретная задача. Первая - желательно не авральная, и не сильно ответственная.
2. Глубокое понимание тех. процесса. Без этого ничего хорошего не выйдет. Это даже важнее, чем классическое прорамерское образование, ИМХО.
3. Время и желание. Без этого все остальное бессмысленно.
Ну и не надо делать сразу монстра. Делайте автоматизацию этапами. Беру один узел, автоматизирую, добиваюсь результата, далее прибавляю второй узел.
Положительных примеров при таком подходе - уйма.
kolyan
если он рабочий то почему переписав его с листа в компьютер он не работет? Зачем нужен такой пример который не объясняет, что мол вот вы всё написали но компилятор выдаёт ошибку, исправляем так-то...
А документацию читать не реально - свихнёшься от голых определений.
Михаил@
Николаев Андрей
реальная задача есть (если бы не было, то мне нафиг не надо это программирование), вот только при попытке её реализации наткнулся на проблему: непонятно как работать с данными аналоговых датчиков(pt100 например). Задал вопрос - люди отправили изучать буквари. В букварях ответа на свои вопросы найти не смог. Полез изучать с нуля простые примеры и прочее, думал может что пойму...
Кстати пример со светофором тоже не получился хотя делал всё как сказано, а компилятор что-то материться непонятное. Да и вообще со всего примера понятно что к чему только в блоке с FBD.(((
короче пошол я, а то только раздражаю походу вас своей тупостью...
УРААААА! Я разобрался)) написал программу на ST(как же всё таки хорошо что он так похож на турбо паскаль)
алгоритм то простенький)) В эмуляторе всё работает как мне надо))
только пока не уверен что правильно состыковал переменные с физическими входами/выходами ПЛК. Как я понял надо в конфигурации ПЛК перед AT какого-либо входа/выхода приписать идентификатор переменной которую мы хотим видеть на этом канале?
Все правильно.
Учтите только, что переменные, которые Вы прописали в конфигурации не должны быть объявлены в программе.
а как же тогда программу писать? Ведь чтобы оперировать этими переменными надо их описать, иначе работать не будет... Не могли бы вы объяснить как так?
Конечно.
Есть 2 варианта работы с переменными:
1. Объявлять в конфигурации ПЛК.
2. Объявлять в программе через МЭК адрес (те самые AT %...). Есть такая строчка в автодеклараторе.
А дальше в программе нажимает е волшебную кнопку F2.
Если переменные объявили в Конфигурации ПЛК - они в глобальных.
всем спасибо за ответы - для порядка объявил все переменные в глобальных, подцепил OPC, мастерскаду - сижу играюсь :D
Правда возник вопрос, как реализовать дистанционное включение/выключение исполнения программы в контроллере. Просто у оператора в скаде должна быть возможность переключаться между автоматическим и ручным (вкл исполнение и выкл соответственно) режимами. Я так понимаю это как-то надо прописать программно и так же посредством переменной типа BOOL включать/выключать программу) щас буду рыть литературу на предмет как это сделать)) Если подскажете буду очень рад))
Дело в том что оператор должен иметь возможность управления только частью обрудования. В то же время например обогрев шкафа управления(на улице будет стоять) должен включаться/выключаться автоматически, без ведома оператора.
есть мысль ввести переменную AUTO_MANUAL и в начале программы проверять в коком она состоянии, если TRUE то перейти на метку 1(и пошла выполняться программа) если FALSE то проскакивает момент исполнения основной части программы и переходит сразу к части обогрева шкафа.
а эту переменную AUTO_MANUAL и будет руками изменять оператор)) Если она FALSE, то можно спокойно вручную управлять оборудованием))
Метод может и тупой но это единственное что я придумал)
хм...очень правильная мысль про авторежим в приоритет...
не могли бы вы подробнее описать как работает ваша идея?
У меня получается такая идея:
IF AUTO_MANUAL=TRUE THEN GOTO <метка1>;
ELSE GOTO <метка2>;
<метка1>
IF SVET<50 THEN A:=TRUE;
ELSE A:=FALSE;
END_IF;
IF SVET<40 THEN B:=TRUE;
ELSE B:=FALSE;
END_IF;
IF SVET<=20 THEN C:=TRUE;
ELSE C:=FALSE;
END_IF;
<метка2>
IF T_SHKAF<3 THEN OBOGREV:=TRUE;
ELSIF T_SHKAF>5 THEN OBOGREV:=FALSE;
END_IF;
не понял как тоже самое сделать только через if без применения меток((
можно ещё сделать через while:
WHILE AUTO_MANUAL=FALSE DO (*выполяется только обогрев пока включён ручной режим*)
IF T_SHKAF<3 THEN OBOGREV:=TRUE;
ELSIF T_SHKAF>5 THEN OBOGREV:=FALSE;
END_IF;
END_WHILE;
IF SVET<50 THEN A:=TRUE; (*исполнение основной программы*)
ELSE A:=FALSE;
END_IF;
IF SVET<40 THEN B:=TRUE;
ELSE B:=FALSE;
END_IF;
IF SVET<=20 THEN C:=TRUE;
ELSE C:=FALSE;
END_IF;
вот зараза))) не даёт специально зациклить через while(((
swerder
в кейсе надо чтоб переменная AUTO_MANUAL была целого типа, а у меня она получается BOOL.
Как сделать чтоб она была целого не могу сообразить, ведь мне этой переменной надо управлять с команды через MasterSCADA.
bool_to_byte пробовали?
пишите прям
case bool_to_byte(AUTO_MANUAL) of
0: ;
1: ;
end_case;
должно работать
if "нет ответа от внешнего мира" or "ошибка обмена с внешним миром" then
делаете то, что Вам нужно...
end_if
Николаев Андрей, краткость - сестра таланта :)
это я понимаю) по видимому это делать через конфигуратор тревог.
Зашёл я туда, задал 2 класса тревог - обрыв связи и ошибка связи, задал действие при возникновении тревог (присвоить соответствующим переменным значение 1) но вот как контроллер то узнает что при обрыве связи надо среагировать по этим двум классам тревог, причём при обрыве на обрыв а при ошибке на ошибку:confused:
у вас же контроллер будет слэйвом?
Получается наверное да. Он конечно будет управлять всем в автомате, но в то же время будет всю информацию передавать в MasterSCADA и если что диспетчер сможет перейти в ручной режим и включать/выключать всё из скады. Так что наверное слейв. ведь 2 мастера не может быть вроде
да, я имел ввиду по отношению к скаде. если организовывать связь со скадой через конфигурацию плк добавляя модуль модбас слейв, то мониторить связь штатными средствами кажется нельзя. надо со скады с некоторой периодичностью перезаписывать один регистр меняющимися значениями. если значения этого регистра в плк не меняются, то ошибка связи.
у меня получается связь со скадой через codesys opc.
не могли бы вы кинуть в меня ссылкой в которой описано как это всё делать с записью регистра, или рассказать подробно? А то я не догоняю что к чему, как его и куда записывать:(
ага... примерно понятно... теперь бы докопаться как это реализовать:D ничего, щас чё нить придумаю)
так... сделал я переодическую запись из скады в переменную SVYAZ_ERROR значений 1 и 2, но вот не могу добиться чтоб при разрыве связи эта переменная стоновилась 0. При разрыве связи со скадой остаётся записаным последнее поступившее значение... Получается условие
IF SVYAZ_ERROR=0 THEN AUTO:=TRUE;
END_IF;
не работает((( если принудительно в начале каждого прогона программы ставить это значение в 0 то она будет всегда сбрасывать в автоматический режим. Что-то я уже незнаю как сделать(( Кто подскажет как при разрыве установить переменную в 0? Тип у неё INT
так... сделал я переодическую запись из скады в переменную SVYAZ_ERROR значений 1 и 2, но вот не могу добиться чтоб при разрыве связи эта переменная стоновилась 0. При разрыве связи со скадой остаётся записаным последнее поступившее значение... Получается условие
IF SVYAZ_ERROR=0 THEN AUTO:=TRUE;
END_IF;
не работает(((
поидее надо сделать
if "svyaz_error не меняется в течение 20 секунд" then auto:=true
end_if
только вот как это записать?
PS: я случайно: хотел отредактировать а получилось почему-то новое
через TOF получается при обрыве связи остаётся записаным последнее пришедшее значение и отсчёт не начинается. Что бы начался надо чтоб это значение сменилось на 0.
единственный выход с TOF на мой взгляд - пульсатор в котором 1 будет длиться скажем 0,01 секунду, а 0 длиться 10 секунд. А время сколько ждать ставим 15 секунд с запасом (в моём случае 15 секунд простоя не критично). В таком случае шанс что обрыв произойдёт на единице есть но мизерный по сравнению с шансом обрыва на нуле.
PS: огромное спасибо за помощь всем кто откликается!!!
см. пост #187
TOFInst(IN := SVYAZ, PT:= T#5s);
MANUAL :=TOFInst.Q;
получается если связь есть то он преводит в ручной и в автомат переключиться вообще не даёт. ФБ так работает: "Если IN равен TRUE, то выход Q = TRUE и выход ET = 0. Как только IN переходит в FALSE, начинается отсчет времени (в миллисекундах) на выходе ET. При достижении заданной длительности отсчет останавливается. Выход Q равен FALSE, если IN равен FALSE и ET равен PT, иначе - TRUE."
Не понимаю как у вас получается через него
вам же написали - на вход in таймера TOF подать "значение_некоторого_регистра = какому-то значению"
tof1(in := значение_некоторого_регистра = какому-то значению", pt := t#10s);
а после таймера обнулять этот регистр
значение_некоторого_регистра := 0;
скадой же слать в этот регистр это самое значение.
спасибо за объяснение, про обнуление дошло - не то обнулял, однако:
TOFInst(IN := BOOL_TO_INT(SVYAZ)=1, PT:= T#10s);
SVYAZ :=0;
на in значение приходит каждые 1,5 секунды, но если связь оборвать то в этом случае по прошествии 10 секунд MANUAL не переходит в состоянии FALSE потому что мы не берём в него значение с выхода Q
TOFInst(IN := BOOL_TO_INT(SVYAZ)=1, PT:= T#10s, Q=>MANUAL);
SVYAZ :=0;
в этом случае по прошествии 10 секунд MANUAL переходит в FALSE, НО каждый раз когда приходит на in со скады значение, Q переводится в TRUE и автомат становится в ручной режим, потому что ФБ так работает.
"Если IN равен TRUE, то выход Q = TRUE. Выход Q равен FALSE, если IN равен FALSE и ET равен PT."
у tof выход q гаснет через время pt после спада входа in
да, но в то же время, q загорается когда приходит вновь значение на in, и тухнет только когда выполняется pt, то есть каждый раз когда приходит со скады значение загорается q а вместе с ним включается ручной режим.
В итоге перевести нашу переменную manual в false мы не можем
вот целиком код программы если поможет:
TOFInst(IN := BOOL_TO_INT(SVYAZ)=1, PT:= T#10s, Q=>MANUAL);
SVYAZ :=0;
CASE BOOL_TO_BYTE(MANUAL) OF
1: IF T_SHKAF<3 THEN OBOGREV:=TRUE; (*только обогрев шкафа если включен ручной режим*)
ELSIF T_SHKAF>5 THEN OBOGREV:=FALSE;
END_IF;
0: IF SVET<50 THEN A:=TRUE; (*исполнение всей программы в автоматическом режиме*)
ELSE A:=FALSE;
END_IF;
IF SVET<40 THEN B:=TRUE;
ELSE B:=FALSE;
END_IF;
IF SVET<=20 THEN C:=TRUE;
ELSE C:=FALSE;
END_IF;
IF T_SHKAF<3 THEN OBOGREV:=TRUE;
ELSIF T_SHKAF>5 THEN OBOGREV:=FALSE;
END_IF;
END_CASE;
CodeSys/PLC_Configuration/PLC... два раза ЛКМ по входу/выходу и прописываете переменную. Не забудьте удалить прописанные переменные из PLC_PRG раздел-объявление переменных
Объясните популярно пожалста, зачем в OPC-Сервере CodeSys вот это окно с именем проекта?
Если нужную программу с конфигом ПЛК и исполнительной частью уже загружена в контроллер и выдает нужные OPC-переменные...