PDA

Просмотр полной версии : Вопросы по программированию в CoDeSys



MagicCat
14.02.2010, 14:56
уважаемые специалисты, пожалуйста заглядывайте переодически в эту темку =) спасибо =)

мой перввый вопрос (в этой теме):

как вернуться из цикла прораммы Sfc в основную программу (в PLC_PRG)?
а) как это сделать в любом месте программы, при выполнении какого то условия?
б) как это сделать после выполнения прораммы?

очень жду ответа. спасибо

MagicCat
14.02.2010, 15:02
Второй мой вопрос. Столкнулся с тем что при выполнении последовательности действий в Sfc в определённом местепроисходит несрабатывание задержки времени. Алгоритм такой:

....
Шаг 14 ST

%QX3.1.0:=TRUE;
DELAY(TIME_IN:=t9);

условие дальнейшего перехода
DELAY.OK


.....

Если глянете пример из мануала по кодесис то там реализована такая же задержка времени между включением лампочек светофора.

Так вот данная цепочка у меня достаточно длинная и вот именно в этом месте (шаг 14 - шаг 15 ) почему то не срабатывает выдержка времени ((( Никак не могу разобраться почему, в остальных подобных блоках всё то же самое( Мистика какая то (((

MagicCat
14.02.2010, 15:10
Третий вопрос. Как сделть чтобы выполнение алгоритма в Sfc начиналось сначала (к примеру после остановки)? Предполагаю что там есть какой то прораммный указатель, который можно сбросить на ноль.

MagicCat
14.02.2010, 15:17
как осуществить программную перезагрузку контроллера ?

alexval2006
14.02.2010, 16:10
http://www.alexval2007.ucoz.ru/123456789/CoDeSys_V23_RU.pdf может поможет почитайте я там видел описание языка sfc

MagicCat
14.02.2010, 21:14
нету там этого =( по этому тут и спрашиваю. тот мануал я первым делом просмотрел.

Николаев Андрей
14.02.2010, 21:31
1. А кто сказал, что PLC_PRG не может быть на SFC.
2. Программа выполняется так: выполняется основная программа - далее в ней виден вызов подпрограмы - контроллер переходит в неё, выполняет её с верху до низу и возвращает управление основной программе, и та выполняется дальше.
3. Ни в коем случае нельзя писать программу, которая перезагружает ПЛК. Это бред в принципе. программа, перезагружающая ПЛК - это БАГ.
4. В SFC есть определенные флаги, по которым можно переходить безусловно на первый шаг. Более подробно в мануале по CoDeSys (сам никогда не использовал, но знаю, что есть)...

ЗАБУДЬТЕ ПРО СИ...

MagicCat
14.02.2010, 22:01
у меня Plc_prg на St, а из неё происходит вызов Sfc. в определённый момент може потребоваться (при нажатии кнопки) вернуться в основную программу из Sfc (прервать выполнение алгоритма).

вопрос 1: как это сделать?

вопрос 2: как при повторном вызове Sfc (при соблюдении условия для её вызова) сделать чтобы она продолжилась не с места прерывания, а с начала.

Sergey666
14.02.2010, 22:48
странно что вы пишете на St Plc_prg ,а подпрограмму на Sfc ,обычно делают все наоборот.
можно использовать оператор Case ,и вызывать подпрограмму с определенного "шага",по событию (кнопка) делается переход на другой "шаг",где вызова подпрограммы нет.
чтобы при повторном вызове подпрограммы не было "косяков" с переменными в начале их "сбрасывают" (0,false).
хотя как это делается в Sfc точно не знаю.
Но при вызове подпрограмма по любому будет выполнятся с начала,а ветвление будет в зависимости от того,что вы написали(или нарисовали).

Николаев Андрей
14.02.2010, 23:31
To Magiccat:
Пока Вы не усвоите основных правил бесполезно рекомендовать...
ПРОГРАММА НЕ СТОИТ НИ В ОДНОЙ ПОДПРОГРАММЕ...
За цикл - 1-2 мс контроллер успевает просчитать всю программу, не зависимо на SFC или ST она написана. Записывает результаты и опять начинает обсчет заново.

MagicCat
14.02.2010, 23:40
странно что вы пишете на St Plc_prg ,а подпрограмму на Sfc ,обычно делают все наоборот.

Ну у меня всё было сначала на ST, потом я не знал как в ST делается нужная мне временная задержка между активацией в TRUE выходов и по этому переписал подпрограмму на SFC.



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

к примеру Case PUSK.Step2 ? (PUSK написана на SFC)



чтобы при повторном вызове подпрограммы не было "косяков" с переменными в начале их "сбрасывают" (0,false).
хотя как это делается в Sfc точно не знаю.
Но при вызове подпрограмма по любому будет выполнятся с начала,а ветвление будет в зависимости от того,что вы написали(или нарисовали).

Не начинается сначала (((, продолжается с места остановки ....... Надо с флагами что то сделать, вернее с SFCInit или SFCReset, но я что то с ними совссем не могу разобраться( Не получается с помощью них сбрасывать. Скорее всего я какой то нюанс упустил.

MagicCat
14.02.2010, 23:47
To Magiccat:
Пока Вы не усвоите основных правил бесполезно рекомендовать...
ПРОГРАММА НЕ СТОИТ НИ В ОДНОЙ ПОДПРОГРАММЕ...
За цикл - 1-2 мс контроллер успевает просчитать всю программу, не зависимо на SFC или ST она написана. Записывает результаты и опять начинает обсчет заново.

ну я просто так для удобства называю, не знаю как это называется у вас. я, кажется, понял что вы пытаетесь мне объяснить, и я уже переделал то что вы говорили, и внутренние циклы убрал =) . остались небольшие проблемы, я бы сказал с синтаксисом.... вот я их и спрашиваю...

Sergey666
15.02.2010, 00:45
Почитайте описание ST в руководстве.
Синтаксис и ресурсы похожи на язык Delphi(Paskal).
CASE Prog_state OF
100: ... Операторы
200:Pusk();
300:...Операторы
Переменная Prog_state-целочисленного типа , меняете ее в программе , в зависимости от ее значения будет выполнятся "кусок"программы.

MagicCat
15.02.2010, 18:49
вопрос в силе (( не найду ответа (((

у меня Plc_prg на St, а из неё происходит вызов Sfc. в определённый момент може потребоваться (при нажатии кнопки) вернуться в основную программу из Sfc (прервать выполнение алгоритма).

вопрос: как при повторном вызове Sfc (при соблюдении условия для её вызова) сделать чтобы она продолжилась не с места прерывания, а с начала.

Николаев Андрей
15.02.2010, 18:53
1. НИКАК. Ну не стоит контроллер в подпрограмме - ну хоть ты тресни... и по этому возвращать его ни откуда не нужно - он сам каждый цикл возвращается, добровольно так сказать... Можно по какому то условию просто не передавать управление этой подпрограмме (не вызывать её)...
if not button then
prg1();
end_if;
2. Вы все правильно поняли с Флагами - надо просто с ними разобраться - у меня руки не доходили...

MagicCat
15.02.2010, 18:59
1. НИКАК. Ну не стоит контроллер в подпрограмме - ну хоть ты тресни... и по этому возвращать его ни откуда не нужно - он сам каждый цикл возвращается, добровольно так сказать... Можно по какому то условию просто не передавать управление этой подпрограмме (не вызывать её)...
if not button then
prg1();
end_if;


ок. не вызывать не получется, потому что она в этот момент уже вызвана. какую метку поставить в Sfc, чтобы перейти в Plc_prg ? (чтобы не выполнять оставшийся код Sfc) Пробывал просто Plc_prg; писать но тогда возникает рекурсия...

MagicCat
15.02.2010, 21:28
не работают флаги :-(

Николаев Андрей
16.02.2010, 15:31
Еще раз.
Давайте четко разделим программу, и работу с флагами в SFC.
1. Работа программы:
По умолчанию системой исполнения в ПЛК выполняется основная программа. То есть для программы a:=a+1; как будет работать ПЛК:
Система исполнения смотрит состояние переменных в области ввода. Передает управление программе. Программа выполняется один раз с верху в низ. То есть a будет равно 1. Далее система исполнения записывает значение переменной а (если указано) в область выходов.
Опять возвращается к входам, опрашивает их, передает управление основной программе... a равно 2. Заканчивается выполнении программы - записываем результат.
С этим вопросы?
Теперь добавляем подпрограмму b:=b+2;
Отбрасываем запись входов и выходов.
Первый цикл...
идем с верху по приложенному проекту:
считаем один раз а. а=1
видим вызов подпрограммы переходим к ней.
считаем один раз b. b=2
выходим из подпрограммы в основную.
Видим что программа закончилась и идем в начало.
И так постоянно.
Теперь просто представьте, что у Вас подпрограмма не на st а на SFC.
Идем по основной, переходим в подпрограмму - смотрим какой шаг на SFC активный. Один раз выполняем активный шаг, и автоматически возвращаемся в основную программу. Без всяких флагов.

Sergey666
16.02.2010, 22:08
не работают флаги :-(

На сайте codesys.ru есть много статей по программированию на SFC.
Прежде чем бросаться в бой с топором в руках надо сначала теорию подготовить.;) Тады и флаги заработают.:p

MagicCat
19.02.2010, 20:05
решил проблему, переписав всё на язык ST. Спасибо Sergey666 за помощь и разьяснения.

Николаев Андрей, так же вам благодарен за разьяснения. Спасибо всем кто откликнулся.

Теперь я уже дописываю свою программу, получилось не так просто, как выглядело на первый взгляд. Простой, на перый взгляд, алгоритм в реализации на CoDeSys оказался достаточно сложным. Если ещё возникнут вопросы то буду их задавать в этой же теме. Ещё раз всем кто откликнулся огромное спасибо.

Николаев Андрей
20.02.2010, 18:13
поверьте мне - это только начало.
в дальнейшем когда освоите все инструменты покажется что на языках высокого уровня сложно - здесь подход другой ;)

Адлан
28.09.2011, 16:37
надо объявить переменную (глобально) sfcreset: BOOL. Если ее значение ИСТИНА, SFC программа перейдет в цикл Init. Чтобы программа смогла перейти к первому шагу и далее, надо сбросить sfcreset в ЛОЖЬ. Это можно сделать в самом цикле Init

capzap
28.09.2011, 16:55
читайте про "Входное или выходное действие" на странице 28 CoDeSys_V23_RU.pdf

drvlas
28.09.2011, 18:38
О, как я вижу, полгода назад коллега бродил по тем же тропинкам. Если уважаемому автору темы все еще интересны вопросы управления выполнением программы, то предлагаю посмотреть тему здесь (http://www.owen.ru/forum/showthread.php?t=11298) и там (http://forum-ru.3s-software.com/viewtopic.php?f=1&t=1102). В том числе вопрос реагирования на СТОП.

Vasilij
18.10.2011, 12:04
Здравствуйте!
При нажатии кнопки на панели оператора включается вход контроллера. По программе включается выход, сигнал с которого должен поступить на элемент (лампа) в панель оператора.

Как передать сигнал с выхода типа BOOL (ПЛК-160) в панель СП270?

Николаев Андрей
19.10.2011, 00:57
В программе присвоить переменной, отвечающей за выход (нужно дать имя) значение переменной, полученной по сети от панели.

Vasilij
19.10.2011, 07:23
В программе присвоить переменной, отвечающей за выход (нужно дать имя) значение переменной, полученной по сети от панели.

Может я что не так понял?
Передача на выход сигнала из программы переменной - с этим понятно, можно и вместо переменной записать номер выхода.

вопрос в том как передать из конфигуратора CoDeSys значение (0) или (1) булевого выхода в панель?

В панели указываем регистр PSW 332.
В CoDeSys параметры модуля должны быть: регистр 332, индекс 2 command 0x03, но такого значения нет, есть только 0x0f и 0x71

Vasilij
21.10.2011, 14:05
Может я что не так понял?
Передача на выход сигнала из программы переменной - с этим понятно, можно и вместо переменной записать номер выхода.

вопрос в том как передать из конфигуратора CoDeSys значение (0) или (1) булевого выхода в панель?

В панели указываем регистр PSW 332.
В CoDeSys параметры модуля должны быть: регистр 332, индекс 2 command 0x03, но такого значения нет, есть только 0x0f и 0x71

Кто знает, как разобраться с этим вопросом, ответьте пожалуйста?

swerder
21.10.2011, 14:48
пример #10
http://www.owen.ru/forum/showthread.php?t=11273

Vasilij
24.10.2011, 08:12
пример #10
http://www.owen.ru/forum/showthread.php?t=11273

Пример №10 не отображает данной информации!!!

Тех. поддержка ОВЕН подключитесь к вопросу!!! пост №25, №27

capzap
24.10.2011, 08:55
Кто знает, как разобраться с этим вопросом, ответьте пожалуйста?

Читайте http://ru.wikipedia.org/wiki/Modbus
С булевыми (битами, флагами) работают функции модбаса 1,2, 5 и 15,а 03 функция работает с регистрами, т.е. 2 байтами

lara197a
24.10.2011, 09:10
Можно вот так:

capzap
24.10.2011, 09:13
оказывается в документе http://www.owen.ru/uploads/re_rp_sp200.pdf есть пункт 4.1.7.2.2 в котором доступно все написано, чего шум то поднимать :)

Александр Приходько
24.10.2011, 15:01
Работайте не с битами, а с регистрами, будет проще.

Vasilij
28.10.2011, 12:47
Спасибо всем за помощь!
Только вот не стыкуются переменные в моей программе.
Программа написана на языке "Функциональные схемы", поэтому сейчас использую элемент преобразования "PACK".

capzap
28.10.2011, 12:52
а зачем паковать, если памяти много можно сделать BOOL_TO_WORD и получаете регистр с двумя значениями 0 или 1

drvlas
28.10.2011, 13:05
если памяти много
Вот, есть повод спросить. Как вы думаете, если действительно памяти в десятки раз больше, чем требуется - есть ли смысл работать с однобайтными переменными? Процессор ПЛК100 - как-то различает, скажем, BYTE и WORD при обработке?
Я в одном проектике взял да и сделал абсолютно все переменные двухбайтными. Но поисследовать, есть ли ухудшение быстродействия - не стало времени. Увезли игрушку :)

Можно пойти и дальше - а может все целочисленные переменные привести к DINT? Хотя, ИМХО, все же должны быть разные комадны для 8- и 32-разрядных операндов...

capzap
28.10.2011, 13:12
ПЛК100 имеет 32-х разрядный RISC-процессор, это означает что за один такт процессора можно выполнить инструкцию что с одним разрядом, что с 16-ю, скорость выполнения будет одинакова

drvlas
28.10.2011, 13:20
ПЛК100 имеет 32-х разрядный RISC-процессор, это означает что за один такт процессора можно выполнить инструкцию что с одним разрядом, что с 16-ю, скорость выполнения будет одинакова
Не факт. Могут быть предусмотрены разные команды для байтных и 2-хбайтных и 4-хбайтных операндов. Я только что поставил вопрос на другом форуме, там где АРМ держат за яблочко. Если будет четкий ответ - поделюсь.

capzap
28.10.2011, 13:39
не путайте с многоядерностью процессоров, за один такт вы выполните только одну инструкцию а будет это бит или 2-х байтное слово уже не важно

drvlas
28.10.2011, 13:51
не путайте с многоядерностью процессоров, за один такт вы выполните только одну инструкцию а будет это бит или 2-х байтное слово уже не важно
Давай не будем спорить, сколько чертей помещается на острие иглы. Подождем ответов людей. которые знакомы с системой команд АРМа. Хотя, конечно, еще может иметь значение реализация компиляции операций с целочисленными переменными в КДС. А это уже вопрос к другим спецам...

drvlas
29.10.2011, 00:44
Это совпадает со мнением спецов по микроконтроллерам: выигрыша в использовании целочисленной переменной BYTE по сравнению с WORD и DWORD - нет. Они там завелись спорить, каков НАОБОРОТ будет выигрыш от использования только 32-разрядных данных, но слегка разделились во мнениях.

Итак, интересная получается рекомендация от drvlas-а: если нет специальной причины определения данных как BYTE или WORD - объявляйте их DWORD. Займет больше памяти (решать вам), но никак не ухудшит скорость работы ПЛК.

ПРОШУ ПОПРАВИТЬ ЭТОТ ПОСЫЛ, если он таки да неверен :)

К видимым мне исключениям относятся: работа со строками (там байты удобны, может быть), работа с портами определенного размера (например, двухбайтными регистрами), создание файлов... КАРОЧИ, это можно обсудить.

Валенок
29.10.2011, 02:16
плк-110.
от byte до dword - по барабану. Около 0.5 мкс на операцию mem-mem-mem
Для real - ок. 4мкс
Только на фига dword, если нужен байт ?

drvlas
29.10.2011, 11:03
Только на фига dword, если нужен байт ?

Повторю свое объяснение на другом форуме:


Нет желания оптимизировать по скорости.

А есть желание уменьшить число типов данных в программе. А именно: все целочисленные переменные размером 1, 2 или 4 байта - сделать 4-байтными. Зачем? А вот зачем.

У меня много т.н. "параметров", т.е. переменных, с которыми может работать пользователь. И эти параметры, а точнее - переменные, хранящие их значения, имеют различные типы - от практически булевых до двойных целых и вещественных. Многие процедуры работы с этими переменными получают на входе указатель на нее и тип данных - а дальше приходится делать нечто подобное Си-шному SWITCH по типу. Чем меньше типов, тем меньше веток в переключателе. Это раз.

Кроме того, часто-густо в операторах присвоения приходится иметь дело с разными переменными - и, если типы не совпадают, то приходится использовать явное преобразование (там язык такой, строгий к типам). А оно еще и громоздкое в записи. Значительно проще было бы не преобразовывать - а! значит лучше иметь одинаковые типы. Это два.

И вообще, если оказывается. что тип BYTE абсолютно ничем не лучше типа WORD, а тот, в свою очередь, не лучше DWORD - то какое право на жизнь имеют эти "огрызки" нормального 32-разрядного слова? Это уже два с половиной :)

Таким образом, никакой оптимизации во взрослом понимании этого слова. Только красивше тексты программ.

capzap
29.10.2011, 12:24
прога с одим типом может и перебор, зато модбас от этого сильно выигрывает, не задумываешься о выравнивании, если еще к тому же и самописный, нужно будет реализовать только две функции, чтение и запись

capzap
29.10.2011, 14:54
имел ввиду регистры либо флаги, а насколько разношерстна по типам программа, все зависит от творца

capzap
29.10.2011, 17:20
А так - объявил одинаковые структуры в слейве и мастере и гоняй себе их туда-сюда на здоровье.
PS
Все никак руки не дойдут до tcp-мастера

Хорошая подсказка, а я раньше REAL-ы разбивал до байтов, чтоб отправить.

P.S. даже MB TCP слейв пробовал, руки доходили :)

Vasilij
31.10.2011, 06:09
а зачем паковать, если памяти много можно сделать BOOL_TO_WORD и получаете регистр с двумя значениями 0 или 1

Спасибо, это проще!
Пробовал совмещать к функциональным схемам добавлял программу на языке "структурированый текст" ничего не выходило. Ошибка была "несколько объявлений переменной", поэтому так и сделал.