В онлайне код нельзя скопировать. Чё за дурость?
Вид для печати
В онлайне код нельзя скопировать. Чё за дурость?
Что не так? Запрет на копирование кода в онлайне вам кажется естественным?
Имеется ввиду копи или копи-пасте ?
Копи.Цитата:
Имеется ввиду копи или копи-пасте ?
Не делайте вид, будто я роскошь какую-то хочу.Цитата:
так ладно Вам только копирование открой, Вам же после захочется и вставить в онлайн код что нибудь
я правда в этом смысла не вижу
Я зато вижу. Мне надо было скопировать код в другой проект и поиграться с ним. Выяснилось, что для этого я должен разлогиниться, скопировать код, залогиниться, щелкнуть OK на этом чёртовом «PLC STARTED ...» и — самое удручающее — заново выставить принудительные значения (force) на дюжине переменных (нет, я не буду писать код инициализации этих переменных, т.к. зафорсить мне их надо было один раз для отладки того самого куска кода). И это всё вместо того, чтобы просто скопировать код.Цитата:
я правда в этом смысла не вижу
Ведь функцию копирования не надо добавлять — она есть, но её за каким-то лешим прикрыли в онлайне.Что капризно? Риторический вопрос «чё за дурость»? Я здесь просто поделился наблюдениями. Ответа на этом форуме ни с кого не требую.Цитата:
Да нет, просто выражено все уж как-то слишком капризно.
хм, попробуйте открыть еще раз КДС, если проект из которого Вы хотите скопировать, был закрыт последним, значит в новой КДС он автоматически загрузится и если в первом окне были изменения, то в новом он спросит открыть оригинал или правленную версию, когда откроется проект копируйте свои данные не выключая онлайн в первом окне
ЗЫ кстати экспорт ни кто не отменял, в онлайне он доступен
Почемуто у меня рассылка не пришла на видео главу 2 и главу три.. а я неделю жду прям измаялся продолжеения на обучение. На кодесис.РФ трудно оринтероваться где посмотреть бывшие главы, и перемсотреть видео. ((((((
Для обсуждения книги создал отдельную тему:
http://www.owen.ru/forum/showthread....1337#post91337
В программу встроен декрементный счетчик CTD который не работает. Где ошибка подскажите?
Вход LOAD не задействован.
Здравствуйте!
ПЛК считывает информацию с нескольких устройств по модбас. В конфигурации ПЛК есть один мастер сети, и все устройства описаны как универсальные устройства.
Если, к примеру, одно из устройств перестанет отвечать, как обнаружить, с которым из них произошел сбой связи? Ведь если следующее ответит, то переменная Last Error установится в ноль.
Или нужно каждый цикл ПЛК читать эту переменную, и если она не равна нулю, тогда Last Address даст нам адрес этого устройства?
Правильно я думаю, или ошибаюсь ?
upd
Сомнения собственно в чем - За один цикл контроллера идет опрос только одного устройства? Или сколько получится ?
Здравствуйте!
Время опроса устройств при настройке через конфигурацию к времени цикла не привязано, опрос выполняется в фоновом режиме и зависит от времени выставленном в параметре polling time (подэлмент Universal ModBus Device).
я сделал например вот так. но еще не тестил на стенде. Если найдете ошибку - поправьте.
IF LAST485ADR=12 AND LAST485ERR=81 THEN TIMER_MZD2(IN:=TRUE, PT:=T#1500ms);
ELSE MZD2_CON_ERR:=FALSE;
END_IF;
TIMER_MZD2();
MZD2_CON_ERR:=TIMER_MZD2.Q;
псевдокод: если последний адрес и последний код ошибки равны соответственно 12(адрес вашего устройства) и 81(код ошибки "нет связи"), то запустить таймер TON. Если по прошествии заданного времени PT условие продолжает фиксировать "LAST485ADR=12 AND LAST485ERR=81" То таймер дойдет до конца, выставит выход в true и переменной отвечающей за ошибку связи вашего модуля установится выходное значение таймера. В противном случае (если фиксируется сочитание отличное от заданного условия) переменная ошибки выставляется в FALSE. получается что у вас ничего не затирается и ошибка если есть пишется в спец.переменную
...но при выполнении следующей строки программы безусловным образом заменится на действующее значение TIMER_MZD2.Q.Цитата:
В противном случае (если фиксируется сочитание отличное от заданного условия) переменная ошибки выставляется в FALSE.
Вот такой вариант "на скорую руку", вроде бы, должен работать правильно:
IF LAST485ADR=12 AND LAST485ERR=81 THEN
ERR_ADR12:=TRUE;
END_IF;
IF LAST485ADR=12 AND LAST485ERR=0 THEN
ERR_ADR12:=FALSE;
END_IF;
TIMER_MZD2(IN:=ERR_ADR12, PT:=T#1500ms);
MZD2_CON_ERR:=TIMER_MZD2.Q;
Вместо булевской переменной ERR_ADR12 можно использовать SR-триггер, смысл от этого не изменится.
Лаконичнее надо.Не первый раз натыкаюсь на индусский код с булевыми на этом форуме. Народ зачем-то городит ветвления ифами и сравнивает булевые переменные с тру и фолс. Как-то так:Код:TIMER_MZD2(IN := LAST485ADR = 12 AND LAST485ERR = 81, PT := T#1500ms, Q => MZD2_CON_ERR)
И это вместо TIMER(IN := NOT X).Код:IF X = TRUE THEN
Y := FALSE;
END_IF
IF X = FALSE THEN
Y := TRUE;
END_IF
TIMER(IN := Y);
Годится, но только если на этом интерфейсе висит одно-единственное устройство, с адресом 12. Или же если хотим следить лишь за отсутствием ошибок на данном интерфейсе, без уточнения конкретного устройства, вызвавшего ошибку (тогда адрес игнорируем, следим только за LAST485ERR).Цитата:
Лаконичнее надо.
Если же устройств два и более - то фиксировать ошибку обмена по "Last Address" и "Last Error" придется индивидуально для каждого адреса. Иначе результат условия LAST485ADR=12 AND LAST485ERR=81 не останется в TRUE на протяжении полутора секунд - ПЛК за это время перейдет к обмену с другим устройством, LAST485ADR станет уже не равным 12, таймер сбросится...
Предложенный мной вариант далек от изящества и сильно попахивает индусским кодом, но принцип иллюстрирует верно. Обнаружили ошибку обмена с данным адресом - запускаем TON, очередной обмен с этим адресом прошел успешно - сбрасываем. И так для каждого устройства на этом интерфейсе.
Вот 100% рабочий вариант для большого количества устройств в сети.
VAR
TIMER_SKV1:TON;
SKV1_CON_ERR: BOOL;
END_VAR
(*переменные LAST485ADR и LAST485ERR объявляются непосредственно в конфигурации ПЛК*)
IF LAST485ADR={адрес устройства} AND LAST485ERR=81 THEN TIMER_SKV1(IN:=TRUE, PT:=T#1500ms);
ELSIF LAST485ADR={адрес устройства} AND LAST485ERR<>81 THEN TIMER_SKV1(IN:=FALSE);
END_IF;
SKV1_CON_ERR:=TIMER_SKV1.Q;
прошу прощения за индусский код.
Там нужно немного доделать самому и немного переделать, где то у меня была эта программа!
для этого случая можно без else, я так думаю:
Как вариант.Код:(*lastNetAddr, lastNetErr - глобальные переменные с крайними
адресом и значением кода ошибки*)
VAR_OUTPUT
err1:BOOL;
err2:BOOL;
err3:BOOL;
END_VAR
...
CASE lastNetAddr OF
10:
err1TON(IN:=(lastNetErr=81 ) , PT:=T#1500ms, Q=>err1);
11:
err3TON(IN:=(lastNetErr=81 ) , PT:=T#1500ms, Q=>err3);
16:
err2TON(IN:=(lastNetErr=81 ) , PT:=T#1500ms, Q=>err2);
24:
;
32:
;
ELSE
;
END_CASE;
У меня такая проблема.... Не знаю как сделать ротацию двигаделей через показания датчика давления... надо что бы например при давлении в 5 бар, включался таймер на 15 сек, и если давление не поднялось выше то включить второй двигатель... помогите плз...
Мда. Окей, какая постановка задачи, такое и решение:Код:timer_on(IN := pressure = 5.0, PT := T#15s, Q => motor2);
Та нет, простой таймер и я могу написать))) я сам уже разобрался, спс)))
Здравствуйте, коллеги.
Попал мне в руки ПЛК 150. Экспериментирую и осваиваю CoDeSys.
Прочитал:
http://www.owen.ru/forum/attachment....1&d=1363171181
Сделал:
http://www.owen.ru/forum/attachment....1&d=1363171181
Собственно вопрос: А что я сделал не так?
Преобразование "REAL_TO_DWORD" очевидно, но непонятно зачем.
Вдогонку:
В списке адрес %QD7.0, а на панели "Базовые параметры" - %QB7
Вопрос 2: Чем чревато отличие в одной букве?
Аккуратнее с такими «очевидностями».Цитата:
Преобразование "REAL_TO_DWORD" очевидно, но непонятно зачем.
Согласно руководству, вторая буква (D) это дескриптор размера, а не типа. И по такому определению на адрес %QD должны приниматься любые 32-битные значения, в том числе с плавающей запятой. Тем не менее, компилятор при обращении вот так по адресу допускает только целочисленные. То бишь баг или в руководстве, или в компиляторе.
Преобразование REAL_TO_DWORD здесь неуместно, т.к. дробная часть будет отброшена. Рекомендую избегать прямого обращения к таким адресам и присваивать имена в окне конфигурации.
Спасибо.
Потерю дробной части наблюдал воочию.
Да... уж. Я, например, ошарашен тем, что к DINT компилятор в упор не хочет применять побитовые логические операции. Потом вычитал, что таки да, нужен BYTE, WORD, DWORD. И делаю тупое присваивание dw := di, чтобы потом покрутить полученное двойное слово.
С другой стороны, такая строгость системы иногда и спасает таких как я, читающих мануалы в последнюю очередь :)
То же самое с INT и SINT. Потому что негоже биты в знаковых типах дёргать. Где вам это понадобилось вообще?Цитата:
ошарашен тем, что к DINT компилятор в упор не хочет применять побитовые логические операции
Да просто выделить младшее слово, например. Я, к примеру, забрасываю DINT куда-то по словам.
Кроме того, бывают ситуации, когда просто однотипные операции делаю с разными типами. А разница между DWORD и DINT для переменных, которые по смыслу не бывают отрицательными - нулевая. Вот и бывает, что объявляю переменную DINT (за кумпанию с другими), а она, ну, может быть от 0 до 999999999. Пофиг, будет ли DWORD или DINT, так ведь? И вдруг выделить из нее некое поле операцией AND - низзя!
Конечно, все решаемо. Я не жалуюсь. Я просто ответил на вопрос.
Не знаю кто глючит, Эмулятор или КОДЕСИС. :confused:
Но в Овен Лоджике такого не происходит.:)
Вы видео покажите что с момента старта плк у Вас на выходе блинка ИСТИНА. А про преобразование на картинке не видно что у Вас единица. Тригер, что Р, что Ф практически не возможно увидеть на выходе ИСТИНА, потому что смена фронта длится один цикл, поставте минимальное время цикла в районе 100мс и увидите синюю полоску