Comments 87
Прекрасный пример, как не надо писать на релейке. Да и заодно убожества Дельты.
Инструкции MOV в релейке быть не должно (разве что не биты а word'ы и прочие данные передать), достаточно койлов, уж тем более, что здесь есть даже их edge-варианты.
Для непривычных, аналогом такого применения MOVв процедурных языках будет if (x=true) y = false
Так же на рис.4 наблюдается нарушения правила единого выхода, что в разных контроллерах - неопределенное поведение (например выход будет моргать по ходу исполнения логики в Allen-Bradley, а в Сименсе не будет)
неопределенное поведение (например выход будет моргать по ходу исполнения логики в Allen-Bradley, а в Сименсе не будет)
Как минимум у Сименс это не какая-то особенность реализации, а вполне себе документированная фича с известными правилами работы и целым разделом документации, посвященным ее настройке, поэтому словосочетание "неопределенное поведение" ей, мне кажется, не подходит. Если требуется совместимость с кодом, который завязан на мгновенное обновление, — как минимум в четырехсотых контроллерах эту штуку можно просто отключить в конфигурации.
Однако даже если контроллер будет менять напрямую выходы, перезапись значения в соседней инструкции, вероятнее всего, не будет физически проявляться просто потому, что за время выполнения одной инструкции выход сработать попросту не успеет. Собственно, автору понадобилось создать значительную задержку между выполнением команд чтобы увидеть мигание выходов в такт логике.
Во-первых, Дельта не убожество, а достаточно хороший продукт по соотношению цена/качество, а также поддержке клиентов. Например, по моему запросу в программе DOPSoft (это дельтовские панели HMI) была изменена кнопка, отображающая последовательность даты/времени в Historic AralmsTrends. Вы скажете - мелочь, я скажу - добейтесь чего-то подобного от Сименса и АВ.
Во-вторых, инструкция MOV должна быть, вопрос только в уместном её использовании.
В-третьих, на рис.4 нет нарушения правила единого выхода, но есть ошибка, цепи Network 2 и 3 фактически не будут работать, состояние переменной outState будет определяться цепью Network 4.
Сама статья написана, ИМХО, сложноватым языком. Не корректно использован термин И-НЕ, потому что в качестве "НЕ" использована 3-я переменная. Всё же 2И-НЕ выглядит так:
![](https://habrastorage.org/getpro/habr/upload_files/8bd/78d/535/8bd78d535838eb6c7d665bbb4b8fc883.jpg)
RS триггер собрается проще, на контактах по переднему/заднему фронту и катушках с SET/RESET функцией. Но это,не зная всю программу, критиковать особо не буду.
Если надо увидеть работу светодиодов - самое простое не замедлять программу, а вставить счётчики, с переменным параметром срабатывания, и отслеживать включение на каждый 5-й, 10-й, ..., 100-й раз.
Самое (для меня) непонятное - а в чём смысл то работы? Паралелльности срабатывания ПЛК всё равно не будет. Если надо одинаковые по времени циклы сканирования - можно отслеживать включение бита в начале цикла, каждый раз его инвертировать, и считать время исполнения, а потом вносить задержку, но это будут миллисекунды.
или как?
1) Спасибо. Приятно слышать добрые слова в адрес DELT-ы J Плохое ли хорошее, но используем то, что есть. Более того, надеюсь, даже улучшаю. Мне уж точно лучше, чем было (до автоматов, естественно).
2) ПО поводу MOV. В стандарте на LD, кажется, ее нет. Но без нее было бы туго. Если не сказать – невозможно. Но здесь, как мне кажется, нужно воспринимать язык как он есть. Не нравится MOV – не используй. Делов-то!
3) Я не вижу ошибки. Все работает и работает как надо.
По поводу И-НЕ. Речь идет не об операции, а о модели элемента, реализующего данную операцию. Это, скажем так, разные вещи. У Вас все же не 2И-НЕ, а, как я понимаю, 2ИЛИ-НЕ. Но даже не в этом дело. Делают триггер и на этих элементах. Так вот. Если Вы соберете триггер на приведенном Вами элементе, то он работать верно не будет. Это гарантированно. Не верите – попробуйте и сами убедитесь. Речь прежде всего идет о генерации. Ее не будет 100%. Устойчивые же состояния будут отражаться.
Возможно, сам триггер можно собрать и проще (хотелось бы увидеть как). Но смысл в том, чтобы избегать каких-то хитрых приемов, упрощающих что-то. Ну и потом убедиться еще надо, что он будет работать правильно. Т.е. как настоящий триггер, а не просто как нечто, имеющее два устойчивых состояния. Это будет «утка», которая крякает, но не плавает J
О замедлении. В том-то и дело, что хотелось бы замедлить программу, не вставляя в нее что-то. Так обеспечивается чистота эксперимента. И это первое что пришло в голову. Т.е. чтобы совсем не касаться модуля PRG RS_триггер. Но можно создать счетчики и «врезать» их после выходных каналов элементов. Это корректно. Так в конечном итоге и пришлось сделать. Только у меня они названы более точно – задержками. А эти задержки могут или транспортными или инерционными. Но это уже более детальный разговор. И сделаны они должны быть тоже, как автоматы. Если вставлять простые счетчики, то придем к эффекту, который случился и у меня.
И о самом непонятном (или непонятом?). О смысле
работы. Он вроде бы озвучен в начале статьи – в реализации идеи. Идеи
автоматного программирования (прошу прощения, что не прописал прямо, но рассчитывал
все понятно и так). Или, что точнее (но по смыслу будет уже), реализации
автоматов на языке LD. И именно это (реализация идеи) и только это создаст
параллельность, которой в исходном варианте программирования нет и в помине.
![](https://habrastorage.org/getpro/habr/upload_files/ce0/ac4/514/ce0ac45149fbafc390cb8a5676dce21a.jpg)
прошу простить, не тот скриншот прикрепил для 2И-НЕ, вот этот правильный
Какое-то странное восприятие PLC - как слабый ПК и с убогими языками программирования. 25 лет в автоматизации, но такие ассоциации первый раз прочел, спасибо за расширение моего понимания, тем чем я всю жизнь занимаюсь
Да, как говорится, не за что ;) Нужно смотреть объективно. Поскольку я до этого программировал на С++ и на обычным ПК, то сравнивать есть с чем. Так что, не в обиду, но возможностей много-много меньше. Но это не значит, что совсем хуже. В чем-то даже лучше и проще. Я и об этом сказал. Но, например, свой код на С++ (аналог его) на ПЛК я уже не перенесу. В принципе. Но что-то получилось (в смысле идеи, но не кода). И во многом об этом статья.
Возможно, Вам больше подошел бы язык ST, он ближе к С, вот тут первоначальные сведения есть. http://www.codesys.ru/docs/st_c.pdf
Правда ST не доступен на контроллерах DVP, только на AS200-300. И на нём сложно делать импульсные цепи. Но мультивибратор я как то делал.
Вы не поняли мой стёб, то что вы пришли с С++, я как раз и понял после первых абзацев вашей статьи. Мне немного не понравилось как вы описали контроллер. В моем понимании (без смотрения в Вики) это комплекс аппаратных и программных средств обеспечивающие управление тех. процессом в реальном времени. Быстро с головы написал, надеюсь асушники меня какашками не забросают
p.s. ну и все же нужно не подыскивать удобный язык программирования а прочесть основы - Ганс Бергер это для Siemens контроллеров, но я думаю можно найти и литературу не специализированную к железу. И тогда проблем с языками не будет.
p.p.s. - Соответственно не будет в логике множественных присвоений
Может, это опять стеб, но проблем с языками у меня лично нет. Просто LD был почти один доступный язык на момент начала работы с данным типом ПЛК.
И по поводу "множественности". Их не много и не мало, а столько сколько нужно при выбранном способе реализации автоматов. Если Вы сможете предложить какой-то свой вариант, уменьшающий их число, то можно будет обсудить и сравнить.
И обращу внимание еще раз. мы боремся не за красивый или минимальный код, а за такой, который отражает просто, однозначно, наглядно и надежно модель программирования. В данном случае - автоматного. Здесь каждая цепь - это один переход (одна дуга) автомата. Поэтому зачем "портить" то, что и так хорошо ;)
Не вижу весь код, потому могу судить не корректно, если outstate у вас аналог состояния графа, то да, все норм)
Все там видно на рис.4 - бардак.
Типичный RS-триггер из любого учебника по электротехнике - схема управления двигателем
![](https://habrastorage.org/webt/il/8f/ag/il8faghq_ycbltejglcvbgrpadg.png)
Для алгоритмов посложнее добавить количество m_StateXXX (ес-но с хранением состояния)
Все там видно на рис.4 - бардак.
Бардак - это одна из форм порядка :)
Потом, бардак это для непросвещенных. А так - полный порядок. Но порядок здесь в наличии модели автомата, представляющей алгоритм программы. Я, например, даже в своих программах на LD не разбираюсь, когда возникают проблемы. Я смотрю на автомат, изменяю его и потом корректирую программу на LD. А без этого уже спустя день-второй я тоже смотрю на свою LD-программу и думаю - какой же там бардак :)
Типичный RS-триггер ...
Прошу прощения, но что-то я в Вашем коде не увидел "типичного триггера". Может можно представить Вашу идею (алгоритм) в форме ... автомата. Ну, на крайний случай, в форме блок-схемы. Если, конечно, это возможно. Но это просто должно быть возможно! Если, конечно, Ваш код не одна из форм настоящего бардака, для которого это сложно сделать (саму невозможность я исключаю совсем) ;)
Прошу прощения, но что-то я в Вашем коде не увидел "типичного триггера"
Без проблем, 1я же картинка.
Триггера там, конечно, нет. Но есть штука похожая на него ;) А вот и автоматная модель, аналогичная схеме на рис. 3.8. и которую Вы, к сожалению, так не создали, может быть следующей:
![](https://habrastorage.org/getpro/habr/upload_files/537/ad2/b86/537ad2b865efa5d79f89250b76b7513e.jpg)
Программа и ФБ на языке LD, которые соответствует данному автомату, будут такие:
![](https://habrastorage.org/getpro/habr/upload_files/3e0/064/cd9/3e0064cd95a43d2281041e5f0e3634a5.jpg)
Это полный код. Он, конечно, побольше, чем у Вас. Но, во-первых, ему я доверяю: автомат достаточно прост, а перевод на язык LD снадартен и проверен. А вот Вашу Программу еще нужно тестировать на соответствие схеме.
Но я вспомнил, что где-то видел аналог Вашего “триггера», и даже нашел его. Это в документации по программированию на ПЛК Дельта. Но называется там эта схема – "Самоблокировка выхода с приоритетом Стопа" и, наверное, так будет точнее:
![](https://habrastorage.org/getpro/habr/upload_files/2f0/224/ad1/2f0224ad1659a2379bde10df21435cc0.jpg)
Но приведена там же и, так называемая, триггерная схема (Пример 10):
![](https://habrastorage.org/getpro/habr/upload_files/0f7/8af/367/0f78af3677f7cc7e4dc458188482fa88.jpg)
Но это тоже не триггер, конечно.
Был тут уже один теоретик с подобным наукообразным стилем общения, все про Драконов задвигал.
Вот только бесконечно далек он был от практики, на что ему резонно пеняли.
RS-триггер в ПЛК - это именно то, что я и написал. И Вы кстати, тоже, только уродливо. В схемотехнике триггеров больше и они отличаются.
Если не умеете писать на релейке, рекомендую использовать SFC. Это чистые графы автоматов, как Вам нравится. Поддерживаются всеми адекватными контроллерами.
Был тут уже один...
Как мне представляется Вам нужно подкорректировать свое отношение к людям вне зависимости от их предпочтений. Относится к ним более уважительно. А к тем, кто владеет, теорией - чуть ли не в первую очередь. К ним надо прислушиваться, а не пренебрежительно смотреть в их сторону (мол, он еще и в шляпе :). Именно теория кардинально влияет на практикую В практике порой все "мутно", а вот в теории можно разобраться права она или нет...
И Вы кстати, тоже, только уродливо. В схемотехнике триггеров больше и они отличаются.
Так вот, - о теории. Вы дали ссылку на схемы триггеров. Это практика. И асинхронный RS-триггер - это практике. Но приведенный граф его поведения - это уже теория. И в данном случае он ошибочен. Почитайте повнимательнее мои статьи и в них все это доказано. Теоретически. Есть этому доказательство не только моих статьях. Тот же [теоретик] Шалыто, но особенно [практик] Фрике показывают как работает триггер. Это не так, как представлено в Вики. Это теория и практика...
Теория доказывает, что на практике с параллельными вычислениями у нас совсем плохо. И практическое моделирование практической же схемы самого простого триггера в этом убеждает. Замечу, самого простого. И не надо моделировать что-то большее, если в малом уже ошибки. Надеюсь, эта "теоретическая мысль" Вам понятна?
Идем дальше. Без ложной скромности теперь о моих достижениях ;) Теоретически я доказал работу триггера. И правильнее, строже и, главное, точнее, чем у того же д.т.н. Шалыто (он, т.к. других доказательств я просто не встречал). Эту теорию я "добил" практикой. Эта "практика" называется ВКПа. Она на С++ (многих это огорчает, но что есть). Ее я использую в своей практической работе. В том числе и на ПЛК (здесь с оговорками).
Итак, ближе к триггерам, на которые Вы дали ссылку... Я Вам гарантирую, что я могу смоделировать все эти схемы "по щелчку" на базе тех логических элементов, которые я создам по автоматной технологии, и результаты будут один в один соответствовать их практической работе. Собственно подобное я делал не раз, сверяя теорию с практикой. Более того, в свое время триггер осциллографом "обмерил" со всех сторон и в разных вариантах. Это, чтобы понять как теория согласуется или должна соответствовать практике.
Вот такое единение теории и практики. И таким оно и должно быть. Теория без практики - мертва. Практика без теории - кустарщина. Мне почему-то кажется, что чем-то подобным занимаетесь и Вы. Извинюсь, если получу подтверждение обратного :)
Теория доказывает, что на практике с параллельными вычислениями у нас совсем плохо. И практическое моделирование практической же схемы самого простого триггера в этом убеждает. Замечу, самого простого. И не надо моделировать что-то большее, если в малом уже ошибки. Надеюсь, эта "теоретическая мысль" Вам понятна?
Мне тут непонятно, откуда вдруг тут (в статье или триггере) появились параллельные вычисления?
Я не против единства теории и практики, но к сожалению, это обычно разные люди =)
Мне тут непонятно, ....
Так это, батенька, объективная реальность. Мне, к примеру, совсем непонятно, когда люди не видят очевидного. А больше всего убивает, что они это очевидное отрицают. У Вас, как мне кажется, еще есть шанс исправиться. и все только благодаря Вашей настойчивости ;)
Так вот, положите перед глазами схему асинхронного RS-триггера. Положили? У него сверху нарисован элемент И-НЕ и снизу еще один элемент И-НЕ. Это разные, подчеркиваю - разные, элементы. Они работают одновременно и синоним этому - параллельно. Т.е. слова одновременно и параллельно означают здесь одно и то же (а не так, как это обычно считается за бугром - concarrent и parallel).
Эти элементы реализуют определенные процессы - реализацию логической функции И-НЕ. Это понятно? Или, может, вспомним импульсную технику и как реализуются и работают подобные элементы. Короче, эти элементы реализуют некие процессы, которые в ПК, ПЛК и т.д. превращаются в вычислительные процессы. Если их "собирать" по аналогии с реальной схемы (она еще перед Вашими глазами?), то им соответствуют параллельные процессы в ПК, ПЛК и далее по списку.
Движемся далее. Эти элементы (то бишь процессы) взаимодействуют определенным образом. У реальных элементов эти связи реализуют проводочки. В ПК это делается иначе, но в чем-то похоже.
Замечу, что если эти связи изменить (например, убрать одну), то это уже не будет триггер. Вывод - связи дело часто порочное и влияют на нашу жизнь и жизнь любых элементов. Да и вообще любых процессов.
Ну как, стало яснее?
Моя фантазия пока иссякла, чтобы предложить другой более наглядный вариант... Правда, почему-то тут же возник образ Камасутры. Там могут быть самые разные связи, но только возможности для тестирования будут несколько урезанные. Да и с точки реализации объектами чисто логических функций будут проблемы. Хотя попытать собрать "триггер", как мне кажется, им (объектам) будет под силу. Как минимум, внешне будет очень похоже :)
Еще одно соображение. В наше время "живой триггер" видят очень немногие люди. Раньше - берешь 155-ю серию, проводочки, паяльник макетируешь и осциллографом сморишь картинки. Сейчас - где это все? Кому это интересно? Но параллелизм мы пытаемся освоить Через, прошу прощения, через ... корутины. А по мне так через одно место. Просто надо быть ближе к ... элементам, проводочкам. Ну, кратко - к практике и реалиям...
Наверное Вы работаете на очень вредном химическом производстве, надеюсь молоко хоть дают =)
В МЭК-61131 нет параллельного исполнения пользовательской программы (ну почти, а с учетом числа реализаций, так вообще можно забыть)
В МЭК, может, и нет (не изучал досконально). Из-за этого их могу даже пожалеть ;) Но, как минимум, у меня параллелизм есть. Это "медицинский факт" (замечу, без влияния какой-либо химии :)
> В МЭК-61131 нет параллельного исполнения пользовательской программы (ну почти, а с учетом числа реализаций, так вообще можно забыть)
Куда он делся? Ещё и несколькими способами.
Например? Я о реальной многозадачности, а не о блоках прерываний, потому что при их выполнении остальные стоят.
И я не о блоках прерываний.
Во-первых, можно запускать задачи через заданные интервалы времени.
![](https://habrastorage.org/getpro/habr/upload_files/35d/000/a7b/35d000a7bf8206bee6ed2e0488fe6ce2.png)
Во-вторых, при использовании шагового программирования будет выдаваться результат выполнения активных шагов.
А если нужна реальная многозадачность, то каждую задачу нужно исполнять на отдельном CPU.
ИМХО, сие сильно усложнит программы, ибо понадобится синхронизировать доступ к общим данным задач. Исходя из моего опыта общения на форумах, 3/4 ПЛК-погромистов вообще не ведают, что такое КА, и ещё меньше умеют ими пользоваться. Так что мгоголовость ПЛК сильно усложнит ПЛК, а реально пользоваться ей будет очень мало людей.
Тем не менее сейчас простейшие контроллерные ЦПУ уже многоядерные, а таргетом КодеСиса или МастерСкады или Изаграфа может быть любой Линух. Так что проблема есть и реальная, наработки по многоядерности я видел только у КодеСиса.
Линукс тут ни при чём, кстати. Вопрос, ИМХО, в синхронизации. Я могу на каждом ядре запустить экземпляр ПЛК, но, повторюсь, всё упрётся в синхронизацию данных.
Именно.
Я немного забыл - в Стандарте в части 5 предусмотрена синхронизация только через ФБ.
Вы удивитесь, но вообще-то для реализации параллелизма не нужно многоядерности. А многоядерность не гарантирует реализации параллелизма. Аргументировать? - пажалста!
Берем объект содержащий параллелизм. Здесь нужен реальный, который будет служить эталоном, критерием реализации параллелизма.
Таким объектом является RS-триггер. Берем, т.к. проще уже некуда...
Мы имеем реализацию его поведения на вполне себе одноядерном ПЛК. Первый тезис доказан.
Мы можем взять два ПЛК и на каждом реализовать модель элемента И-НЕ. Затем связать эти ПЛК через входы/выходы. Гарантированно вы не получите желаемого поведения. И почему? Потому что нет модели параллельных вычислений.
А что это за фишка такая - модель параллельных вычислений? Ее пытаются найти/создать уже многие лета. Моделей таких предлагалось много. И, кстати, сети Петри одна из таких моделей. Но все они были благополучно похе..ны, пардон, - забыты. Но пока еще не было таких, которые забраковали бы модель на базе сетей автоматов. Той, о которой здесь и говорится.
Да, для тех, которые хотят покусится на автоматную модель. Попробуйте найти пример, который бы опровергал/доказывал ее несостоятельность. Уверяю - не найдете. Могу, правда, ошибаться, но до сей поры такового не нашлось. Теория все-таки, блин ее ети... ;)
Почему-то программисты ПЛК забывают, что контроллер промышленный это дискретная штука. В Сименсе моргать выходы не будут, потому что они устанавливаются в начале цикла ПЛК, потом идет чтение входов, выполнение организационных блоков и т.д.
В AB скорее всего сделали иначе и состояние выходов меняют по ходу выполнения программы, что не очень то логично, RLO хотелось бы видеть в конце цикла, а не как программисту в голову взбредет.
В общем то есть детские ошибки, которые лечатся нормальной пусконаладкой и выдиранием волос из мягкого места спины, когда ничего не работает, а заказчик требует и угрожает расправой.
По поводу Дельты, это нормальная альтернатива в современных условиях для систем среднего класса. Но у них тоже сроки поставки конские.
Изменение выходов, а равно как и чтение входов по ходу выполнения программы нарушает пожалуй самый главный из принципов - детерминированного поведения: при выполнении цикла программы входа\выхода не меняются, дабы не получить трудноуловимый undefined behavior.
не уверен насчёт АВ, но в Дельте цикл такой: Чтение ВХОДОВ -> работа программы слева направо и сверху вниз по цепям -> запись ВЫХОДОВ
Все это так. Но что понимать под циклом программы. У автоматов цикл - это переход между состояниями, т.е. один такт дискретного времени. В программах для ПЛК, судя по описанию, это работа программы от начала и до оператора END (если несколько программ, то сумма времен). А если в программе будет цикл. Да, не дай Бог, еще и бесконечный? Да, в ПЛК превышение цикла контролируется. Но если цикл нужен? У автоматов таких ограничений нет. Контролируется только такт дискретного времени. Автоматная программа выполняет только один шаг – переход из текущего состояния и после этого передает управление другому автомату. И в сумме эти шаги не должны превышать заданную величину дискретного такта. Это в синхронном режиме, т.е. с фиксированным значением дискретного такта. Но эта величина может быть и плавающей – режим асинхронной работы автоматов.
Вообще автоматом является управляемый объект, и его состояния (наливается, загружается, перемешивается...), а что там в программе происходит - дело пятое и уже тем более уровень программных инструкций не интересен.
Вообще-то речь о других автоматах. О математической модели так называемого преобразователя информации (см. Введение в кибернетику. Глушков В.М.). Да и любая книга на тему конечных автоматов поясняет, о каких таких автоматах идет здесь речь. Наш контекст - конечные автоматы, как формальная алгоритмическая модель для объектов, реализующих функции управления в форме [любых] алгоритмов. Это ПК, ПЛК и т.п. В процессе могут создаваться и модели объектов управления. Нет проблем. Иногда это очень даже нужно (например, для адаптивного управления). И здесь уже нужно подкорректировать свое понимание понятия "состояния". Оно может отождествляться с теми процессами, что упомянули Вы (наливай и т.п.) , но совсем не являться ими.
По поводу Дельты, это нормальная альтернатива в современных условиях для систем среднего класса. Но у них тоже сроки поставки конские.
Все так. Но заменить чем-то не очень реально. Остается ждать и надеяться, т.к. с другой движухой - в сторону замещения как-то не очень... Печально, но факты вещь упрямая.
По поводу Дельты, это нормальная альтернатива в современных условиях для систем среднего класса. Но у них тоже сроки поставки конские.
Младшим их сериям DVP - до среднего класса ПЛК как до Луны пешком. Я сказал, что они убогие (упомянутые в статье) почему
Они древние
Медленные - 25MHz. Статья про разборку
Обкусанная память программ - 12к шагов =)
Софт для программирования времен Windows 3.1 и возможностей - мало (недавно вышел новый, но не для всех серий, лишь AS200/300)
Коммуникационные возможности и возможности расширения - а это именно то, что важно для среднего класса - ниже всех похвал, даже порты связи неизолированные.
Сейчас есть китайские клоны S7-200, Mitsubishi FX, и сонма контроллеров под CodeSys 3. Это все гораздо лучший выбор из-за нормального софта, производительности и расширяемости.
"Древность, обкусаность, убогость" .. вам, милейший Симаргл, стоит поучиться корректности общения, а не другим пенять. DVP на своем месте прекрасно работает. Экскаватором клумбы не сажают.
Ну я так думаю, что контроллер на некорректное обращение не обидится =)
Но так то Вы правы, лопата и лук и стрелы тоже на своем месте прекрасно работают.
Но какие эпитеты Вы предпочли бы услышать для контроллера, сравнимого (даже сильно слабее), с контроллером S5-115U выпуска 1989г ?
Какие прекрасно сохранившиеся останки!
Какая винтажная архитектура!
Это прямое наследие древних мастеров!
Я привел примеры нормальных контроллеров того же класса.
Ну, мерять этими, ну Вы понимаете о чем идет речь, как негоже. Да, DVP по нынешним меркам слегка устарел. Так Дельта уже подготовили им смену. Если уж что осуждать, обсуждать, то уже это. По мне серия AS много мощнее и языков побольше поддерживает. Так что почти норм. Но, например, производство инертно и тупо ставит то, что уже проверено. Им, порой, не нужны ни новые контроллеры, ни уж тем более новый тип (даже пусть "нормальный") контроллеров. Это все в их понимании источник лишнего геморроя. Так что и DVP иногда не самый худший вариант. Но я так на стороне AS. И уже почти согласились, но вот только "конские сроки поставки"... Если кто-то не решит эту проблему, то так и до коллапса недалеко...
контроллер не обидится, я не скажу малышу )) но мне было неприятно. а после мучений с Сименсом, Юнитроником и особенно - с Омроном, я стал правоверным Дельтовцем. Эпитеты я бы предпочёл технические, не эмоциональное субьективное мнение, типа "отстой этот ваш бульдозер, уже давно теслу изобрели" .
А в отместку я сделаю Вам больно: в макросах HMI Дельты я использую оператор GOTO !!!! и он таки отличнейше работает ))))))
Полностью согласен.
Например, я сейчас работаю в основном на DVP. Наследие прошлого, так сказать :). Но это то, что реально ставится на линии. Но параллельно я проработал варианты на AS200 и т.д. Жду только, когда практика подтянется. Времена, правда, мутные. Теоретически мы готовы, а вот практически как-то ... так - не очень.
Автор! Для реализации конечных автоматов в ПЛК есть шаговое программирование. Изучаем объекты S и команды STL, SET, RET.
Я по наивности, уважаемый собеседник, тоже так поначалу думал. Мне в наследство досталась для сопровождения программа, где этого добра было ... "по самые не могу". Но потом разобрался и ... с результатом Вы знакомы. Вас он, может, и не впечатляет, но ... пошаговое программирование Вам в помощь. До автоматов Вам еще, похоже, шагать и шагать ;) Мне это "пошаговое программирование" вот где, когда приходится возвращаться к старому проекту. Слава Богу, что это делать приходится все реже и реже и реже... Спасибо здесь автоматам. Вот тем, которые я описал. Вот как-то так.
Во-первых, не "пошаговое", а "шаговое" программирование.
Во-вторых, видимо, с КА я знаком лучше, чем автор статьи.
---------
> Автоматная программа выполняет только один шаг – переход из текущего состояния и после этого передает управление другому автомату
В теории- да, а как на практике это сделать, в ПЛК? Ведь в ПЛК программа выполняется вся, от начала и до конца, без пропуска команд (если не используется JMP, надеюсь с IL все знакомы?).
В теории- да, а как на практике это сделать, в ПЛК? ...
Все просто. Да, выполняется вся. Но реально будет работать код только для текущего состояния.
Ну, хорошо. Обратимся за помощью к гуру КА (я это серьезно)...
Пусть я изобрел велосипед и не понял этого. Так давайте разберемся с "шаговым программированием". Где в нем автоматы? Где в нем компоненты, присущие автоматам: множество состояний, функции переходов, выходов. Вот то, что я знаю о нем:
Пусть S-ки - это аналог состояний, а команды типа STL S<N> .- это некое состояние SN
Пусть SET S<N> это переход в новое состояние S<N>
Пусть даже код в неком S<N> от самого SN до команды SET SN - это аналог функций переходов/выходов
Я ничего не упустил?
Это и есть автомат? Это и есть автоматное программирование? А то, что я изобрел и есть велосипед. Переизобрел, так сказать, то, что есть?
Не совсем так..
Состояние автомата хранится в S. Если шаг активен, то выполняется код справа от STL. Команда SET устанавливает номер активного шага.
![](https://habrastorage.org/getpro/habr/upload_files/6e2/de7/83e/6e2de783ec5b004b03d8a5b8b5571974.png)
Кстати, активными могут быть несколько шагов (один из способов псевдопараллельного выполнения).
![](https://habrastorage.org/getpro/habr/upload_files/bde/b5b/8e4/bdeb5b8e4dee7aa852eb92125a7dc514.png)
Выключение режима шагового программирования осуществляет команда RET.
![](https://habrastorage.org/getpro/habr/upload_files/deb/e6a/5be/debe6a5be0e39e4e9068ce8155ffd304.png)
В основе шагового программирования лежат сети Петри, частным случаем которой являются автоматы Мили и Мура.
Собственно, я и без спец.инструкций так пишу =)
Точно так не получится.
Активация новых шагов предварительно автоматически очищает предыдущие активные шаги, так что если самому писать подобным образом, то понадобятся лишние команды на сброс активных шагов.
И мы опять возвращаемся к вопросу: зачем повторять то, что уже есть в ПЛК? Как минимум, напрасно тратится память и время ПЛК.
Да, вроде, я и почти о том же выше написал. Но... как бы и все понятно, но начал было, используя пошаговое программирование, создавать триггер, и ... если честно, - затык полный (: А проверить бы хотелось. Не смогли бы Вы набросать его код по аналогии с моим? Был бы признателен.
Теперь еще. Используя S-ки можно создать один большой автомат. Вроде бы, используя псевдопараллелизм, о котором Вы пишете, можно даже создать даже параллельные (псевдопараллельные) автоматы. Собственно это мне и надо - множество параллельных автоматов для того же триггера. Но как-то не "не точится у Данилы-мастера каменный цветок" ;)
Так что очень рассчитываю на Вашу помощь в этом деле. А то как-то вопрос повисает в воздухе. Можно ли, используя пошаговое программирование, создать нормальный RS-триггер?
Теперь о сетях Петри. На мой взгляд сравнивать их с автоматами как-то не очень. Петри модель вероятностная. Мы рассматриваем автоматы детерминированные. Исходя из этого, ну, ни как автоматы Мили и Мура не могут быть их частным случаем. Хотя у того же Питерсона (книга, кажется, Сети Петри называется) доказывается эквивалентность сетей Петри и автоматов. Но все это достаточно мутно, т.к. уж больно много вариантов сетей Петри и всяких нюансов в их работе. Проще сетей Петри совсем не касаться ;)
Хотя было дело я на автоматных сетях реализовал сети Петри... Но уж больно давно это было...
Может, все таки, чтобы не растекаться, попробуем - "шаговый RS-триггер"? Заранее спасибо.
> Можно ли, используя пошаговое программирование, создать нормальный RS-триггер?
Что есть "нормальный триггер"?
Ещё раз повторю, что это называется "шаговое программирование". Зачем коверкать термины, нравится, что ли?
..."нормальный триггер"?
Теперь повторюсь уже я :) В контексте нашей беседы - это асинхронный RS-триггер. Ссылка на схемы триггеров из Вики была приведена (см. выше схемотехнике триггеров больше ).
Наша задача смоделировать его поведение, в идеале повторив его структуру, т.е. число элементов, их поведение и связи между ними. Т.е. аналогично тому, как это описано в статье. Ну, и затем протестировать его на соответствие поведению реального триггера. О том, каким оно должно быть также описано в статье.
...зачем коверкать термины, нравится, что ли?
Ну, прошу прощения. Как-то автоматически случилось. Постараюсь больше не нарушать... Но если уж придираться, то, действительно, термина "шаговое программирование", похоже, нет. Я его тоже не нашел, как и те, которые пытались здесь его найти ранее. Понятие "шаговое реле" еще можно найти - в документации, а вот "шагового программирования" не обнаружил даже там. Может, это Ваша инициатива так его называть?
У RS-триггера есть запрещённое состояние. Как его разруливать? Какое исходное состояние устанавливать? Нет термина "нормальный триггер".
----
> Может, это Ваша инициатива так его называть?
Нет, не моя.
![](https://habrastorage.org/getpro/habr/upload_files/7a4/32a/5df/7a432a5df7141c5d9581500aafa9b5b2.png)
![](https://habrastorage.org/getpro/habr/upload_files/da7/151/3f6/da71513f67d04734ff719061faab73f7.png)
...Нет термина "нормальный триггер".
Давайте не будет придираться к словам.
У RS-триггера есть запрещённое состояние. Как его разруливать? Какое исходное состояние устанавливать?
Нет у триггера запрещенных состояний. Нет в теории конечных автоматов понятия "запрещенные состояния". Но есть - "недостижимые".
У триггера все состояния достижимые. Его модель со всеми состояниями и как они достигаются описана в статье. В данной статье дана его реализация на ПЛК на языке LD. Она работает в точности с тем, как доказано формально и подтверждается практикой реального триггера. И, кстати, приведенная реализация разруливает в легкую состояния, которые кто-то по недомыслию назвал "запрещенными". Их запретить невозможно. Таково уж поведение асинхронного RS-триггера. И это поведение никак не изменить.
Поэтому специально "разруливать" не надо. Все должно получаться само-собой. Ну как в представленной реализации или как в реальной схеме RS-триггера. Особенно в последнем случае, ведь, ни кто и ни что не разруливает?
А что, у Вас в "пошаговом программировании", как и у меня, тоже не получается "каменного цветка"?
в ПЛК есть шаговое программирование
А можно ссылочку, а то гугл не знает.
А объекты в разных контроллерах разные называются похоже.
Это надо смотреть док-и на программирование на сайте Дельты. Но только под DVP (WPL Soft). Под AS (ISP Soft), кажется, уже такого нет. Могу, правда, ошибаться, т.к. данной возможностью не пользуюсь и не интересуюсь. Ни к чему.
Да, Сименс некоторые вещи называет не так, как они названы в МЭК 61131.
В данном случае, это эрзатц-SFC от Дельты, в Стандарте этого нет.
Чего нет, SFC? Вот он:
![](https://habrastorage.org/getpro/habr/upload_files/24f/9ab/140/24f9ab1408d881c714c8d8680568bd77.png)
Поддержка SFC в ПЛК требует реализации шагового программирования, так что всё вполне стандартно, просто не все это знают.
Говоря о стандартах, рекомендую изучить его:
![](https://habrastorage.org/getpro/habr/upload_files/612/089/a8a/612089a8aec89b22558dfa7cd2d86e8e.png)
Нет шаговых реле и команд дельтовских STL, SET, RET. См начало треда.
Кстати, этот стандарт уже нашел преемника - IEC 61499
А чем не устроили стандартные, то есть определённые в стандарте, триггеры?
![](https://habrastorage.org/getpro/habr/upload_files/281/7c6/63d/2817c663d121a935f18d2e93a29c10e8.png)
Ну вот, "наша песня хорошо - начинай сначала".
Да не триггер мне нужен, а пример, на котором можно протестировать свойства созданной модели параллельных вычислений. Триггер для это подходит просто великолепно. Я не знаю других таких же примеров. Чтобы был такой простой и так качественно тестировал. Таковы уж его свойства, связанные с наличием обратных связей у параллельных процессов.
Если, например, "шаговое программирование" сможет реализовать триггер, а его тестирование покажет ошибочность его работы, то такое программирование ни к черту не годится. Триггер - элементарный тест на параллелизм. Все и точка. Не больше и не меньше. Еще и еще раз. Это мог бы быть и другой пример Не триггер. Но лучше его нет. Если кто-то предложит лучше - то будет реализовать его и его тестировать. Ну, вот как-то так. Неужели такая мысль так туго доходит. Дело не в триггере, а в его свойствах.
Пробежался по постам.
> Но это тоже не триггер, конечно.
Насколько помню, триггером называют элемент, обладающий свойством сохранять своё состояние при снятии управляющих сигналов, причём, это состояние должно быть различимо.
Схема на рисунке ниже обладает свойством сохранять своё состояние при снятии управляющих сигналов, потому и называется "RS-триггер", в которой вход inR имеет приоритет на входом inS. Назначение приоритета необходимо, иначе невозможно будет различить состояние триггера при inS=inR, когда Q=nQ.
![](https://habrastorage.org/getpro/habr/upload_files/1d9/091/827/1d909182737d1bfff81d7034e4ef0d5a.png)
Идеальный RS-триггер не может работать в силу своей структуры. Он ни в одной программе моделирования электронных схем не работает, кстати. Обязательно нужна какая-то неоднородность в управляющих сигналах или поведении элементов, образующих триггер, чтобы триггер перешёл в устойчивое, а ещё лучше определённое, состояние, то есть Q#nQ. В программе ПЛК эту неоднородность реализуют просто путём определения порядка вычисления выходных сигналов и предварительным задания начальных значений входных сигналов (обычно, "0"), или привлечения при маркера первого цикла.
А городить огород на туевой хуче элементов для получения аналогичного результата, ИМХО, горе от ума.
Учитесь внятно говорить, чего вы хотите.
В таких случаях обычно говорят - "поучайте лучше ваших паучат". Но не буду. Если я кого-то не убедил, то вина, безусловно, только на мне ;).
Если бы мне нужен был именно триггер я создал бы его примерно таким:
![](https://habrastorage.org/getpro/habr/upload_files/00b/ce3/dbf/00bce3dbfc6269ba7e8ff032e89974c3.png)
Просто, надежно, понятно. Нет неясных приоритетов и т.п. заморочек... Переключения выполняются "нулем" установочных сигналов. Выход nQ можно убрать. И это будет уже аналог стандартного триггера. И тогда, действительно, зачем городить огород: взял стандартный и пользуйся.
Ну, а поскольку мои описания работы и подход к его реализации RS-триггера Вас не устроили, то посмотрите у К.Фрике Вводный курс цифровой электроники. Издание 2-е, 2004 г. параграф 7.4. Анализ с учетом задержки вентилей. У меня, безусловно, другой подход, но результаты почти совпадают (почти). Но Вам может этот вариант больше понравится своей внятностью ;).
Люди добрые подскажите по базовым вещам: ISPsoft AS200 ST как конвертировать WORD_TO_DWORD и т.д.?{DWORD}A := {DWORD}A + {WORD}D10;
P.S. В документации вижу только что напрямую нельзя складывать, а как преобразовать ни слова.
P.S.2 А есть какой ни будь толковый форум по дельтам и софту?
Жаль не могу подсказать сейчас, работаю в полях без ноутбука с документацией. Попробуйте позвонить в Стоик, там толковые инженеры поддержки.
+7 (965) 357-50-53 (сервис)
Форума совсем хорошего (быстроответного) не встречал
Удачи!
в файле: ISPSoft 3.16\sysLib\StdLib.lib нашлось WORD_TO_DWORD и тд, но как этим пользоваться?
Попробовал. ISP ругается, не опознаёт операцию WORD_TO_DWORD.
кажется нашёл обходной путь - конвертировать типы не нужно, нужно только соблюсти правило, что слева от оператора присвоения была переменная не "короче", чем справа. Т.е. Var1_WORD = Var2_DWORD+VAR3_DWORD не сработает.
Сначала вы присваиваете значение переменной А типа WORD в переменную В типа DWORD (вроде "удлинняем" её), а потом уже делаете операции с В какие нужно.
Вот ниже пример, я сложил А=1 и D=1 000 000 000, ISP проглотил. Попробуйте.
![](https://habrastorage.org/getpro/habr/upload_files/789/78b/cc2/78978bcc295ccda880ff212a5b907e1b.jpg)
Так то можно, но мы на ровном месте огребли кучу геморроя: для каждой "левой" переменной формулы обьяви временную переменную + лишняя строка с присвоением
P.S. тут багу поймал(бл.н а ведь еще и не начинал писать код): с каких пор DWORD стал знаковым?
![](https://habrastorage.org/getpro/habr/upload_files/5e3/1fa/53b/5e31fa53b1ed404065562d0fc122e306.png)
P.S2. Да еще и не одну:
железо: DVP-12SE + DVP-16SP + DVP-16SP
в коде копирую регистры в битовую область IO(и наоборот тоже самое кстати):
BMOV D0 K3Y0 7
по документации контроллер оккупирует под встроенный ВВ Y0 - Y17(The PLC occupies 16 input points (X0~X17) and 16 output points (Y0~Y17). The extension
input point starts from X20 and extension output point from Y20.), однако!:
Y0 - Y3 = D0.0 - D0.3
Y20 - Y27 = D1.4 - D1.11 (КАКОГО ЛЕШЕГО???)
Y30 - Y37 = D2.0 - D2.7
мдяяя... я про баги писал в Стоик, они официальные представители, перенаправят куда надо. Если будет желание - поговорите с Владимиром Остаповым, очень грамотный спец,рекомендую. Может и про конверсию типов подскажет.
нашёл вот тут https://content.helpme-codesys.com/en/CODESYS Development System/_cds_operator_convert_integer.html
такое описание формата:
![формат оператора конверсии формат оператора конверсии](https://habrastorage.org/getpro/habr/upload_files/fa7/a8e/4c8/fa7a8e4c8c3897e19db8389674edee7c.jpg)
так что пишем правильно. видимо, у Дельты как-то обрезан функционал..
Кстати, а у вас DVP-SE даёт писать программу на ST? у меня нет
Со Стоиком(deltronics.ru) есть нюанс: "Мы не оказываем техподдержку оборудования, купленного не у нас. Обратитесь к продавцу."
Вот, как просто! Автоматы в деле. Для ПЛК фирмы DELTA