Русский
Русский
English
Статистика
Реклама

Siemens

Владимир Китов Сначала думал, что не смогу в капиталистической системе работать

15.07.2020 20:18:51 | Автор: admin


Владимир Китов уже рассказывал о работе в ГВЦ Минморфлота СССР и ЦНИИ Монолит, мультитерминальном мониторе для ЕС ЭВМ, истории АСУ в СССР, встречах с выдающимися советскими учеными-кибернетиками. В заключительной части интервью Владимир Анатольевич вспоминает IT 1990-х и постсоветский период своей карьеры: работу в DEC, SIEMENS, Техносерв, IBS, Fujitsu, а также увлечение историей и театром, стихи о кибернетике и дружбу с Леонидом Филатовым .

DEC


В самом начале 1991 года корпорация Digital Equipment Corporation (DEC) тогда главный конкурент IBM решила открыть представительство в СССР. В Советском Союзе компьютеры ЕС ЭВМ были аналогами компьютеров IBM 360, а СМ ЭВМ компьютеров DEC. DEC делал великолепный компьютер PDP 11/70. Я в марте 1991-го прошел пять собеседований и с апреля стал у них работать. Кстати, был первым россиянином, принятым на работу в московское представительство. Не исключаю, что во многом благодаря тому, что руководил созданием ОБИ продукта, конкурировавшего с системой CICS IBM.

Принимали меня на работу в представительство DEC в России на должность начальника отдела ИТ-проектов, но через полгода переориентировали на должность руководителя направления Наука и образование. Первая моя визитка DEC в СССР.


Значок, выпущенный DEC в 1991 году. Через пару лет синий фон логотипа Digital был заменен на бордовый

Когда я пришел в DEC, у них было 118 000 сотрудников в нескольких десятках стран мира. Мощнейшая корпорация, но в какой-то момент ее менеджеры, как говорится, задремали. Сначала в 1998 году DEC была съедена Compaq Computers Corporation, но та подавилась в 2002-м ее в свою очередь съел Hewlett-Packard.

Но это будет еще через восемь лет, а пока начальником у меня был обаятельный итальянец, который фактически руководил мной дистанционно из Турина. В Москву приезжал нечасто, но обязательно с полуторалитровой бутылкой граппы для меня. Удалось создать неплохой отдел, пригласив Володю Дьяконова, Игоря Калинчева, других толковых программистов. Работы у моего отдела было весьма мало не было заказов, т. к. Россия страна квалифицированных и знающих себе цену программистов, а в то время, по советской традиции, каждая организация привыкла делать свои ИТ-проекты сама. Нет заказов на проекты, значит нет и прибыли. А при капитализме такие подразделения не нужны.


Впервые месяцы российское представительство DEC арендовало несколько комнат вофисе компании Роллс-Ройс впереулке Садовских (сейчас Мамоновском) рядом сТверской улицей. Нафото сотрудники московских обеих компаний: крайний слева первый генеральный директор DEC вСССР Роберт Крауз, крайний справа Владимир Китов. Роберт Крауз выпускник Корнельского университета, доприхода вDEC работал начальником отдела культуры посольства США вМоскве.

Возвращаюсь я из полуторамесячной стажировки в DECВеликобритания, а моего отдела уже и не существует. Уволили и шефа-итальянца, перекрыв мне тем самым канал регулярного поступления граппы, и остальных сотрудников отдела тоже. А про меня сказали: Владимир пусть пока на фирме побудет, он нам может пригодиться. Формально меня прикрепили к техническому центру DEC, который располагался в технопарке на ВДНХ. Пару месяцев я болтался практически без дела. Если провести аналогию с футболом, тогда в команде DEC я был тем, кем позднее стали Фернандо Торрес в Атлетико и Фрэнк Лэмпард в Челси сотрудником без определенных занятий. Изредка выполнял разовые поручения: съездил на завод в Зеленоград, чтобы оценить целесообразность его покупки DEC для выпуска компьютеров; участвовал в переговорах с руководством технопарка насчет расширения арендуемых площадей для нашего техцентра; организовал в ЦМТ небольшую экспозицию компьютеров DEC и т. д. А в основном, целыми днями изучал техническую документацию по дековской технике и совершенствовал английский. Потом я его выучил неплохо, даже думать начал на английском. Жизнь заставила, т. к. все совещания на языке, и если ты не понимаешь, о чем говорят, то ты и оказываешься виноват в том, что бизнес пробуксовывает. Значит, скоро могут выгнать. А на улице не меньше десятка претендентов, которые только этого и ждут, чтобы радостно занять твое место.

Через пару месяцев эта неопределенность закончилась так. Вызывает меня в свой кабинет генеральный директор представительства г-н Питер Шипош. Знакомит меня с американцем по имени Роберт Дженевски и говорит, что Боб формирует европейскую команду Наука и образование, а мне предлагается возглавить это направление в России. Я, не думая слишком долго, согласился, хотя многие коллеги отговаривали, справедливо утверждая, что дело это не только непростое, а прямо скажем, и рискованное. Но меня, бывшего советского научного работника, как раз привлекало то, что здесь все зависит только от тебя самого. Неважно, например, член ты КПСС или нет. Поработал хорошо молодец, награды тебе и премии, а плохо пенять не на кого, освобождай место для другого смельчака.


Укрепляя связи корпорации DEC с российской наукой и образованием. Проректор МГУ Н. И. Коротеев, Главный ученый секретарь РАН Н. А. Платэ, В. А. Китов, доктор Р. Боерс (Голландия), ректор МГУ В. А. Садовничий, директор ИРЭ Ю. В. Гуляев, Президент РАН Ю. С. Осипов, декан химфака МГУ Ю.В.Лунин

В московском представительстве DEC было 5 основных направлений. Помимо моего Наука и образование были еще направления нефти и газа, промышленных предприятий, транспорта и госструктур. Пятеро россиян-руководителей этих направлений тогда делали годовой план в несколько десятков миллионов долларов. Мы знали свою страну, ее порядки и развивали бизнес неплохо. А я-то сначала думал, что не смогу в капиталистической системе работать. До того, как меня на фирму взяли, думал, что при капитализме люди так напряженно работают, что я просто не выдержу. Решил, приду на несколько месяцев, посмотрю, попробую, а потом пусть выгоняют. В действительности задержался в DEC на семь с половиной лет, а потом еще почти пятнадцать лет на других фирмах оттрубил.

Работая в компании DEC, я не только руководил направлением Наука и образование, но и представлял фирму в российском отделении общества DECUS (Digital Equipment Computer Users' Society Обществе пользователей компьютеров DEC). В России DECUS объединяло несколько тысяч программистов и электронщиков, буквально влюбленных в дековские компьютеры. Я получал огромное удовольствие от общения с этими энтузиастами техники DEC. У меня была приятная обязанность, имея определенный денежный фонд, реально помогать членам DECUS проводить ежегодные конференции по обмену опытом. Мы собирались в Москве, в Питере и в известных наукоградах. Одним из излюбленных мест был уютный научный городок Протвино.

Владимир Китов во время работы в DEC на ежегодной американской компьютерной выставке SUPERCOMPUTING-1995 в г. Сан-Диего (США)

Надо еще сказать, что, работая на DEC, я всегда в душе оставался патриотом российской науки, выходцем из которой был. Тем более, в тяжелые 1990-е годы, когда на науку в стране денег не было, и многие мои приятели-ученые (особенно физики и химики) уезжали на Запад. Не ради колбасы, а потому что там были мощные серверы для компьютерного счета их научных задач. Поэтому я, как мог, обосновывал перед своими боссами необходимость помощи нашим научным организациям. Утверждал, что наша помощь фундаментальной российской науке очень важна для укрепления престижа корпорации в мире. Думаю, мои усилия были своевременны.

Достаточно вспомнить, что компания подарила мощные серверы мехмату и химфаку МГУ имени Ломоносова, МВТУ имени Баумана, МИФИ, а также сделала максимально возможные скидки на суперкомпьютеры для ИФВЭ (Протвино), ИПХФ (Черноголовка), ОИЯИ (Дубна), ИАТЭ (Обнинск) и других. В Обнинске торжественный запуск дековского Альфа-сервера был совмещен с днем с открытия памятника Фредерику Жолио-Кюри.

Кстати, в 1991 году во время моей стажировки в DECВеликобритания в городе Саутгемптон произошло мое первое знакомство с сетью. Мне выделили временное рабочее место с огромным монитором. Включаю его и вижу сообщение: Хелло, Владимир. Завтра после работы в столовой будет праздник божоле. Ты приглашен. Пришлось активно участвовать в популярном празднике молодого вина.


Владимир Китов во время работы в DEC

От Siemens до театра


Во второй половине 1997 года в штаб-квартире DEC близ Бостона местные ребята сообщили мне, что дела у корпорации идут все хуже и хуже. И как раз в 1998 году моего бывшего директора г-на Питера Шипоша пригласили работать в Siemens, одну из крупнейших корпораций мира. Ее крупное международное подразделение Siemens Nixdorf занималось производством и распространением компьютеров. Штаб квартира этой фирмы находилась в Мюнхена, а Шипоша поставили генеральным директором представительства в России. Он тут же мне позвонил: Владимир, хочу, чтобы вы работали у меня директором партнерской сети. Так я стал обладателем отличного кабинета, членом Совета директоров, да еще и костенштеллеляйтером Kostenstelleleiter одним из менеджеров, отвечающих за распределение бюджетов.


Владимир Китов перед входом в московский офис компании Siemens Nixdorf на улице Пресненский Вал

Вначале в Siemens обстановка для меня была весьма необычной. Я был воспитан на советских военных фильмах, а тут вокруг немецкая речь и масса немцев. Постепенно я стал забывать английский язык. Оказалось, что все здесь в московском представительстве немцы из ГДР, у многих из них русские жены. Они прекрасно говорили по-русски, а английского многие не знали вообще. Люди неплохие не лучше и не хуже нас. Но система работает четко, как хорошо смазанный механизм, дело идет, сплошной орднунг (порядок значит). Со временем, у меня сложились хорошие рабочие отношения с немецкими коллегами, в частности, с господами Мюллером, Вольфом, Борманом и Гютлером.

Потом я работал в компании Техносерв, одном из крупнейших в России ИТ-интеграторов. Вначале меня пригласили тоже на должность директора по партнерам. Причем Алексей Николаевич Ананьев лично сказал, что готов меня принять по упрощенной схеме. Но я ответил, что хочу приниматься на работу, как все где бы меня еще расспрашивали о подробностях биографии, подключив к детектору лжи? Такую уникальную возможность я никак упустить не мог.

У Техносерва была большая партнерская сеть по всей стране, и я за нее отвечал. Меньше чем через год шеф назначил меня одним из трех своих замов. В то время в Техносерве систему руководства понять сразу было сложно. Было два генеральных директора и аж четырнадцать их заместителей. Должность владельца компании Алексея Ананьева называлась Председатель совета компании Техносерв, и у него уже было два заместителя: по технологиям и по продажам. Я стал третьим по маркетингу. Это была вершина всей моей производственной карьеры. Ананьев был олигархом, он входил в список российских миллиардеров Forbes-50. Он практически каждый день приезжал в офис на своем лимузине (не исключаю, что бронированном), и мы вчетвером регулярно совещались у него в кабинете, решая текущие дела.


Объединенный институт ядерных исследований в Дубне. Владимир Китов, академик Владимир Кадышевский и Алексей Ананьев

Об Алексее Николаевиче у меня осталось самое благоприятное впечатление как о хорошем семьянине, деловом и тактичном человеке. По крайней мере, в отношении себя я не припоминаю никакой начальственной грубости или пренебрежения. Насколько я могу судить по личному общению в знакомствам клубе АП КИТ, многие из руководителей российской ИТ-индустрии умные, интеллигентные люди. В частности, такими я точно могу назвать Наталью Касперскую, Игоря Ашманова, Ольгу Дергунову, Владимира Баласаняна, Бориса Нуралиева, Тагира Яппарова, Игоря Морозова, Давида Яна. И, конечно, не только их.

Помню, что одним из первых моих дел в Техносерве была организация 10-летнего юбилея компании. Как раз и у IBM был юбилей 90, а Техносерв в России тогда был их основным партнером. Убедить всех начальников, что праздновать надо совместно, было несложно. Сняли бизнес-центр Правительства Москвы и на его фасаде повесили придуманный мной громадный транспарант IBM и Техносерв 100 лет вместе.

Потом я попал в одну из крупнейших российских ИТ-компаний IBS Information Business Systems. Там я познакомился с двумя великолепными специалистами и замечательными людьми: Сергеем Павловым и Александром Котовым. С ними мы создали группу компаний Innoway/Infosuite, которая и сейчас успешно занимается ИТ-проектами.

В заключение карьеры в бизнесе я несколько лет работал в Fujitsu-Siemens международной компании, возникшей в результате трансформации Siemens-Nixdorf. Потом она стала компанией Fujitsu, т. к. японцы выкупили долю Siemens и стали единоличными владельцами, хотя все заводы по производству компьютеров оставили в Германии. Т. е. просто сменили вывеску.


Владмир Китов в августе 1991 года. Страница из домашнего фотоальбома

За капиталистический период своей трудовой деятельности я работал в трех иностранных компаниях: DEC (США), Siemens (Германия), Fujitsu (Япония) и трех российских: Техносерв, IBS, Innoway. Придя в апреле 1991 года в американскую корпорацию DEC, был уверен, что буду с треском уволен месяцев через шесть, не выдержав высокого трудового капиталистического ритма. Хотелось просто попробовать. Оказалось, что и мы тоже умеем упорно и инициативно трудится. Меня, например, три года награждали чемпионской бронзовой доской DEC 100 как победителя капиталистического соревнования, каждый раз сопровождая это солидной премией и бесплатной поездкой вместе с семьей. Кстати, тремя бронзовыми досками за все время существования представительства DEC в России не награждался больше никто. Корпорация Siemens за результативную работу наградила меня швейцарскими золотыми часами с сапфировым стеклом. Но главным результатом капиталистической деятельности считаю то, что я приобрел большое количество новых замечательных и интересных друзей, с которыми продолжаю поддерживать отношения и поныне. Наверное, потому что большую часть из этих двадцати с лишним лет я руководил направлением Наука и образование. Т. е. много общался с учеными, преподавателями и литераторами, среди которых очень много интереснейших людей, тем более в России.

Когда я уже работал в компании Fujitsu, моя заботливая жена Оля неоднократно предлагала мне уволиться. Потому что в девять утра на работу приходишь, а уходишь, как правило, в девять вечера уходишь. Надо же годовой план по бизнесу делать. Каждый финансовый год новый бой. Жене пообещал: Ладно, как 60 лет исполнится уйду на пенсию. Но в 60 лет не решился, т. к. понимал, что обратной дороги нет. Покинул фирму в 62, но быстро понял, что без работы жить скучно. Тогда решил, что работать буду, но уже не ради денег, а ради интереса и чего-то новенького для души. Так я стал замдиректора по развитию бизнеса музыкального театра Экспромт под руководством замечательной актрисы Людмилы Ивановой.

Театр Людмилы Ивановой


Театр в моей жизни появился неслучайно. Я и мои товарищи всегда интересовались литературой и искусством. В молодые годы регулярно (раза три в месяц) ходили в театр, штурмовали билетные кассы Таганки иСовременника. Помню, провели ночь в очереди у музея изобразительных искусств имени Пушкина, чтобы попасть на просмотр привезенной из Лувра Джоконды. Дружил с интересными хорошими людьми.


Владимир Китов, Валерий Миляев, Людмила Иванова, ее подруга и Ольга Китова жена Владимира Анатольевича

История моего появления в театре Экспромт такова. Я жил с родителями наискосок от Кремля, в так называемом Доме на набережной или Доме правительства, описанном в романе Юрия Трифонова. У дома был музей, и я считаю себя его другом. Директор музея вдова писателя Ольга Романовна Трифонова. Поэтому, когда музею исполнялось 20 лет, я участвовал в организации юбилея, был ведущим юбилейного вечера, который проиходил как раз в театре Экспромт у Людмилы Ивановой. У Людмилы Ивановны был прекрасный муж, замечательный физик Валерий Александрович Миляев, известный бард. Он автор популярной песни Приходит время, помните:

Приходит время, с юга птицы прилетают,
Снеговые горы тают, и не до сна.
Приходит время, люди головы теряют,
И это время называется весна.

Тут же, нас как-то потянуло друг к другу. Мы подружились с Валерой и Милой. Потом Людмила Ивановна говорит: Почему бы тебе с твоим опытом в бизнесе не пойти ко мне заместителем директора по развитию. Мне стало интересно. Особенно нравилось смотреть, как репетируют артисты, как создается спектакль.

Параллельно меня пригласили в Институт истории естествознания и техники возглавить направление истории информатики и компьютеров. Несколько месяцев я работал в двух местах, а потом понял, что надо что-то выбирать. История компьютеров для меня это вся моя сознательная жизнь. Поэтому я ушел из театра, но с Валерой Миляевым и Людмилой Ивановой дружить мы продолжали.

Пытался я писать стихи


В институте истории естествознания и техники ИИЕТ имени С. И. Вавилова РАН работало достаточно много всесторонне развитых людей, поэтов и бардов. К 80-летию ИИЕТ решили издать сборник стихотворений сотрудников. Есть там и мое, история написания которого следующая. Однажды коллеги из Политехнического музея, с которым мы очень дружим, написали мне про моего соавтора и друга Валерия Владимировича Шилова: Узнали мы, что он Поэт и вы стихи писать пытались.

Так как мы с Валерой считаем, что оба дилетанты, то я обиделся, что он Поэт, да еще и с большой буквы, а я всего лишь пытался. Тогда и написал стих Ответ коллегам из Политехнического музея, которое опубликовали в сборнике.

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

Босой, забитый, крепостной,
Не посещавший школу,
Умен, смышленый, озорной,
С селянками веселый.

Свой ум потомкам передал
Да здравствует генетика.
И в СССР, не без труда,
Признали кибернетику!

Напомню, что Анаталой Иванович Китов автор первой в СССР позитивной статьи о кибернетике.

Я и персональные компьютеры, а также из воспоминаний


Мое знакомство с ПК состоялось конце 1980-х годов. На работе, а я уже работал в Институте кибернетики заведующим лабораторией компьютерных сетей, мне выделили довольно дорогой ПК венгерского производства. В апреле 1991 года меня приняли на работу в московское представительство корпорации Digital Equipment Corporation (DEC) и довольно скоро выдали ПК, но уже ноутбук, по нынешним меркам, конечно, допотопный. Потом в 1994-м году мой сын, который учился в 5 классе, заключил со мной соглашение: Если я закончу учебный год на одни пятерки, ты мне купишь компьютер. Пришлось купить ему ПК, хоть я и опасался, что он будет его отвлекать от школьных уроков. Но он никогда не играл в компьютерные игры. Довольно быстро научился программировать на Паскале и сам написал компьютерную трехмерную игру аналог популярной в то время стрелялки Вулф. Три этих компьютера были первыми ПК в моей жизни.


Владимир Китов во время работы в DEC

Вообще я видел много ЭВМ разных поколений: одно из воспоминаний детства, конечно, первая советская серийная ламповая ЭВМ Стрела, которую я увидел где-то в 1956 году, заехав вместе с папой к нему на работу в ВЦ 1 МО СССР. Позже, когда я уже был студентом, компьютеры стали выглядеть уже довольно буднично. Мы, помимо обычных занятий в вузе, работали еще на ЭВМ Днепр-1 на военной кафедре. Программы и данные тогда хранились на перфокартах. И вот, однажды, у меня случилась большая неприятность я споткнулся, опаздывая на занятие, и колода перфокарт, которая была у меня в руке, разлетелась. Потом собрать их в нужном порядке было совсем непросто!

Сейчас, пожалуй, самое удивительное для меня современные мобильные телефоны. Вспоминается работа на больших ЭВМ-монстрах, а тут классный компьютер у тебя в кармане.

Что нас ждет в будущем


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

Уже сейчас с компьютером в кармане можно представить будущую тотальную компьютеризацию. Но как люди могли это предположить в далекие 1950-е годы при тех габаритах ЭВМ, той ненадежности вычислительной техники и техники связи?! Хотя иногда случались и казусы. В частности, когда Мстислава Всеволодовича Келдыша спросили, сколько нужно ЭВМ, чтобы решить задачи страны, он ответил: Наверное, шесть или семь. Компьютер тогда многими рассматривался просто как большой арифмометр. Посчитал ядерную реакцию, посчитал орбиту спутника и все. Но были и поистине гениальные прозрения.

Во второй половине 1960-х папе присылали пригласительные билеты на заседания Совета по кибернетике, организуемых его председателем Акселем Ивановичем Бергом в Московском доме ученых. По этим пригласительным на эти заседания бывало ходил я. Помню, как-то там обсуждался вопрос Может ли ЭВМ мыслить?. Берг считал, что нет, что она делает все по алгоритму. ЭВМ лучше человека играет в шахматы перебирает, очень быстро считает. Но человек обладает другими качествами. Например, интуицией. Один человек тогда высказал мнение, что Думающий компьютер создать не сложно. Его надо сделать так же, как устроен человеческий мозг. Но устройство человеческого мозга как раз остается одной из самых больших загадок природы.

Друзья и знакомые


Я обыкновенный человек и не думаю, чтобы упомянутые моменты моей жизни были бы кому-нибудь особенно интересны, кроме меня самого и моих близких. Но без этого контекста рассказ о работе был бы, как мне кажется, не совсем полными. Т. е. программировали мы очень увлеченно, но и об общем культурном развитии никогда не забывали. Прежде всего, мы старались следить за всеми публикуемыми книжными новинками: Евтушенко и другие шестидесятники, Солженицын, Булгаков, Хемингуэй, Фолкнер и другие.

В жизни мне необыкновенно везло на дружбу и со многими талантливыми интересными людьми. Еще до школы жил в одном доме на Таганке и ходил в прогулочную группу из семи детей (типа современного детского сада) с Ириной Родниной. У моего папы, сколько я помню, были персональные машины: Победа, Волга с оленем и без, но самый супер была трофейная немецкая машина премиум класса Horch, во время войны возившая Бормана. Громадная, с никелированными блестящими ободами, подножками и двумя запасными колесами по бокам. Когда папа приезжал домой обедать, его водитель катал на этом Хорьхе всю детвору нашего дома по двору.

Учился я в простой школе 497 близ высотки на Котельнической набережной. Директор нашей школы любила повторять: Володя Китов настоящий пионер!. Как председатель совета пионерской дружины и комсомольский секретарь я имел определенный авторитет не столько у соучеников, сколько у их знаменитых родителей: скрипача, народного артиста СССР Дмитрия Цыганова, писателя Константина Паустовского, композитора Бориса Мокроусова и других. С сыном народного артиста, солиста Большого театра Владимира Ивановского Сережей школьные годы я просидел за одной партой. Это давало нам неограниченное количество контрамарок в Большой. Мы могли позволить себе прийти на Князя Игоря, чтобы посмотреть половецкие пляски и после этого удалиться. До 6-го класса с нами училась будущая кинозвезда Наташа Гундарева. Незабываемыми для меня на всю жизнь были три визита к Галине Сергеевне Улановой мы договаривались, чтобы она посетила нашу школу.


Советские грамоты и рисунок коллеги, программиста Госплана Николая Пунина, нарисованный в 1974 году. Николай Пунин, женившись на дочери финского коммуниста, лишился работы в Госплане и стал профессиональным художником. Он рисовал плакаты к новым фильмам, а позже эмигрировал в США

Студентом почти каждое лето ездил в спортивный лагерь МЭИ Алушта, где по вечерам на танцах играла рок-группа Скоморохи во главе с Александром Градским. В начале 1980-х два года после свадьбы прожил на Пушкинской площади в доме, где сейчас Макдоналдс, а тогда было кафе Лира. Там мы как два автомобилиста и владельца Жигулей познакомились с соседом по подъезду народным артистом СССР Михаилом Ульяновым. Он был прекрасным собеседником, а еще помню, однажды ехал после работы с ним в лифте, а войдя в квартиру, включил телевизор и увидел маршала Жукова в его исполнении. Еще мы с ним вместе как-то посетили пункт приема стеклотары на Палашевском рынке: я убедил Михаила Александровича, что сдавать скопившиеся бутылки совсем не зазорно. Отесли по две полных сумки.

Судьба свела меня с добрейшей души человеком Сашей Стерниным известным в стране мастером фотодела, тогда фотохудожником в Театре на Таганке, сейчас театра Ленком. Саша подружил меня с гениально разносторонним человеком Леонидом Филатовым, дружба с которым продолжалась многие годы вплоть до его кончины, а с женой Лени Ниной Филатовой-Шацкой продолжается и по сей день. Леня, помимо творческих талантов, обладал еще и качествами настоящего друга, человеческой порядочностью и необыкновенной эрудицией. В области кино и театра это был человек-энциклопедия. А главной ценностью в жизни для него была Любовь, точнее любовь к его Нюсе и к книгам. Их отношения с женой как будто продолжались со сцены Таганки, где они исполняли роли Мастера и Маргариты. Кстати, я этот спектакль благодаря Филатовым смотрел около двадцати пяти раз. Жертвенность и самоотдача Нины во время Лениной болезни вызывают чувства глубокого уважения и восхищения.

Удивляюсь, почему на фоне однотипных современных сериалов не создадут фильма о великой любви Лени и Нины. Еще Леня очень любил книги, которые, как и многое в СССР, были страшным дефицитом и распределялись, как качественные продукты или однатровые шапки. Естественно, у Лени сложилась группа фанатов из числа директоров книжных магазинов. Бывало, он звонил: Володя, едем за книгами в книжный на Сретенку, и мы отоваривались по полной. Когда Леня с Ниной переехали в двухкомнатную квартиру, в качестве высшего признания дружбы и доверия он пригласил меня поучаствовать в священнодействии расстановке книг по шкафам с учетом эпох, жанров и авторов. Ну и, конечно, Леня поэт. Сочинять и печататься начал еще со школьной скамьи, живя в Ашхабаде. Однажды он написал:

В нашей пишущей стране
Пишут даже на стене.
Вот и я решил со всеми
Быть, конечно, наравне!


Владимир Китов, Нина и Леонид Филатовы, Галина Полякова-Юрова, Ольга Китова

Нам с моей женой Олей и, конечно, с Ниной, посчастливилось быть в числе первых слушателей многих его только что написанных произведений. В том числе, отрывков из сказки Про Федота-стрельца, удалого молодца.

***

Сейчас я с удовольствием работаю в РЭУ имени Плеханова доцентом кафедры информатики и старшим научным сотрудником Лаборатории искусственного интеллекта, нейротехнологий и бизнес-аналитики, а также стараюсь быть хорошим дедушкой трех моих внуков: Кати, Тани и Сережи. Работаю на кафедре, на которой раннее в течение 17 лет проработал мой отец, который тоже перешел в Плехановку, став пенсионером. Решающую роль в этом его переходе сыграл его друг с 1957 года профессор Константин Иванович Курбаков замечательный ученый и человек, с которым я продолжаю регулярно общаться. Кафедру информатики возглавляет моя жена, доктор экономических наук Ольга Викторовна Китова, под руководством которой трудится 48 сотрудников, функционирует Академический центр компетенции IBM. Недавно мы издали учебник Цифровой бизнес, ставший победителем всероссийского конкурса АКАДЕМУС в номинации Экономика и управление.


Владимир Китов с женой Ольгой Викторовной впрезидиуме Международной конференции имени А. И. Китова Информационные технологии иматематические методы вэкономике иуправлении, ИТиММ, 2019 г.

Российский экономический университет имени Г. В. Плеханова современный университет, входящий в ведущие рейтинги QS и THE, у него богатая история и талантливый коллектив, здесь учатся студенты из десятков стран мира. В последние годы в университете создан Институт цифровой экономики и информационных технологий, объединяющий кафедры и научные лаборатории, в котором обучается более 2 тысяч студентов. Ежегодно в РЭУ имени Плеханова проводится Международная научно-практическая конференция имени А. И. Китова Информационные технологии и математические методы в экономике и управлении, организацией которой я занимаюсь в качестве заместителя председателя оргкомитета. 15-16 октября 2020 года эта конференция пройдет в десятый раз, и будет посвящена столетнему юбилею моего отца А. И. Китова.
Подробнее..

HMI на основе Node-red и Scadavis.io

22.06.2020 20:08:04 | Автор: admin
В настоящее время в связи с ростом популярности концепции IoT и развитем сопутствующих технологий многие производители программного обеспечения для промышленной автоматизации используют это в своих продуктах. Доступ к SCADA-системам через web-интерефейс идея и реализация не новая. Еще лет 10 назад Citect scada позволяла это делать с помощью веб-браузера IE. Но идея IoT это не только доступ к ресурсам через web, а также возможность агрегировать различные сетевые проводные и беспроводные интерфейсы, совмещать различные уровни архитектуры: field, edge, cloud. В поисках возможных решений использования совместного open-source IoT edge платформы и SCADA системы я наткнулся на интересную связку платформы Node-red и SCADA-фреймворк scadavis.io

Scadavis.io


Начну описание scadavis с той информации, которая представлена в официальных источниках. На странице сайта scadavis.io указано: Powerful SCADA-like visualization tools, free-form synoptic graphics for real-time data display. A pure HTML5 solution, mobile friendly, framework agnostic, with no special server requirements needed. All your data and graphics stay on your servers and clients. (Мощные SCADA-подобные инструменты визуализации, сводные графики произвольной формы для отображения данных в реальном времени. Чистое решение HTML5, мобильное, независимое от фреймворка, без особых требований к серверу. Все ваши данные остаются на ваших серверах и клиентах.)

Далее представлены примеры страниц, которые можно спроектировать.

Затем идет информация о графическом редакторе построения экранных страниц SCADAvis.io Synoptic Editor, который можно преобрести в Microsoft Store.



Также на сайте показана таблица, в которой представлены планы использования Scadavis.io. Система имеет три плана: Basic, Pro, Enterprice. Основные отличия Basic плана: стоимость бесплатный, нет технической поддержки, исходный код расположен на SCADAvis.io.

Дисклеймер в данном абзаце я хочу показать файловую структуру проекта, которую мне было любопытно увидеть. Это никоим образом не презывает нарушать лицензионные права данной системы. Тем более список файлов лекго просматривается с помощью инструментов разработчика в консоли браузере.

На момент исследования набор файлов был следующий:
  • Основной скрипт synopticapi.js, в котором орпеделена функция основного объекта для работы с svg страницами находится на ресурсе scdavis.io.
  • На этом же ресурсе расположены скрипты symbol_webreflection.js, содержащий функции для работы с символами и их свойствами.
  • А также, насколько я понимаю, две проприетарные обфусцированные библиотеки o1.js и o2.js. Детально разбираться в них я не стал, так как особо времени и желания не было.
  • Фреймом для подключения библиотек и отображения визуализации служит synoptic.html файл, расположенный там же.

Подключение скрипта проекта, документация API и Synoptic Editor представлены на ресурсе scadavis.io/learn.html

Далее проект содержит ряд open source библиотек для работы с svg, с различной визуализацией и графиками:
  • Vega-min.js, vega-lite.js vega.github.io/vega С помощью Vega вы можете описать внешний вид и интерактивное поведение визуализации в формате JSON, а также создавать веб-представления с использованием Canvas или SVG.
  • snap.svg-min.js snapsvg.io SVG позволяет создавать интерактивную, независимую от разрешения векторную графику, которая будет отлично смотреться на экране любого размера.
  • jquery.min.js jquery.com jQuery это быстрая, небольшая и многофункциональная библиотека JavaScript.
  • d3.js d3js.org Сочетает мощные компоненты визуализации и управляемый данными подход к манипулированию DOM.
  • chroma.min.js gka.github.io/chroma.js Это небольшая библиотека JavaScript без внешних зависимостей для всех видов преобразования цветов и цветовых шкал.


Node-red


Node-red чрезвычайно популярная платформа. В просторах сети находится огромное количество статей и видеороликов по ней. На wikihandbk.com следующее определение Node-RED это инструмент визуального программирования для интернета вещей, позволяющий подключать друг к другу устройства, API и онлайн-сервисы. Сами авторы позиционируют Node-red как IoT edge платформу:

image

Установка данной платформы также не составляет труда на различный операционных системах и состоит из двух шагов:
  • Установка Node.js: nodejs.org
  • Установка Node-red: npm install -g --unsafe-perm node-red


В блоге Ricardo Olsen показаны шаги по интеграции системы Scadavis.io и платформы Node-red, а также представлены исходные файлы экранных страниц формата svg. Автор рекомендует использовать плагин для Node-red node-red-contrib-uibuilder, который позволяет создвать динамический веб-интерфейс, используя различные js-библиотеки, а также использовать веб-фреймворк VueJS.

image

Однако это не единственный способ, позволяющий построить пользовательский интерфейс на базе Node-red. Имеется достаточно популярный модуль, содержащий ряд нод для создания дашбордов в реальном времени от создателей самой платформы node-red-dashboard.

image

Виджет Template может содержать любые допустимые директивы html и Angular / Angular-Material.Этот узел можно использовать для создания динамического элемента пользовательского интерфейса, который изменяет свой внешний вид на основе входного сообщения и может отправлять сообщения обратно в Node-RED. С помощью ноды Template можно создать объект экранной страницы Scadavis, задать необходимые свойства, эмулировать поведение объекта и связать теги (переменные) экранной страницы с внешней средой

Создание SCADA-страницы с помощью Template виджета
<div id="office"></div> <script src="http://personeltest.ru/aways/scadavis.io/synoptic/synopticapi.js">var office = new scadavis({  container: "office", //Указание созданного ранее контейнера  iframeparams: 'frameborder="0" height="610" width="687"',  svgurl: "drawing.svg" //SVG страница});office.zoomTo(0.82); //Масштабирование изображения        //Эмуляция поведения тегов        setInterval(function () {office.storeValue("TAG2", 100 + Math.random() * 80);office.storeValue("TAG3", 120 + Math.random() * 60);office.storeValue("TAG4", 150 + Math.random() * 60);office.storeValue("TAG5", 110 + Math.random() * 30);office.storeValue("TAG6", 200 + Math.random() * 100);office.storeValue("TAG7", 130 + Math.random() * 40);office.updateValues();value = 130 + Math.random() * 40;}, 5000);</script>


В статье Node-RED Dashboard Template Examples (AngularJS) хорошо показаны примеры взаимодействия ноды Template с другими нодами, которые обмениваются сообщениями msg в контексте Angular Scope.
Допустим, мы ходим в качестве свойства объекта msg.topic передавать имя тега, а в качестве значения msg.payload. И при каждом событии изменения объекта msg обновляем объект SCADA с помощью методов storeValue и updateValues

 (function(scope) {        scope.$watch('msg', function(msg) {            if (msg)                 office.storeValue(msg.topic, msg.payload);                office.updateValues();            }        });        })(scope);    

Также используя пример с ресурса https://scadavis.io/learn.html и функционал ноды Template можно обрабатывать различные события SCADA-объекта и передавать их другим нодам, например так:
(function(scope) {substationsynoptic.on("click", function (event, tag) {    var v = substationsynoptic.getValue(tag);    if (event.currentTarget.id === "TAPUP")        substationsynoptic.setValue(tag, v + 1, false, false);    else        if (event.currentTarget.id === "TAPDOWN")            substationsynoptic.setValue(tag, v - 1, false, false);    if (event.currentTarget.id === "XCBROPEN")        substationsynoptic.setValue(tag, false, false, false);    else        if (event.currentTarget.id === "XCBRCLOSE")            substationsynoptic.setValue(tag, true, false, false);    if (v === true)        substationsynoptic.setValue(tag, false, false, false);    else        if (v === false)            substationsynoptic.setValue(tag, true, false, false);    scope.send( {'payload':{ 'tag': tag, 'value': v }} );});})(scope);


Графический редактор


Пару слов о графическом редакторе построения визуальных страниц для СКАДА-системы. Как уже упоминалось выше на офсайте предлагается приобрести SCADAvis.io Synoptic Editor. Одняко, опять же это не единственный возможный вариант. Как известно из самого описания редактор построен на базе Inkscape SVG Editor. Практически это Inkscape с плагином позволяющий назначать теги (переменные) и другие свойства различным графическим компонентам svg файла. Т.е. для простого отображения странице в контексте scadavis достаточно иметь svg файл, который можно редактировать в любом удобном редакторе. Но на этом не все. Находится большое сходство между редактором компании ECAVA INTEGRAXOR www.integraxor.com Inkscape 0.91 SAGE 4.16 распостраняющимся бесплатно (необходимо только зарегистрироваться на сайте) и Synoptic Editor. Как в итоге оказалось, действительно возможно создавать и редактировать svg файлы для Scadavis, используя Inkscape 0.91 SAGE 4.16. Разница наблюдается при проектировании скриптовой анимации и некоторых других специфических вещах, которые отсутствуют в Object properties редактора SAGE.

image

Согласно описанию SCADAvis.io Synoptic Editor, для того чтобы назначить цвет объектов по условию включения, необходимо в колонке Limit указать цифру 2:

  • 0 not initialized state
  • 1 false (off) state
  • 2 true (on) state
  • 129 false (off) state plus failed value
  • 130 true (on) state plus failed value

image

Плагин для работы с PLC Siemens


В арсенале Node-red имеется плагин для работы с PLC Siemens node-red-contrib-s7, основанный на фреймворке nodeS7. Плагин достаточно прост и интуитивно понятен в использовании. Он содержит три ноды: S7 in, S7 out, S7 control. В основном используются первые две ноды для чтения и записи тегов в PLC. Один ньюанс, который нужно учитывать при работе с S7-1200, описан в доке к плагину. Я с этим сталкнулся ранее, когда использовал библиотеку Snap7

image

Необходимы некоторые дополнительные шаги настройки в ПЛК:

Optimized block access должен быть отключен для тех DB блоков, к которым мы хотим получить доступ
image

В разделе Защита свойств ЦП установите флажок Разрешить доступ с помощью PUT / GET
image

Краткое заключение


Преимущества подхода использования Node-red в качестве Web-SCADA подобной системы очевидны. Node-red популярная open-source IoT платформа, имеющая огромное сообщество, множество различных плагинов и решений, возможность интегрировать различные протоколы. На ресурсе support.industry.siemens также есть мануал по использованию Node-red и обсуждение использования платформы. SCADA-фреймворк такой, как scadavis.io является хорошим примером интеграции хорошо известного среди специалистов подхода визуализации SCADA-систем и IoT edge платформы.
Подробнее..

Мобильная Установка Доказательства Актуальности Контроля Изменений. Часть 1. Хороший человек идет на войну

28.12.2020 06:15:07 | Автор: admin

Итак, надоело! Даже, не так, ДОСТАЛО! А точнее, за.... Впрочем, не буду прибегать к ненормативной лексике. Квартира, купленная 2.5 года назад - это не квартира, а какое-то вечное испытание. Да такое, что Форт Баярд отдыхает. Кроме того, в конце игры Баярда можно нехило поднять золотишка, а чем тут все закончится - я еще не знаю. Недостаточная (ниже норм, утвержденных Правительством РФ, а эти нормы, скажем так, разрабатывались моржами) температура воздуха в помещении, отсутствие горячей воды по утрам, а ежедневное принятие душа превращается в соревнование "кто быстрей", ибо вода неожиданно может стать кипятком. Или, наоборот, льдом. Бездействие управляющей компании, сбор инициативной группы, объявления по подъездам, коллективная жалоба... это и многие другие веселые подробности останутся за рамками повествования.

Итак, если какой-то параметр, будь то температура или давление, не устраивает, то этот параметр надо для начала измерить. Желательно, в автоматическом режиме, непрерывно и с сохранением всех значений. И тут на помощь приходят средства промышленной автоматизации - датчик давления, датчик температуры, и программируемый логический контроллер с модулем аналоговых входов и поддержкой протокола HART. Почему именно они? Во-первых, я АСУшник, а не электронщик. Во-вторых, я исполняю обязанности руководителя технической группы Управления "Цифровое производство" уральского филиала компании ООО "Сименс". А, стало быть, все эти игрушки у меня есть. Этого оказалось вполне достаточно, чтобы продумать, собрать на коленке и запрограммировать систему, которой я дал замысловатое название Мобильная Установка Доказательства Актуальности Контроля Измерений (весь смысл замысловатости заключается в получившейся аббревиатуре... настолько я огорчен сложившейся ситуацией).

В качестве датчика, измеряющего давление, выступает Siemens Sitrans P DS3 с диапазоном измерения от 0 до 16 бар, выходом 4..20 мА и, что немаловажно, поддержкой цифрового протокола HART. HART означает Highway Addressable Remote Transducer. По сути, это цифровой протокол обмена данными между системой управления и датчиком. Обмен данными двухсторонний. Для кодирования нулей и единичек цифрового обмена используется частотная модуляция, которая накладывается прямо поверх аналогового сигнала 4..20 мА. Поддержка HART сильно играет мне на руку, поскольку позволяет избежать дополнительного аналого-цифрового преобразования на стороне ПЛК и, скажем откровенно, "забить" на "землю" (боюсь, что после этих слов мне коллеги руки не подадут). На фотографии этот красавец уже подключен к домашнему водопроводу.

Датчик температуры - тоже Siemens, тоже с HART'ом. Вторичка - Sitrans TH300, первичка - обычный Pt100 в толстой гильзе. Именно из-за гильзы он не подошел для замеров температуры воздуха - просто огромная инерция измерений.

В качестве CPU применяется S7-1510 (он же ET200SP CPU), заказной номер 6ES7 510-1DJ01-0AB0, версия прошивки 2.8. К CPU справа подключен четырехканальный модуль аналоговых входов с поддержкой HART, заказной номер 6ES7 134-6TD00-0CA1. Блок питания слева от контроллера, весьма большой и очень избыточный по мощности в моем случае.

Для визуализации измеряемых параметров и, что немаловажно, для их архивации взял базовую операторскую панель второго поколения, KTP400 Basic, 6AV2 123-2DB03-0AX0, прошивка обновлена до 16.0. Причина для такого выбора простая - мобильных панелей у меня под рукой нет, а "немобильные", стандартные версии предназначены для врезки в дверь шкафа управления, но никак не для того, чтобы держать их в руках. Маленькую четырехдюймовую панель на весу удержать можно без проблем, а вот семидюймовую Comfort или Unified одной рукой не удержишь. Разбивать подотчетное оборудование и попадать на 1200 евро её листовой стоимости не хочется никак, поэтому лучше маленькую и легкую, чем большую, тяжелую, но функциональную.

Для обвязки применяется обычный провод сечением 0.5 мм2 и НШВИ 0.5х8. Техническая эстетика не соблюдается никак. Корпуса нет. Заземляющих проводников нет. Все обвязано, абы как. Прикладное ПО далеко не универсально, уставок от оператора нет, даже константы не применяются, все тупо в лоб. В общем, это ни в коем случае не готовое решение, которое можно сертифицировать и вносить в реестр СИ. Я напишу про это тут один раз, дабы избежать войн в комментариях, да, со всеми этими замечаниями я согласен.

Датчики подключаем к каналам 0 и 1 аналогового модуля в соответствии с документацией.

У нас используется вариант (1) - двухпроводное подключение датчика. Под "двухпроводностью" подразумевается, что к датчику в общем случае идет всего два провода, "+" и "-" непосредственно от аналогового модуля. Отдельного питания на датчик не требуется, он запитывается от модуля AI. Электроника модуля получает энергию по внутренней шине контроллера, а "силовая" часть подается на отдельные клеммы. В итоге, первый датчик (датчик давления) садим на контакты 9 и 13 (нулевой канал), датчик температуры - 10 и 14 (первый канал).

Для программирования и конфигурирования этой системы применяем среду разработки TIA Portal V16 (+update 3), в составе Step 7 Professional (контроллер) и WinCC Basic (операторская панель). После создания проекта в первую очередь создаем и конфигурируем ПЛК.

Включаем System and Clock Memory, пригодится.

Задаем IP адрес CPU - 192.168.43.205. Конфигурируем аналоговый модуль. Второй и третий каналы отключаем, на нулевом и первом включаем HART и активируем всю диагностику (диагностика совсем необязательна в моем простом случае).

Обзор настройки каналов модуляОбзор настройки каналов модуляНастройка нулевого (и первого тоже) каналаНастройка нулевого (и первого тоже) канала

Поскольку в данном случае задействовано всего 2 канала, а от функционала HART требуется всего лишь передача значения измеряемой величины, то можно поступить просто и забирать первичную переменную HART обоих датчиков через пространство ввода/вывода аналогового модуля. Тем самым избавляемся от необходимости осуществлять системный вызов в программе PLC.

Из этой таблицы видно, что нам надо забрать две переменные с адресов ID8 и ID13. Первичные переменные HART будут поступать нам, как готовые вещественные величины. Пропишем эти адреса в Tag Table. Так же я еще прописал все четыре аналоговых канала модуля, но в программе они никак не используются... просто привычка объявлять переменные по каналам, которые есть в проекте.

Посмотрим, что я начудил в программе контроллера. Вообще, в ПЛК можно обойтись без какой-либо программы вообще. Информация с датчиков и так автоматически поступает в переменные с именами CH0_HART (давление) и CH1_HART (температура). Однако, установка изначально разрабатывалась, как универсальная - она замеряет и Т воздуха, и Т воды, и давление воды, да еще и в нескольких местах (воздух в разных комнатах, например). Если обойтись одним трендом, то можно уже через день запутаться, что, где и когда измерял. Поэтому программа контроллеру тут носит больше "организационный" характер.

Все необходимые переменные сведены в один блок данных.

Вся программа написана в "главном" огранизационном блоке. Расписывать ее нет необходимости, можно ознакомиться с комментариями в коде.

"Data".CurrentPress := "Ch0_HART" / 10.0; //давление перевести из бар в МПа"Data".CurrentTemp := "Ch1_HART"; //текущая температураIF "Data".MeasP THEN //если включен (с панели) замер давления        //допускается всего 4 места измерения давления - в ванной (ХВС, ГВС) и на кухне    IF "Data".WaterSelector <= 0 OR "Data".WaterSelector > 4 THEN         "Data".WaterSelector := 1;    END_IF;        //создать для панели сообщение "идет замер давления в/на <место замера и выбранная труба">    CASE "Data".WaterSelector OF        1: //ХВС в ванной            "Data".WaterMessage := W#2#0000000000000001;        2: //ГВС в ванной            "Data".WaterMessage := W#2#0000000000000010;        3: //ХВС на кузне            "Data".WaterMessage := W#2#0000000000000100;        4: //ГВС на кухне            "Data".WaterMessage := W#2#0000000000001000;    END_CASE;        //тнекщее давление в МПа скопировать в отдельную переменную для тренда    "Data".CurrentPress_M := "Data".CurrentPress;        //если замер только что включили, сбросить минимальное и максимальное зафиксированное значение    IF (NOT "Data".MeasP_prv) THEN        "Data".MinPress_M := "Data".CurrentPress_M;        "Data".MaxPress_M := "Data".CurrentPress_M;    END_IF;        //зафиксировать при необходимости минимальное значение    IF "Data".CurrentPress_M < "Data".MinPress_M THEN        "Data".MinPress_M := "Data".CurrentPress_M;    END_IF;        //зафиксировать максимальное значение давления во время этого замера    IF "Data".CurrentPress_M > "Data".MaxPress_M THEN        "Data".MaxPress_M := "Data".CurrentPress_M;    END_IF;        //выставить аварийные и предупредительные сообщения    "Data".P003Alarm_M := "Data".CurrentPress_M < 0.03;    "Data".P01Alarm_M := "Data".CurrentPress_M < 0.1;    "Data".P02Alarm_M := "Data".CurrentPress_M < 0.2;ELSE //если замер давления не ведется    "Data".CurrentPress_M := 0.0; //обнулить переменную для тренад давления    "Data".WaterMessage := W#2#0000000000000000; //сбросить "место проведения давления"    "Data".P003Alarm_M := FALSE; //сбросить флаги алармов и сообщений    "Data".P01Alarm_M := FALSE;;    "Data".P02Alarm_M := FALSE;;END_IF;IF "Data".MeasTair THEN //аналогично для температуры воздуха        IF "Data".PlaceSelector <= 0 OR "Data".PlaceSelector > 7 THEN        "Data".PlaceSelector := 7;    END_IF;        CASE "Data".PlaceSelector OF        1: //спальня            "Data".PlaceMessage := W#2#0000000000000001;        2: //детская            "Data".PlaceMessage := W#2#0000000000000010;        3: //зал            "Data".PlaceMessage := W#2#0000000000000100;        4: //кухня            "Data".PlaceMessage := W#2#0000000000001000;        5: //ванная            "Data".PlaceMessage := W#2#0000000000010000;        6: //туалет            "Data".PlaceMessage := W#2#0000000000100000;        7: //прочее            "Data".PlaceMessage := W#2#0000000001000000;    END_CASE;        "Data".CurrentTemp_Mair := "Data".CurrentTemp;        IF (NOT "Data".MeasTair_prv) THEN        "Data".MinTemp_Mair := "Data".CurrentTemp_Mair;        "Data".MaxTemp_Mair := "Data".CurrentTemp_Mair;        "Data".MeasTwater := false;    END_IF;        IF "Data".CurrentTemp_Mair < "Data".MinTemp_Mair THEN        "Data".MinTemp_Mair := "Data".CurrentTemp_Mair;    END_IF;        IF "Data".CurrentTemp_Mair > "Data".MaxTemp_Mair THEN        "Data".MaxTemp_Mair := "Data".CurrentTemp_Mair;    END_IF;        "Data".T18Alarm_M := "Data".CurrentTemp < 18;    "Data".T20Alarm_M := "Data".CurrentTemp < 20;    "Data".T22Alarm_M := "Data".CurrentTemp < 22;ELSE    "Data".CurrentTemp_Mair := 0.0;    "Data".PlaceMessage := W#2#0000000000000000;    "Data".T18Alarm_M := FALSE;    "Data".T20Alarm_M := FALSE;    "Data".T22Alarm_M := FALSE;END_IF;//аналогично для температуры водыIF "Data".MeasTwater THEN    "Data".CurrentTemp_Mwater := "Data".CurrentTemp;        IF (NOT "Data".MeasTwater_prv) THEN        "Data".MinTemp_Mwater := "Data".CurrentTemp_Mwater;        "Data".MaxTemp_Mwater := "Data".CurrentTemp_Mwater;        "Data".MeasTair := false;    END_IF;        IF "Data".CurrentTemp_Mwater < "Data".MinTemp_Mwater THEN        "Data".MinTemp_Mwater := "Data".CurrentTemp_Mwater;    END_IF;        IF "Data".CurrentTemp_Mwater > "Data".MaxTemp_Mwater THEN        "Data".MaxTemp_Mwater := "Data".CurrentTemp_Mwater;    END_IF;        "Data".T40Alarm_M := "Data".CurrentTemp < 40;    "Data".T55Alarm_M := "Data".CurrentTemp < 55;    "Data".T57Alarm_M := "Data".CurrentTemp < 57;    "Data".T60Alarm_M := "Data".CurrentTemp < 60;ELSE    "Data".CurrentTemp_Mwater := 0.0;    "Data".T40Alarm_M := FALSE;    "Data".T55Alarm_M := FALSE;    "Data".T57Alarm_M := FALSE;    "Data".T60Alarm_M := FALSE;END_IF;//при первом запуске контроллера сбросить зафисированные мин и макс "общих" (не замерных) величин"tonFirstScan".TOF(IN:=NOT "FirstScan",                   PT:=T#1s);IF "tonFirstScan".Q THEN    IF "Data".CurrentPress < "Data".MinPress THEN        "Data".MinPress := "Data".CurrentPress;    END_IF;        IF "Data".CurrentPress > "Data".MaxPress THEN        "Data".MaxPress := "Data".CurrentPress;    END_IF;        IF "Data".CurrentTemp < "Data".MinTemp THEN        "Data".MinTemp := "Data".CurrentTemp;    END_IF;        IF "Data".CurrentTemp > "Data".MaxTemp THEN        "Data".MaxTemp := "Data".CurrentTemp;    END_IF;END_IF;//сбросить мин и макс по запросу с панелиIF "Data".ResetPressStat THEN    "Data".MinPress := "Data".CurrentPress;    "Data".MaxPress := "Data".CurrentPress;    "Data".ResetPressStat := FALSE;END_IF;IF "Data".ResetTempStat THEN    "Data".MinTemp := "Data".CurrentTemp;    "Data".MaxTemp := "Data".CurrentTemp;    "Data".ResetTempStat := FALSE;END_IF;//выставить обобщенный флаг "идет замер""Data".Meas := "Data".MeasP OR "Data".MeasTair OR "Data".MeasTwater;//для определения фронтов"Data".MeasP_prv := "Data".MeasP;"Data".MeasTair_prv := "Data".MeasTair;"Data".MeasTwater_prv := "Data".MeasTwater;//сообщения для панели оператора"Data".Alarms.%X0 := "Data".MeasP;"Data".Alarms.%X1 := "Data".MeasTair;"Data".Alarms.%X2 := "Data".MeasTwater;"Data".Alarms.%X3 := "Data".T18Alarm_M;"Data".Alarms.%X4 := "Data".T20Alarm_M;"Data".Alarms.%X5 := "Data".T40Alarm_M;"Data".Alarms.%X6 := "Data".P003Alarm_M;"Data".Alarms.%X7 := "Data".P01Alarm_M;"Data".Alarms.%X8 := "Data".P02Alarm_M;"Data".Alarms.%X9 := "Data".T22Alarm_M;"Data".Alarms.%X10 := "Data".T55Alarm_M;"Data".Alarms.%X11 := "Data".T57Alarm_M;"Data".Alarms.%X12 := "Data".T60Alarm_M;

Перейдем к конфигурирования прикладного программного обеспечения операторской панели. Добавим ее в общий проект и зададим ip адрес.

Добавим некоторые настройки рантайма - выбор бита для списков и цвет алармов в зависимости от их класса.

Создадим соединение с контроллером и вытащим необходимые тэги (все это делается автоматически при вытаскивании тэга с ПЛК на любой экран панели). Выставим минимально возможное время опроса переменных в 100 мс.

Все тэги берем с блока данных 1 ПЛКВсе тэги берем с блока данных 1 ПЛК

Для тэгов Data_Alarms, DataWaterMessage и Data_PlaceMessage создадим сообщения.

Создадим Alarm Log для сообщений панели на максимальное количество записей, 500000. Весь лог будет храниться в текстовом виде на USB-флэшке, подключенной к панельке. Журнал циклический, по достижению предельного количества записей, старые будут затираться.

В настройках классов сообщений укажем, алармы каких классов будут сохраняться на фдэшке

Аналогично создадим хранилище для исторических трендов, которое будет так же храниться на флэшке в виде текстового файла. "Трендировать" будем три переменных - значение давление, температуры воздуха и температуры воды во время измерения (не на постоянной основе). Запись значений будет производиться только при изменении переменной, а не на постоянной основе. В противном случае журнал начнет весьма быстро перезатираться.

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

Кнопкой F1 листаем экраны замеров. Остановися только на экране давления, два других аналогичны. На этом экране отображается текущее мгновенное значение давления при идущем замере, эксремумы давления, выбор места проведения измерения и график с историческими данными. Кнопкой F3 начинаем замер давления, кнопкой F4 останавливаем,

На любом экране кнопкой F2 открывается журнал событий.

Дополнительно для собственного удобство я сделал копию этой панели и изменил ее тип на PC Station с одиночной SCADA-системой WinCC RT Advanced. На 4дюймовом экране очень неудобно смотреть графики.

Зато, на 24 дюймах смотреть удобно

Установка находится в работе с 21 декабря. За это время мне стало изместно время пикового вечернего разбора воды, это в районе 22 часов местного времени. Ситуация удручающая, давление падает ниже установленных норм (0.03МПа) и падает влоть до нуля. Да и в целом давление не постоянное, оно может за секунду упасть с трех килограммов до одного, а потом за 5 секунд подняться до 2.5 килограмм.

В настоящий момент система полностью локальна. Все данные сохраняются в панельке, на фэшке переносятся на ПК и изучаются на нем.

Следующим шагом будет установка к линейку ПЛК WiFi модуля, настройка WiFi-моста и создание полноценного операторского интерфейса на базе WinCC OA под управлением Linux Debian (Buster).

Подробнее..

Неизвестный Сапсан часть 1 общий обзор конструкции электропоезда

02.07.2020 00:11:00 | Автор: admin
Как-то, давным-давно, обещал я рассказать об электропоезде Сапсан. Пришло время выполнить свое обещание

Для начала скажу, что речь не пойдет о дороговизне билетов, расписании этого поезда, о его уместности в инфраструктуре Октябрьской железной дороги. Пройдем мимо хайповых тем. Речь пойдет сугубо о технической стороне вопроса, затрагивающей в частности и тормоза. Но не только их.

1. Немного общих цифр


Электропоезд Сапсан является локализованной версией семейства высокоскоростных поездов Velaro, на базе которого Siemens производит высокоскоростные поезда как для Deutche Bahn (немецких железных дорог), так и много ещё для кого. У нас поезду дали обозначение ЭВС Электропоезд Высокоскоростной Сименс. Дорога эксплуатирует два его варианта: ЭВС1 для участков, работающих на постоянном токе 3 кВ и ЭВС2 двухсистемый электропоезд для сетей постоянного тока 3 кВ и переменного тока 25 кВ.


Сапсану присущи все характерные черты высокоскоростных поездов, с формировавшиеся за 56 лет эксплуатации этого вида транспорта в разных странах мира.

Во-первых, Сапсан поезд постоянного формирования. В отличие от пригородных электропоездов (собак), которые формируются из пар моторный вагон + прицепной вагон (плюс головные вагоны с кабиной управления), за счет чего можно формировать электрички разной длины. Сапсан является монолитной неразделяемой инженерной системой. Все вагоны в поезде эксплуатируются вместе. Поезд сформирован из десяти 4-х осных вагонов, средней массой 65 тонн, то есть масса поезда около 650 тонн, что соответсвует статической нагрузке от одной колесной пары на рельс 16,3 тонн, при допускаемой для высокоскоростных поездов 18 тонн. Вагоны поезда цельнометаллические, с несущим кузовом.

Условно поезд можно разделить на две пятивагонные секции, симметричные по компоновке.

Компоновка электропоезда ЭВС1 для системы постоянного тока (кликабельно)


Каждый вагон в пятивагонной секции имеет свою профессию:
  1. Головной моторый (SR B) в этом вагоне располагается кабина управления, тяговый преобразователь и четыре тяговых двигателя
  2. Промежуточный прицепной (DR T) здесь расположены два токоприемника постоянного тока и быстродействующий выключатель, для защиты силовых цепей от перегрузки
  3. Промежуточный прицепной, на ЭВС1 имеющий обозначение MW T. На двухсистемном ЭВС2 в этом вагоне расположен тяговый трансформатор, главный выключатель и токоприемник переменного тока, и тогда этот вагон обозначается TR T трансформаторный
  4. Промежуточный моторный (SR T) здесь едет тяговый преобразователь, питающий четыре двигателя
  5. Промежуточный прицепной (BAT R) в этом вагоне расположены аккумуляторная батарея и преобразователи собственных нужд, вырабатывающие напряжение 110 В постоянного тока, для питания цепей управления и трехфазное напряжение переменного тока 440 В, 60 Гц, для питания вспомогательных машин. В этом вагоне также расположены и тормозные резисторы.


Компоновка двухсистемного электропоезда ЭВС2 (кликабельно)


Другая секция из пяти вагонов, с 6-го по 10-й, устроена совершенно симметрично.

Основной объем в любом из вагонов занимает пассажирский салон, вместимость которого от вагона к вагону несколько отличается. Поэтому, для размещения оборудования остается только крыша и пространство под полом вагона. На крыше, главным образом размещаются токосъемные устройства, высоковольтные шины и аппараты защиты. Внизу, под полом вагона, в контейнерах размещено преобразующее и регулирующее оборудование, тормозное оборудование, вспомогательные машины. Кроме всего этого, на тележках моторных вагонов размещаются асинхронные тяговые двигатели мощностью по 510 кВт каждый (2 двигателя на тележку, по две тележки на вагон). Таким образом, полная мощность электропоезда составляет свыше 8 МВт. Максимальная касательная сила тяги около 350 кН. Таким образом доступное при пуске максимальное ускорение равно 0,54 м/с2.

Что же, от общего обзора в стиле википедии, можно перейти к деталям.

2. Механическая часть


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

На Сапсане используется два типа тележек: тележка моторного вагона, и тележка прицепного вагона. Принципиальным и главным отличием одной от другой является наличие и отсутствие тягового привода. Наличие тягового привода определяет и разную конструкцию механики тормоза.

Общий вид тележки моторного вагона (кликабельно)

1 рама тележки; 2 клещевой механизм дискового тормоза; 3 рессорное подвешивание 1-й тупени; 4 пневморессора 2-й ступени; 5 гаситель поперечных колебаний; 6 демпфер виляния; 7 тяговый электродвигатель (ТЭД); 8 опора пружины качания; 9 форсунка песочницы; 10 путеочиститель (только на головных вагонах); 11 зубчатая муфта поперечной компенсации; 12 тяговый редуктор; 13 колесная пара; 14 буксовый узел; 15 гаситель вертикальных колебаний 1-й ступени; 16 гаситель вертикальных колебаний 2-й ступени;

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

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

Соответственно, эффективные радиусы трения для колодок на моторной и не моторной тележке находятся в соотношении 3/2, дабы обеспечить одинаковое тормозное усилие на той и другой тележке.

Общий вид тележки прицепного вагона (кликабельно)

1 рама тележки; 2 клещевой механизм; 3 рессорное подвешивание 1-й ступени; 4 пневморессора 2-й ступени; 5 гаситель поперечных колебаний; 6 демпфер виляния; 7 опора пружины качания; 8 колесная пара; 9 букса колесной пары; 10 гаситель вертикальных колебаний 1-й ступени; 11 гаситель вертикальных колебаний 2-й ступени.

Чем выше скорость движения экипажа по рельсам, тем более выражена роль динамических нагрузок в общей картине распределения усилий, приложенных к его элементам. Источником возникновения динамических нагрузок является ряд возмущающих факторов, главными из которых являются неровности верхнего строения пути в вертикальном и поперечном направлениях, а так же кинематическая склонность колесных пар к развитию их поперечных колебаний в колее, за счет конической формы поверхности катания.

Если с первым все понятно, то со вторым что я имел в виду? И зачем вообще железнодорожные колеса имеют коническую форму?

В колесной паре оба колеса жестко связаны между собой через ось, а значит, пренебрегая крутильной упругостью оси, можно считать, что оба колеса имеют одинаковую угловую скорость. Всегда. И при движении в прямом участке пути всё будет отлично. А если мы поедем в кривой? Вот тут, для того чтобы внутреннее колесо (ближнее к центру поворота) не проскальзывало, скорость его центра должна быть меньше скорости центра внешнего колеса. Если бы колеса были не связаны жестко, то так и получилось бы внутреннее колесо стало бы вращаться медленнее внешнего. Но так как существует жесткая связь, внутреннее колесо начнет проскальзывать, а ось колесной пары испытывать серьезные нагрузки на кручение.

Чтобы избежать этого придумали остроумное решение раз нельзя уменьшить угловую скорость внутреннего колеса, то тогда можно уменьшить его радиус! Уменьшить радиус внутреннего колеса, а радиус внешнего увеличить, и тогда произойдет перераспределение скоростей центров колес, обеспечивая лучшие условия прохождения поворота в части проскальзывания и динамических нагрузок на ось. Для этого поверхность катания колес делается конической. При этом, как нетрудно сообразить, при входе в кривую, колесная пара смещается в поперечном направлении в сторону противоположную центру поворота. Выйдя из равновесного состояния, свободная колесная пара продолжит совершать поперечные колебания даже в прямом участке пути, с частотой тем большей, чем больше скорость её вращения.

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

Все эти факторы приводят к тому, что элементы ходовой части совершают сложные пространственные колебания, неизбежные при присутствии в связях между ними упругих элементов, обеспечивающих податливость конструкции в направлении действия динамических нагрузок. Колебания эти необходимо гасить, поэтому тележка Сапсана буквально обвешана гидравлическими гасителями. Кроме того, система управления электропоезда оценивает характеристики колебаний в реальном времени, делая вывод об устойчивости движения тележки в колее.

Описанию механики движения высокоскоростного поезда лучше посвятить отдельную статью, в рамках этой сложно будет рассказать обо всех нюансах, которые безусловно интересны. Пока только скажу, что механическая часть поезда, унаследованная от предка немецкого ICE3, вполне рассчитана на скорости движения до 350 км/ч.

3. Силовая электрическая схема


Проще всего описать схему двухсистемного электропоезда ЭВС2 односистемый ЭВС1 отличается от него отсутствием оборудования для работы на переменном токе.

Функциональная схема силовых цепей электропоезда ЭВС2 (кликабельно)

Traktions container контейнер тягового преобразователя; Netzfilter сетевой фильтр; Traktions motoren тяговые двигатели

При работе на переменном токе, напряжение снимается из контактной сети одним из токоприемников переменного тока P-AC, и через главный выключатель AC-HS и крышевой ввод попадает в третий (или восьмой) вагон электропоезда. Токоприемников переменного тока на поезде два поднимается задний по ходу движения токоприемник, второй выступает в качестве резервного и вступает в дело при повреждении основного токоприемника. Питание на секцию с опущенным токоприемником подается по крышевой высоковольтной шине, через пару разъединителей DLT. Переменное напряжение 25 кВ, 50 Гц, поступает на первичную обмотку тягового трансформатора, понижается им, и от четырех вторичных полуобмоток подается в контейнеры тяговых преобразователей (Traktions container). Там это напряжение выпрямляется четырехквадрантными преобразователями (4QS-преобразователи), подаваясь на вход звена постоянного тока, и далее на автономный инвертор напряжения (АИН) PWR, питающий тяговые двигатели.

Не следует путать 4QS-преобразователь с управляемым выпрямителем. Выпрямитель, в том числе управляемый, всегда является понижающим AC-DC преобразователем, в то время как 4QS-преобразователь, кроме того что может работать как управляемый выпрямитель, является ещё и повышающим AC-DC преобразователем, за счет наличия в его схеме контура короткого замыкания с индуктивным дросселем и специального алгоритма управления ключами. Подробнее о принципе его работы можно почитать, например, тут, так как в задачу данной статьи не входит описание принципов построения силовых преобразователей. Тем не менее, отмечу, что напряжение (действующее) на вторичной полуобмотке тягового трансформатора равно 1550 В, при этом с выхода 4QS-преобразователя снимается напряжение постоянного тока 3 кВ. За счет данного преобразователя, система управления стабилизирует напряжение в звене постоянного тока, в не зависимости от колебаний напряжения в тяговой сети (от 19 до 29 кВ).

Упрощенная схема силовой цепи при питании переменным током (кликабельно)


Часть схемы со звеном постоянного тока и АИН у ЭВС1 и ЭВС2 совершенно идентична, за исключением того, что при питании от постоянного тока, АИН вынужден довольствоваться тем напряжением постоянного тока, которое приготовила ему тяговая подстанция. С учетом тяги других поездов на участке, рабочие пределы его изменения от 2,2 до 4 кВ.

При работе на постоянном токе, каждая секция поезда питается от своего токоприемника постоянного тока P-DC. Таких токоприемников на поезде четыре, они попарно расположены на втором и девятом вагоне. В нормальной работе поднимается задний по ходу движения токоприемник в каждой пятивагонной секции. Второй токоприемник в паре является резервным.

Упрощенная схема силовой цепи при питании постоянным током (кликабельно)


Почему на постоянном токе поднимают два токоприемника? Потому, что действующее значение напряжения в сети постоянного тока (3 кВ) меньше действующего значения напряжения в сети переменного тока (25 кВ) в 8,3 раза. При одинаковой потребляемой из сети мощности, ток текущий через токоприемник постоянного тока будет выше во столько же раз. По правде несколько не совсем так, нужно еще учитывать реактивую мощность в цепи переменного тока, однако, если использовать один токоприемник, он получится и массивным, и протекание всего тягового тока может вызвать пережог контактного провода в месте токосъема, поэтому тяговый ток уполовинивают, питая каждую секцию от своего токоприемника.

Итак, постоянный ток, через токоприемник P-DC и быстродействующий выключатель DC-HS подается на отпайку плюсового провода звена постоянного тока тягового преобразователя и подается на вход автономного инвертора напряжения (АИН) PWR. АИН преобразует постоянный ток в переменный трехфазный, с изменяющейся частотой и амплитудой напряжения, за счет чего осуществляется регулирование тягового усилия, развиваемого тяговыми электродвигателями (ТЭД).

Рассмотренная схема обеспечивает режим тяги, так и режим электродинамического торможения, которое на Сапсане рекуперативно-реостатное.

При возможности выполнять рекуперацию (исправные силовые цепи и ненасыщенная контактная сеть с напряжением на постоянном токе менее 4кВ, на переменном менее 29 кВ) выполняется рекуперативное торможение. АИН работает как регулируемый трехфазный выпрямитель по схеме Ларионова, преобразуя трехфазное напряжение, вырабатываемое ТЭД в постоянный ток, которое при работе на постоянном токе отдается в сеть, а при работе на переменном преобразуется в однофазное напряжение 4QS-преобразователем, работающим в режиме инвертора, обеспечивающего компенсацию реактивной мощности, значение коэффициента мощности максимально близким к единице (пресловутый косинус фи). Далее, повышенное тяговым трансформатором напряжение, выдается в сеть.

При срыве рекуперации, энергия, преобразованная АИН, перераспределяется на тормозной резистор RB. Для решения этой задачи в звене постоянного тока в силовую цепь включен импульсный регулятор напряжения (ИР), представляющий собой транзисторный понижающий DC-DC преобразователь, основная задача которого регулирование тока, протекающего через тормозной резистор.

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

Таким образом, каждый из четырех моторных вагона электропоезда оснащен одним тяговым преобразователем, обеспечивающим работу четырех тяговых двигателей в режиме тяги и электродинамического торможения. Из сорока осей в поезде, 16 осей оснащены тяговым приводом, общей мощностью 8 МВт в режиме тяги и рекуперации и 3,2 МВт в режиме реостатного торможения (40% мощности за счет ограничения тока через тормозные резисторы).

Приведу тяговую характеристику поезда зависимость силы тяги от скорости (кликабельно)



Из этого графика, в частности, видно, что электропоезд способен разогнаться до скорости свыше 300 км/ч на площадке, а на подъеме в 10 тысячных поддерживать скорость 230 км/ч.

При исправном одном моторном вагоне (25% мощности) поезд на площадке вполне легко пойдет со скоростью 180 км/ч, а на подъем в 10 тысячный будет уверенно ехать со скоростью 80 км/ч.

Все вышесказанное говорит о том, что поезд располагает запасом мощности, и способен на гораздо более высокие эксплуатационные показатели, чем он демонстрирует сейчас.

Ограничение в 250 км/ч введено искусственно в системе управления тягой, из-за отсутствия на наших дорогах инфраструктуры для движения с большими скоростями. После модернизации участка Москва Санкт-Петербург, однако, Сапсан (при отключенной системе АУДиТ Автоматическое Управление Движением и Торможением, как раз и не дающей разогнаться выше 250) достиг скорости 290 км/ч. Быстрее по нашим железным дорогам пока никто не ездил.

4. Тормозные системы электропоезда


Рассмотрим общие черты тормозов. Электропоезд оснащен несколькими тормозными системами:

  • Пневматический тормоз непрямого действия (автоматический тормоз)
  • Электропневматический тормоз непрямого действия
  • Электродинамический рекуперативно-реостатный тормоз (4 вагона из 10)
  • Стояночный тормоз с пружинными энергоаккумуляторами (СПТ)

В штатном режиме использование этих тормозных систем выполняется системой управления. В соответствии с состоянием органом управления на пульте машиниста, задания, формируемое подсистемой АУДиТ Автоматическое Управление Движением и Торможением, а так же подсистемой автоведения, происходит выбор рабочей тормозной системы и уровень тормозного усилия ей обеспечиваемый.

Управление движением, в том числе и торможением, обеспечивается тремя рукоятками на пульте машиниста. При этом различают несколько режимов регулирования скорости:

  1. Автоведение управление поездом без вмешательства машиниста
  2. Поддержание заданной скорости машинист задает требуемую скорость задатчиком скорости (рукоятка 1 на рисунке ниже), ограничивая мощность привода в тяговом режиме задатчиком силы тяги (рукоятка 3). Разгон, при полной тяговой мощности автоматически происходит с ускорением не более 0,5 м/с2. Тормоза задействуются автоматически, при превышении текущей скорости над заданной, обеспечивая торможение с ускорением -0,5 м/с2. Таким образом, в этом режиме поезд управляется одной единственной рукояткой задатчика скорости, а переход из тяги в торможение выполняется плавно и без участия машиниста.
  3. Режим ручного торможения. Машинист задает тормозное ускорение тормозным контроллером под правой рукой (рукоятка 4), система управления поездом поддерживает это ускорение на заданном уровне. При этом режим тяги отключается, и повторное включение тяги, после ручного торможения, возможно только при полном отпуске тормозов и перевода рукоятки задатчика тяги в положение 0 (так называемое квитирование)


Кабина электропоезда Сапсан (кликабельно)

1 задатчик скорости; 2 дисплейный модуль устройства безопасности КЛУБ-У; 3 задатчик силы тяги; 4 тормозной контроллер (задатчик тормозного ускорения); 5 реверсивный переключатель; 6 дисплей интерфейса человек-машина; 7 тормозной дисплей.

В любом из перечисленных режимов управления, система управления тормозами руководствуется, прежде всего, величиной заданного ускорения, которое, в ручном режиме, в зависимости от положения рукоятки контроллера и скорости поезда определяется по следующим кривым

Кривые заданного тормозного ускорения (кликабельно)


Для обеспечения заданного ускорения приводятся в действие тормоза, причем приоритетным рабочим тормозом является электродинамический рекуперативный тормоз (ЭДТ) на моторных вагонах.

Естественно и логично отдавать приоритет ЭДТ, так как 40% вагонов поезда являются моторными, при этом ЭДТ обеспечивает довольно существенное тормозное усилие. О мощности ЭДТ на Сапсане можно судить по его тормозной характеристике

Тормозные характеристики электропоезда в режиме ЭДТ (кликабельно)


В режиме рекуперативного торможения, на скорости 250 км/ч, ЭДТ обеспечивает поезду тормозное ускорение -0,18 м/с2, при меньших скоростях его эффективность повышается до -0,5 м/с2.

При недостаточной эффективности ЭДТ, приводятся в действие пневматические (ПТ) или электропневматические (ЭПТ) тормоза на прицепных вагонах моторные продолжают использовать ЭДТ. При этом тормозное усилие регулируется таким образом, чтобы, опять таки, поддерживать заданное ускорение. При превышении ускорения над заданным значением, прежде всего отпускаются пневматические тормоза. Система стремится, таким образом, максимально использовать возможности электрического тормоза.

При скорости ниже 3 км/ч, выполняется замещение электродинамического тормоза пневматическим. При снижении эффективности ЭДТ на каком либо из моторных вагонов, конкретно на этом вагоне выполняется замещение ЭДТ на ПТ/ЭПТ.

5. Особенности конструкции пневматических и электропневматических тормозов


Об этих системах следует поговорить подробнее, даже вне рамок данной статьи. В этой же статье поговорим об общих принципах реализации автоматических тормозов на Сапсане.

Высокоскоростное движение предъявляет к пневматическим и электропневматическим тормозам обязательное требование любое торможение с применением ПТ/ЭПТ должно происходить с обязательной разрядкой тормозной магистрали служебным темпом!

Исходя из данного требования, торможение всегда осуществляется путем разрядки тормозной магистрали с последующим срабатыванием на каждом вагоне воздухораспределителя (ВР), набирающего тормозные цилиндры из запасного резервуара (ЗР). Даже если это торможение электропневматическое.

При работе ЭПТ происходит одновременная разрядка тормозной магистрали на всех вагонах, локально, в месте подключения к ней воздухораспределителя, выполняемая электропневматическими вентилями. Этим обеспечивается одновременность их срабатывания, но и только! Воздухораспределитель реагирует только на разрядку тормозной магистрали. Конструкций подобных нашему пассажирскому ЭПТ, где разрядки ТМ практически не происходит, а наполнение тормозных цилиндров ведется из запасного резервуара непосредственно электровоздухораспределителем, с одновременной подпиткой ЗР из ТМ, вы на высокоскоростных поездах не увидите.

При выключении ЭПТ, разрядка тормозной магистрали выполняется с головы поезда, со стороны рабочей кабины, устройством, по своему действию аналогичным крану машиниста, именуемым блок управления тормозной магистралью (БУТМ). Посмотрим на схему тормозов головного вагона

Упрощенная схема тормозов головного моторного вагона (кликабельно)


Зарядное давление тормозной магистрали на Сапсане равно 0,5 МПа. Система управления, через электропнематические вентили, снижает давление в уравнительном резервуаре (УР) служебным темпом. В след за этим, БУТМ, стремясь поддерживать давление в тормозной магистрали давлению в УР, снижает давление и в ней служебным темпом.

Воздухораспределитель срабатывает на торможение. Но он не наполняет тормозные цилиндры! Он создает в своей тормозной камере давление, равное тому, которое должно установится в тормозных цилиндрах! За наполнение ТЦ отвечает преобразователь давления (ПД), работающий как пневматическое реле. Тормозная камера ВР соединена с рабочей камерой ПД трубопроводом, через запирающий электропневматический вентиль.

При подаче питания на этот вентиль, он перекрывает трубопровод и сбрасывает давление из рабочей камеры ПД, что приводит к отпуску тормозов даже при сработавшем на торможении воздухораспределителе. Питание на этот вентиль подается, если на вагоне работает электрический тормоз. Если электрический тормоз не работает, питание с этого вентиля снимается и происходит наполнение тормозных цилиндров до давления, заданного от ВР.

Замечу также и то, что запасный резервуар, непрерывно, через обратный клапан, отпитывается от питательной магистрали (ПМ), где поддерживается давление от 0,8 до 1 МПа, за счет работы компрессора. Давление в ЗР лежи в этих же пределах, так что пневматический тормоз электропоезда является неистощимым. В отличие от поездов с локомотивной тягой, питательная магистраль проходит через все вагоны электропоезда.

Схема тормозов моторного промежуточного вагона выглядит также, как и на головном, за исключением того что там отсутствует БУТМ. На прицепном вагоне установлено 6 тормозных цилиндров, вместо четырех на моторном, в остальном, его устройство в части тормоза, аналогично устройству моторного промежуточного вагона.

Следует отметить, что воздухораспределитель, обозначаемый страшной аббривеатурой KEdSo-EAE, производства Knorr Bremse, в отличие от ВР 242, принятого у нас, имеет ступенчатый пневматический отпуск, за счет того, что работает на разнице не двух давления (в ТМ и ЗР), а трех давлений: в тормозной магистрали (ТМ), рабочей камере (РК) и тормозной камере (ТК). В РК сохраняется давление равное зарядному, что позволяет выполнять отпуск ступенями.

Эта особенность идет от того, что на европейских дорогах ВР (серии KE) унифицированы между грузовыми и пассажирскими поездами, да и грузовые поезда короткие, так что для пневматического торможения в них нет нужды в монстрах типа ВР 483.

Второй нюанс БУТМ, который является по сути не просто тормозным краном с дистанционным управлением, а управляется опосредованно, через систему управления поездом, которая сама, без участия машиниста решает, когда и насколько разрядить тормозную магистраль, чтобы обеспечить требуемое ускорение (заданное машинистом, подсистемой АУДиТ или системой автоведения), а так и когда отпустить тормоза, тоже принимает решение электроника.

А что делать если эта ваша электроника выйдет из строя? Во-первых, есть режим экстренного торможения (ЭТ). Реализуется он безо всякой электроники машинист, переведя контроллер в положение ЭТ, механическим клапаном открывает огромную дыру в тормозной магистрали. Справа, на тумбе, установлен второй клапан, выполняющий ту же функцию нажатие на ударную кнопку открывает ТМ в атмосферу. Естественно, существует и ряд электрических цепей, образующих так называемую ПЭТ Петлю Экстренного Торможения. Но её функция вторична, поезд может быть остановлен и без неё.

Вторым способом, уже после ЭТ и откачки поезда, если надо довести поезд до депо без вызова вспомогательного локомотива, является использование крана резервного управления. Он установлен справа от машиниста на боковой тумбе и имеет три положения: О отпуск, П перекрыша, Т торможение. Этот кран позволяет вручную, пневмо-механически регулировать давление в ТМ, выполняя торможение и отпуск тормозов.

Заключение


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

На закуску предлагаю вашему вниманию видеоэкскурсию на тренажер Сапсана, руководителем разработки которого является ваш покорный слуга



Продолжение следует...
Подробнее..

Оптимальная расчетная конечно-элементная модель. Способы соединения частей КЭ модели

26.03.2021 14:15:31 | Автор: admin
Оптимальная расчетная конечно-элементная модель какая она? такой чаще всего не проговоренный вслух, а порою даже и неосознанный вопрос непременно рождается (как минимум в подсознании) у каждого инженера-расчетчика при получении ТЗ на решение задачи методом конечных элементов. Каковы критерии этой самой расчетной модели-мечты? Пожалуй, здесь стоит отталкиваться от известного философского принципа Всё следует упрощать до тех пор, пока это возможно, но не более того. Вот только как применить этот принцип к нашим научным и инженерным задачам?

Рисунок 1

Критерии оптимальной расчетной конечно-элементной модели


Поразмыслив, проанализировав свой практический опыт, я выделил три основных критерия оптимальной расчетной конечно-элементной модели: 1) физические допущения, адекватные целям расчета; 2) упрощения детализации геометрии, правильный выбор видов конечных элементов и способов их соединения; 3) качественная сетка КЭ. Эта статья является продолжением моего доклада Особенности использования различных видов конечных элементов в Femap с NX Nastran, прочитанного на Femap Symposium 2020. В докладе я обзорно рассказывал о применении этих трех критериев на примере конкретных проектов, а здесь я подробнее расскажу подробнее о втором критерии.

Чтобы определиться с концепцией рациональной расчетной схемы, в которую мы будем преобразовывать (чаще упрощать) исходную геометрическую модель, нужно в первую очередь хорошо понимать физику моделируемого процесса, осознавать факторы и параметры, изменение которых более всего влияет на результат. Необходимо разбираться в видах конечных элементов (линейные, поверхностные, объемные), способах соединения частей модели и в особенностях их совместного применения. Причем части модели могут состоять из конечных элементов разных видов. Да, и конечно же нужно знать возможности используемого вами расчетного комплекса. Расчетный комплекс Femap с NX Nastran поддерживает все виды конечных элементов и позволяет соединять области, состоящие из конечных элементов разных видов, всеми основными способами.

Способы соединения частей КЭ-модели


Существует три основных способа соединения (в более широком смысле слова взаимодействия) частей конечно-элементной модели, передачи нагрузки и внутренних усилий между частями модели. Эта классификация носит условный характер, и я ввел ее для удобства восприятия информации расчетчиками-практиками.
Первый способ соединение конечных элементов разных частей модели узел в узел. Это самый классический способ. При его использовании граница перехода между частями модели не оказывает никакого собственного влияния. Фактически решатель работает с единой сплошной моделью, а части модели существуют только для удобства работы пользователя в пре- и постпроцессоре.

Рисунок 2

Второй способ это применение MPC-связей (multiple point constraint). MPC соединяют узел с узлом (тогда это скорее SPC single point constraint) или узел с группой узлов с помощью жестких или интерполяционных элементов.

Рисунок 3

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

Рисунок 4

Эти три способа соединения (взаимодействия) даже более чем различны. Например, целые классы задач (штамповка, соударение тел) просто невозможно решить без применения контактных поверхностей. При решении же более простых задач (линейная статика, модальный анализ), как правило, есть возможность выбрать, как именно упрощать геометрию и какой способ соединения частей модели применить.

Практические примеры


Разберем и проанализируем по вышеописанным критериям модель радиобашни, изображенную на рис.3. Расчетная модель радиобашни используется для определения собственных форм и частот колебаний металлоконструкции башни, потому точный учет жесткости силовых элементов исключительно важен. Это очень ответственная задача собственные частоты колебаний необходимы для определения динамической составляющей ветровой нагрузки (см. Руководство по расчету зданий и сооружений на действие ветра к СП 20.13330.2010 Нагрузки и воздействия).

Модель радиобашни состоит из конечных элементов трех видов: 1) несущие вертикальные круглые трубы и связи соединяющих их (также из круглых труб) смоделированы балочными конечными элементами; 2) ребра жесткости, соединяющие трубы и опорную плиту, смоделированы поверхностными КЭ; 3) опорная плита смоделирована солидами (объемными КЭ).

В модели также применены три основных способа соединения частей конечно-элементной модели:
а) узел в узел соединены части модели (линейные), между которыми нет зазоров;
б) с помощью MPC-связей соединены линейные элементы (имитирующие трубы), между которыми есть зазоры. Кроме того, посредством MPC-связей соединены элементы ребер жесткости и вертикальных труб;
в) контакты заданы между нижней гранью ребер жесткости и поверхностью опорной плиты.

Я считаю эту расчётную модель очень грамотным результатом преобразования геометрической модели в расчетную, так как модель достаточно проста, но при этом в ней учтены основные конструктивные элементы, определяющие жесткость конструкции. Как правило, в простых строительных САПР отсутствуют инструменты, позволяющие соединять конечные элементы различных видов (в случае радиобашни не было бы возможности смоделировать опорные элементы). То есть в простой строительной САПР конструкцию радиобашни удалось бы смоделировать лишь из одних труб, разбив их балочными конечными элементами. В этом случае податливость основания не учитывается и собственные частоты колебаний конструкции оказываются завышены.

Далее на примере расчетного комплекса Simcenter Femap c NX Nastran я подробнее расскажу о втором способе соединения частей модели, а точнее о применении MPC-связей. Элементы типа R математически эквивалентны многоточечному уравнению связи (Multipoint Constraints Equations, MPC). Они накладывают постоянные ограничения на компоненты перемещения соединяемых узлов. Каждое уравнение связи выражает зависимую степень свободы как функцию независимой степени свободы.
Элементы RROD, RBAR, RBE1, RBE2 и RTRPLT это жесткие элементы. Элементы RBE3 и RSPLINE интерполяционные элементы, они не являются жесткими.

Рисунок 5

Элемент RBE2 использует уравнения связи, чтобы связывать степени свободы зависимых узлов со степенями свободы независимого узла. Относительные деформации между зависимыми узлами отсутствуют, то есть соответствующие элементы не деформируются. Варьируя настройки степеней свободы RBE2 в поле DEPENDENT (Зависимый), можно получить WELD сварное соединение (активируя шесть степеней свободы TX, TY, TZ, RX, RY, RZ) или BOLT болтовое соединение (активируя TX, TY, TZ, вращения остаются свободными).

В отличие от элементов RBE2, элемент RBE3 не добавляет конструкции дополнительную жесткость, то есть RBE3 это интерполяционный элемент. RBE3 можно использовать как инструмент распределения нагрузки и массы в КЭ-модели, аналогичный грузовым площадям в строительных системах автоматизированного проектирования. Нагрузки в виде сил и моментов, приложенные к зависимому узлу, распределяются в независимые узлы пропорционально весовым коэффициентам.

Рисунок 6

В большинстве случаев в настройках степеней свободы RBE3 в поле INDEPENDENT (Независимый) не рекомендуется активировать вращательные степени свободы.
Подробнее специфика применения RBE2 и RBE3 представлена в статье наших партнеров из компании КАДИС: RBE2 в сравнении с RBE3 в Femap c NX Nastran.

Рисунок 7

Но вернемся от теории к практике и разберем типовую задачу расчета кронштейна, на примере которой отлично видно, что, неправильно задав способ соединения частей модели, мы получим принципиально неверное решение. Кронштейн закреплен на П-образной пластине с помощью двух болтов. К отверстиям кронштейна приложена сила с направлением вдоль пластины. П-образная пластина разбита поверхностными конечными элементами, а кронштейн объемными КЭ. С учетом толщины пластины пластина и кронштейн соприкасаются.

Рисунок 8

Чтобы результат расчета был адекватен, способ соединения кронштейна с П-пластиной (модель передачи нагрузки) должен соответствовать реальной физике работы болтового соединения. Гайки закручены с некоторым усилием (моментом). Этот момент вызывает силу, прижимающую кронштейн к поверхности пластины. Силу трения в свою очередь определяют коэффициент трения и сила реакции. При приложении нагрузки к кронштейну часть его основания прижимается к пластине, а некоторая часть основания, напротив, стремится от него оторваться, вследствие чего при превышении определенной нагрузки происходит частичное раскрытие стыка.

С точки зрения математического моделирования нам необходимо: а) задать непосредственное соединение болтов и гаек с кронштейном и пластиной и б) задать взаимодействие изначально прижатых друг к другу поверхностей. На рис. 9 показаны напряженно-деформированные состояния кронштейна с пластиной при двух вариантах задания соединений. Составляющая а назовем ее имитация болтов в обоих вариантах задана одинаково: два паучка из RBE-элементов и болт из балочных конечных элементов созданы с помощью встроенной API-команды Hole to Hole Fastener.

Первый и второй варианты различаются настройками свойств контактной пары поверхностей составляющей б. В первом варианте настройки контакта соответствуют склейке двух поверхностей, что не отвечает физике работы болтового соединения. Этот вариант можно было бы использовать, если бы кронштейн был соединен с пластиной при помощи сварных швов по периметру и внутри. Адекватное решение (второй вариант расчета) получается при задании контакта с трением. Такой вид взаимодействия поверхностей позволяет учесть эффект частичного раскрытия стыка. Задача при этом становится нелинейной и решение занимает гораздо больше времени в связи с необходимостью обеспечить сходимость решения. Подробнее о нелинейном анализе и обеспечении сходимости можно прочитать в моей статье Просто о нелинейном анализе методом конечных элементов. На примере кронштейна.

Рисунок 9

Существует несколько способов моделирования болтового соединения. Представленный выше способ (балочный элемент + RBE + контакт с трением) относительно прост, однако он позволяет учесть передачу сдвиговых усилий. Есть более точный, но и гораздо более трудоемкий способ моделирования болтового соединения: непосредственное моделирование болтов, гаек, шайб объемными конечными элементами (рис. 10). Этот способ позволяет учесть все тонкости работы болтового соединения (даже контакт в резьбе) и в том числе производить нелинейный анализ с учетом пластичности.

Рисунок 10

Глобально-локальный анализ


Проанализируем теперь сложную конечно-элементную модель марсохода Кьюриосити (Curiosity). На примере марсохода я хочу познакомить читателя с понятием глобально-локального анализа (ГЛА). Глобально-локальный анализ это процесс изолированного рассмотрения отдельных частей конструкции, при котором выполняется условие равенства силовых факторов и перемещений, соответствующих поведению этой части в составе конструкции. Возможность применения ГЛА обоснована принципом Сен-Венана: в частях конструкции, достаточно удаленных от места приложения нагрузки, напряжения и деформации мало зависят от способа приложения нагрузки. Потому часть модели можно вырезать и выполнить анализ только для этой части при условии, что значения силовых факторов на границах выреза заданы правильно.

Рисунок 11

Но вернемся к марсоходу и его модели. Весит марсоход около тонны, его габариты: длина 4,5 метра, ширина 2,5 метра, высота 2,1 метра. В процессе проектирования было проведено множество расчетов средствами Simcenter Femap, в том числе линейный статический анализ, анализ потери устойчивости, нелинейный анализ; рассчитаны отклики на воздействие случайной вибрации, выполнен анализ переходных процессов.

Конечно-элементная модель марсохода, изображенная на рис. 11, это глобальная конечно-элементная модель (ГКЭМ). С ее помощью можно подобрать сечения труб и толщины оболочек, вычислить нагрузки реакции в узлах конструкции. В модели применены линейные, поверхностные и объемные КЭ, части модели соединяются как узел в узел, так и посредством MPC-связей и контактов. Для такой сложной конструкции как марсоход рационально использовать глобальную модель как нагрузочную, а узлы считать отдельно с помощью подробных локальных конечно-элементных моделей (ЛКЭМ) то есть применять алгоритм глобально-локального анализа (рис. 12).

Для расчета узлов в ЛКЭМ очень важно правильно задать граничные условия, силовые факторы. Существует три способа переноса граничных условий из ГКЭМ в локальную конечно-элементную модель: перенос перемещений, перенос силовых факторов, комбинированный способ. Для осуществления этих операций в Femap есть удобный инструмент FreeBody. Чтобы более подробно узнать о ГЛА и о применении FreeBody, рекомендую ознакомиться с докладом Алексея Патая из компании Центр Технических Проектов: Возможности Femap для глобально-локального анализа авиационных конструкций.

Рисунок 12

Заключение


Подведем итоги, опираясь на вышеприведенные результаты анализа трех расчетных моделей: радиобашни, кронштейна и марсохода. Какая она все-таки оптимальная расчетная конечно-элементная модель, и насколько простой модель может быть? Ответ для каждой конкретной задачи индивидуален, но есть общие критерии.

Что касается понимания физики процесса: например, нам не нужно моделировать каждый крепежный элемент радиобашни, чтобы определить собственные формы и частоты колебаний конструкции, требуется учитывать лишь элементы, в целом определяющие распределение масс и жесткость конструкции.

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

На примере расчета кронштейна, соединенного болтами с П-образной пластиной, мы увидели, что очень важно правильно задать способ передачи нагрузки, граничные условия. В противном случае мы получим результат, не соответствующий действительности. Да, в соответствии с принципом Сен-Венана, напряженно-деформированное состояние (НДС) конструкции в глобальной модели на достаточном удалении от неточно смоделированного узла практически не изменится. Но НДС элементов узла будет определено неверно, что может быть критичным, если это ответственный узел и он сильно нагружен. Особенно важно как для точности решения, так и для сходимости правильно задавать нелинейные контакты.

Для сложных же конструкций, таких как марсоход Кьюриосити, делать одну сложную и подробную конечно-элементную модель чаще всего нерационально. Целесообразнее использовать алгоритм глобально-локального анализа, то есть формировать глобальную нагрузочную конечно-элементную модель и локальные конечно-элементные модели для расчета ответственных узлов. Затем, после расчета узлов, при необходимости можно внести изменения-уточнения в ГКЭМ.

Конечно, тема оптимальной расчетной конечно-элементной модели не может быть исчерпана в рамках одной статьи. Но я надеюсь, что мой обобщенный практический опыт и теоретические знания будут полезны, и в следующий раз вы сможете быстрее найти свое оптимальное решение. При этом расчетная модель будет проще, а точность выше!

Филипп Титаренко,
специалист по расчетам на прочность,
продакт-менеджер по направлению Femap
АО Нанософт
E-mail: titarenko@nanocad.ru


Уважаемые читатели, приглашаю вас на бесплатный Профессиональный курс по расчетам методом конечных элементов (март-апрель 2021 г.). Чтобы зарегистрироваться на курс и ознакомиться с его программой, пройдите, пожалуйста, по ссылке здесь или щелкните на рисунок выше.

Профессиональный курс по расчетам МКЭ от АО Нанософт включает в себя как ценные теоретические знания и инженерные методики, ориентированные на прикладное применение, так и практические демонстрации, вокршопы по решению типовых инженерных задач в расчетном комплексе конечно-элементного моделирования Simcenter Femap c NX Nastran.

Курс состоит из трех вебинаров и предназначен для инженеров, технических работников и студентов, работающих в областях, где требуется проведение физических расчетов. В заключительной части каждого вебинара вы сможете задать вопрос ведущему, Филиппу Титаренко, и получить консультации по интересующим вас вопросам.

Даты и время проведения вебинаров:
Инженерный анализ методом конечных элементов в Simcenter Femap, обзор модулей 30 марта, 14:00
Импорт и преобразование геометрической модели в расчетную. Femap с NX Nastran 7 апреля, 11:00
Основные способы соединения частей КЭ-модели, передачи нагрузок в Femap с NX Nastran 15 апреля, 11:00

Бесплатную пробную версию Simcenter Femap с NX Nastran можно скачать здесь.
Подробнее..

Промышленный интернет вещей в ПЛК Simatic S7-1x00 на примере протокола MQTT

13.01.2021 20:16:14 | Автор: admin

Обнаружил в базе знаний Siemens (SIOS) интересный пример использования контроллеров линейки S7-1200 и S7-1500 в качестве клиента протокола MQTT

Ссылка на первоисточник:https://support.industry.siemens.com/cs/document/109748872/fb-lmqtt_client-for-simatic-s7-cpu?dti=0&pnid=13685&lc=en-RU

По ссылке можно найти саму библиотеку с функциональным блоком MQTT_Client (с открытыми исходниками, кстати) и пояснительную записку к примеру. Документация сама по себе вполне исчерпывающая, знающие английский язык могут смело идти по ссылке и не читать эту заметку, подарив тем самым себе несколько увлекательных часов инженерных изысканий. А для остальных, менее опытных и/или более ленивых, я кратко расскажу основное и продемонстрирую свой пример работы клиента, творчески переработанный под более-менее реальное применение.

Кратко о терминах.

MQTT message queuing telemetry transport. Протокол телеметрии для передачи сообщений. Затрудняюсь перевести название корректно на русский.

Message сообщение. Непосредственно, сами передаваемые данные. Сообщение состоит из нескольких частей:

-Topic, тема сообщения. Символьная строка, размер которой в исходном примере ограничен 200 символами. Клиенты для получения сообщений должны предварительно подписаться на конкретную тему, т.е. topic

-QoS, quality of service. Дополнительный признак, указывающий ждать ли подтверждения получения сообщения или нет.

-Message text, текст сообщения. Текстовая строка из 500 символов.

Протокол построен на модели подписчик/издатель, общая логика которого слегка отличается от обычной клиент-серверной модели, привычной в промышленных протоколах.

При клиент-серверном подходе один или несколько участников исполняет роль сервера, т.е. узла в сети, который отвечает на запросы клиента. Сервер сам по себе не инициирует связь и не проявляет активность, он лишь отдает запрошенные данные и принимает уставки и команды. При этом адресация данных, тип данных и прочее закладываюся и структурируются изначально на этапе разработки серверной части. Клиент тоже должен знать эту карту адресов Modbus. Изменение набора данных требует перенастройки и клиента, и сервера.

В модели подписчик-издатель, применяемой в протоколе MQTT, совершенно необязательно заранее формировать, конфигурировать или программировать набор данных (топики). Вообще никак данные конфигурировать в серверной части не требуется. Топики создаются автоматически от издателя. Подписчики, в свою очередь, подписываются на топики, причем можно подписаться даже на тот топик, в который не написал ни разу ни один издатель. Как только в этот топик будет отправлено хотя бы одно сообщение, все подписчики его получат.

Итак, роли в протоколе MQTT.

Издатель он же publisher. Узел, который отправляет сообщения (текстовую информацию) на определенную тему (topic).

Подписчик он же subscriber. Узел, который подписывается на определенные темы. Новые сообщения в заявленных темах подписчик получает автоматически.

Роли издателя и подписчика могут совмещаться на одном и том же узле сети. Это роли клиента.

Роль сервера в протоколе MQTT выполняет узел, который называется брокер. Именно брокер запоминает, какие клиенты на какие темы подписались. Именно брокер принимает сообщения от издателей на определенную тему и автоматически раздает их соответствующим подписчикам.

К брокеру может быть подключено несколько и подписчиков, и издателей. Максимальное количество мне неизвестно. Предположу, что все ограничено лишь мощностью железа, на которой работает брокер и настройками стека TCP/IP операционной системы.

В первоисточнике (см. ссылке в начале) идет архив с библиотекой LMQTT_Client. Архив необходимо распаковать, а библиотеку подключить к уже созданному проекту Step 7. Подключение библиотеки выполняется через пункт меню Options Global Libraries Open library. В результате Вы увидите следующее:

Библиотека подключена к проекту

Библиотека содержит две версии функционального блока клиента протокола MQTT для контроллеров S7-1200 и S7-1500. В моем примере будет использоваться младший ПЛК, S7-1214. Реализации отличаются тем, что старшие S7-1500 позволяют адресовать брокер по доменному имени, а S7-1200 только по ip-адресу. Необходимо перетащить блок LMQTT_Client из библитеки во вкладку Program Files контроллера. Типы данных скопируются в проект автоматически. Далее я отхожу от примера и осуществляю вызов ФБ MQTT_Client из своего собственного функционального блока под названием MQTTExchange:

В принципе, если выполнить все настройки правильно и играть запросами через поля экземпляра функционального блока, то можно проверить работоспособность прямо сейчас. Но вначале пройдемся по основным входным и выходным пинам этого ФБ.

enable при положительном фронте этой дискретной переменной устанавливается соединение с брокером MQTT, при отрицательном фронте соединение разрывается. Т.е. для работы необходимо держать этот вход в состоянии TRUE

publishData структура для отправки (публикации) сообщения. Состоит из бита запроса на публикацию (для отправки сообщения бит необходимо взвести в истину и снять в ложь после появления флага done или error), топика и текста сообщения, а так же признака качестве QoS

subscribeToTopic структура, которая содержит флаг запроса на подписку, флаг запроса на отписку (да, можно в любой момент отписаться от топика), непосредственно имя топика и признак качества

На начальном этапе нам важны следующие две структуры, которые необходимо для установления связи с брокером: это tcpConnParam и mqttParam. Эти структуры я заполняю единожды в OB100 при запуске контроллера. Необходимый минимум для работы протокола описывается ниже.

Аппаратный идентификатор интерфейса контроллера

Идентификатор интерфейса ( сетевой карты ) ПЛК. В моем случае у меня всего один интерфейс. Его ID я уже помню наизусть, поэтому пишу 64. Подсмотреть Hardware ID можно в аппаратной конфигурации ПЛК.

Следующее идентификатор соединения. Именно логического соединения по протоколу TCP/IP, connection ID. Должно иметь значение от 1 до 4096, назначается программистом, у каждого логического соединения должен быть свой уникальный айди, иначе связь не будет функционировать. В моем случае у меня присутствует одно-единственное соединения, и я смело назначаю ему 1

Следующее назначение IP-адрес хоста, на котором функционирует брокер.

В данном примере брокер работает на моем домашнем рабочем компьютере с публичным статическим ip-адресом. Из соображений информационной безопасности два байта ip-адреса стерты. В качестве брокера выступает mosquitto под Windows. Разные способы установки брокера хорошо описаны по ссылке:

http://www.steves-internet-guide.com/install-mosquitto-broker/#manual

Там же можно скачать уже настроенный в базе брокер, его я и использую:

http://www.steves-internet-guide.com/install-mosquitto-broker/#

Никаких особенных настроек не применяется. Сертификаты шифрования не используются (об этом чуть позже). На удаленном компьютере просто запущена программа mosquitto.exe, а на удаленном маршрутизаторе сделан проброс порта 1883 (порт для стандартных коммуникаций MQTT) в локальную сеть.

Я умышленно использую брокер, недоступный локально. Одно дело поднять все в рамках локальной сети в горячо любимом диапазоне адресов 192.168.0.х или 192.168.1.х, а совсем другое убедиться в возможности работы системы, как ей и положено, по удаленным каналам связи. Ведь сам контроллер находится сейчас в лаборатории, он подключен к местному маршрутизатору от провайдера, и у контроллера есть только локальный ip-адрес, а не публичный и, тем более, не публичный статический ip.

Кстати, помним, что для организации выхода в интернет контроллеру в данном случае необходимо явно указывать шлюз в настройках его ip-адреса.

Обязательно надо прописать router address, иначе ПЛК не сможет подключиться к внешнем ресурсам глобальной сети

Следующая настройка порт, по которому удаленный брокер слушает соединения. По непонятной причине в примере этот порт указан, как 1884, в то время как стандартным портом для нешифрованных коммуникаций является 1883. Задаю его явно:

Последняя настройка символьное имя клиента. Должно быть уникально в системе. В качестве имени у меня задано S7-1214.

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

Первое. Last will. Буквально на русском языке завещание (сетевые граждане такие юмористы!). Если выполнить эту настройку, то клиент при подключении к брокеру передает и ее. В случае отвала связи клиента, брокер автоматически разошлет это завещание всем участникам обмена. Завещание является таким же сообщением, у него так же задается топик и текст.

Второе. Возможность шифрования трафика. Для общего тестирования можно обойтись и без него. В продакшене ни в коем случае.

Выставив поле activateSecureConn в настройках необходимо провести еще ряд манипуляций активировать глобальные настройки безопасности проекта, импортировать сертификат брокера, создать сертификат контроллера и так далее. Вопросы зашифрованного соединения я уже поднимал в заметке про OPC UA коммуникации. В целом же действия тут больше напоминают настройки безопасного соединения для Open User Communications (SecOUC). В настоящем примере вопросами безопасности передаваемых данных я пренебрегаю. Подробности настройки описаны все в той же документации.

Закончив настройки, необходимо убедиться, что все работает, как надо. Для начала, конечно же, просто подпимем соединение с удаленным брокером. Для этого достаточно подать истину на вход enable функционального блока LMQTT_Client:

Как видно, при поданном enable выходные биты tcpEstablished и mqttEstablished содержат истину, это означает, что связь установлена успешно. В процессе испытаний я обнаружил интересное поведение блока, а именно при подачи истины на вход enable подтверждение связи появлялось на одну-две секунды и пропадало. Связь устанавливалась только со второй попытки. Кроме того, при физическом обрыве связи этот ФБ просто информирует об отсутсвии соединения, и не предпринимает попыток автоматически пересоединиться. В целях автоматического соединения и пересоединения добавлен следующий нетворк:

Смысл следующий если в течении 5 секунд установлен флаг запроса связи, но нет подтверждения, снять флаг запроса связи. И если флага запроса нет в течении 5 секунд, установить флаг запроса. В тепличных условиях лаборатории это прекрасно работает. В полевых условиях при нестабильной связи временные константы желательно скорректировать.

В данном примере предполагается, что контроллер не только отправляет какую-либо информацию брокеру, но и подписан на топик. Точнее, даже на два топика, чтобы пример был интереснее. В качестве принимаемой информации может быть, что угодно команды, уставки, запросы архивной информации или состояния оборудования. В принципе, все ограничивается исключительно объёмом свободной рабочей памяти. Вполне логичным будет подписаться на нужные топики сразу после установления связи. И для этого потребуется поиграть с полями структуры subscribeToTopic, которую лучше все воспринимать, как управляющую структуру.

По переднему фронту (то есть, по единомоментному факту) установления соединения я поднимаю локальную битовую переменную #SubscriveToTopics и выставляю номер шага процедуры подписки в 1. Номер шага используется в связи с тем, что все операции у нас ассинхронные, и их надо выполнять последовательно, одну за другой, а не все сразу (все сразу не выполнятся).

Первый шаг подписки подписаться на топик с названием global. В случае успешного выполнения операции подписки переходим на следующий шаг. Иначе выполняем процедуру переподключения (хотя, реакция может быть иной, на усмотрение разработчика)

Смотрим. Если выставлен бит выполняем подписку и шаг = 1, то

если не выставлен бит управляющей структуры подписатся, то задать имя интересующего топика (global) и поднять бит управляющей структуры подписаться

если бит управляющей структуры подписаться поднят, то смотреть на биты выполнения задания done и error. При появлении бита done сбросить бит управляющей структуры подписаться и перейти на шаг 2. В случае возникнования ошибки выполнить переподключение к брокеру.

Шаг 2. На этом шаге не нужно делать вообще ничего. Этот шаг требуется для того, чтобы ФБ клиента вызвался хотя бы один раз со сброшенным битом управляющей структуры подписаться. Для этого есть и более изящные решения, но я обошелся простейшим таймером.

После 100мс ожидания просто идем на следующий шаг, к подписке на второй топик (шаг 3).

Шаг 3 аналогичен шагу 1, за исключением имени топика. После успешного завершения шага 3 сбрасывается локальный бит выполнить подписку (#SubscriveToTopics) и обнуляются шаги подпрограммы подписки.

После выполнения подписки можно смело проверять работу клиента. Для этого я вызываю программуmosquitto_pub.exe:

mosquitto_pub.exe -h myhost.mydomain.ru -t global -m kill all humans

, где

myhost.mydomain.ru доменное имя удаленного брокера

global топик global, на который только что подписался клиент

kill all humans текст сообщения в топике global

После отправки сообщения смотрим выходную структуру subscriptionsMessage:

Как видно, в топике global прошло сообщение kill all humans

Флаг newMessageReceived нам еще пригодится в дальнейшем. Этот флаг выставляется сразу по получению нового сообщения и действителен в течении одного цикла сканирования. По нему очень удобно будет обрабатывать полученные команды, уставки или запросы.

Вторая задача контроллера в этом примере отправлять информацию о технологическом процессе через равные промежутки времени. Например, каждые сутки. Или каждые два часа. Ну, или каждые 10 секунд, потому что в учебном примере не очень хочется терять время на пустое ожидание. Поэтому каждые 10 секунд я поднимаю локальный флаг отправить данные и выставлю шаг подпрограммы отправки в 1:

Нетворк отправки данных для разнообразия написан на SCL, а не нарисован в LAD. Право же, оперировать строками в графических языках не самое удобное дело.

Всего отправляется значение 4 переменных, три из которых заданы статично в блоке данных, а одна постоянно увеличивается на небольшую дельту. На первом шаге подпрограммы задается имя топика, это имя personal0. А так же формируется строка сообщения. Поскольку оперируем мы именно символьными данными, приходится выполнять преобразование типа REAL_TO_WSTRING и конкатенацию строк. Для контроллеров, тем более, начального уровня, это не самое лучшее занятие очень быстро расходуется память и неплохо так съедаются вычислительные ресурсы. Длина передаваемого сообщения 500 символов, есть куда развернуться. Можно, так же, добавить еще и метку времени. Можно формировать буфер сообщений, тем самым аккумулируя хотя бы минимум данных на период отсутствия связи. В общем, тут можно делать, что угодно (но лучше делать, что написано в ТЗ).

После формирования строки поднимается бит управляющей структуры отправить сообщение и меняется номер шага. На втором шаге идет проверка успешности или неуспешности отправки, после чего сбрасывается локальный бит выполнить отправку и сбрасывается номер шага подпрограммы отправки.

Запустим клиент MQTT и посмотрим, что приходит в топике personal0 (именно в этот топик ПЛК и отправляет данные):

Ну, и напоследок. Демонстрация возможностей удаленного управления. Если в топике personal0 пришло сообщение exterminate, дискретный выход Q0.0 устанавливается в значение истина.

Команда издателя:

mosquitto_pub.exe -h host.domain.ru -t personal0 -m exterminate

Нетворк программы контроллера:

Проверка пришедшего сообщения выполняется только по факту прихода самого сообщения (бит newMessageReceived), что вполне логично. А далее необходимо только проверять имя топика и текст сообщения. Любые дальнейшие действия программируются, как угодно.

На этом технический пример заканчивается, и хочется немного порассуждать о возможностях применения. Они есть, и, кажется, весьма широкие. Фактически, это можно применять в любых распределенных недорогих системах, где присутствуют малые объемы информации и, в силу этого, использование специализированных телемеханических протоколов нецелесообразно в виду их высокой стоимости. Ну, например, в ЖКХ. Если маленький ПЛК смотрит на расход энергоресурсов (общедомовых, а, может, даже и поквартирных) и раз в сутки отправляет сводку в диспетчерский центр. Или смотрит на состояние общедомового оборудования, шлет параметры раз в час, но при аварии моментально. Достаточно лишь снабдить ПЛК GSM-модемом, и фактически, ничего больше не требуется, кроме простого компьютера с фиксированным ip-адресом. Рассуждая дальше, можно и без физического ПК обойтись, засунув его в облако. Главное, не забыть должным образом настроить шифрование трафика. В этом случае имеет смысл данные потребления энергоресурсов из клиента сразу складывать в базу данных, но это уже требует высокоуровневого программирования

Или, как вариант, та же распределенная система, но не только сбор данных, но и взаимодействие M2M (контроллер-контроллер). Тут точно так же, достаточно минимального канала связи и доступного брокера.

Можно даже и на скаду информацию выводить, не особо заморачиваясь с программированием серверной (брокерской) части. Ведь ничто не мешает настроить все полевые контроллеры на отправку сообщений брокеру, взять еще один контроллер, читать эти сообщения и их результат раскладывать по блокам данных, и уже из них выводить показания на тот же WinCC Advanced.

Дальнейшие исследование показали отличное применение mqtt совместно со средой Node-RED. На Node-RED была "нарисована" программа, принимающая эти данные от брокера, разбирающая полученную строку и записывающая всю информацию (метку времени, значение) в базу данных MariaDB. Она же, программа на Node-RED позволила вытаскивать информацию за указанный временной промежуток, показывать ее в виде таблицы, графика и делать выгрузку в виде .csv файла.

Подробнее..

Клиент-серверный обмен данными между двумя PLC серии S7-1500 по протоколу OPC UA

04.01.2021 04:07:06 | Автор: admin

При написании данной заметки использовались следующие материалы:

1. Creating of OPC UA clients with .NET and helper class

https://support.industry.siemens.com/cs/document/109737901/creating-of-opc-ua-clients-with-net-and-helper-class?dti=0&pnid=13716&lc=en-RU

2. OPC UA Client Library

https://support.industry.siemens.com/cs/document/109748892/opc-ua-client-library?dti=0&pnid=13716&lc=en-RU

3. On-line справка Step 7 Professional V15.1

4. SIMATIC S7-1500, ET 200MP, ET 200SP, ET 200AL, ET 200pro Communication. Function Manual (10/2018 A5E03735815-AG)

5. Здравый смысл

Протокол OPC UA (http://personeltest.ru/aways/ru.wikipedia.org/wiki/OPC_UA) появился впервые в контроллерах Simatic во второй версии прошивки и в Step 7 версии 14. Тогда контроллер можно было настраивать только в качестве OPC UA - сервера, то есть ПЛК мог отвечать на запросы и отдавать данные, но не мог сам инициировать связь и опрашивать других участников сети.

Радикально ситуация меняется в ноябре-декабря 2018 года с выходом прошивки 2.6 и Step 7 версии 15.1. Появляется возможность настроить CPU в качестве OPC UA клиента. А это, в свою очередь дает нам возможность организовать защищенный канал обмена информацией машина-машина (контроллер-контроллер). И это важно (про существование Secure OUC мне так же известно, однако OUC являет собой обмен данными в свободном формате, чего хватает для маленьких объемов, но отсутствие строгого формата данных накладывает свой отпечаток). Большинство протоколов полевого уровня для промышленности разрабатывалось в прошлом веке и рассчитаны они, в первую очередь, на честных людей. Только время идет, честных людей становится меньше, злодеев - больше, поэтому обмен данными надо как можно лучше спрятать, зашифровать, запаролить, обложить сертификатами, а всем посторонним в ответ показывать обидные жесты и говорить неприличные слова.

Итак, настройка контроллера (S7-1512 FW2.6) в качестве OPC UA сервера.

В процессе некоторых манипуляций в TIA Portal'е, вроде включения глобальных настроек безопасности, среда будет выдавать вам предупреждающие и временами даже угрожающие окна сообщений. При описании я не акцентировал на этом внимание, так что просто нажимайте кнопку ОК и со всем соглашайтесь.

  1. По умолчанию OPC UA отключен в настройках, поэтому заходим в свойства CPU, ищем ветку OPC UA Server General и активируем OPC UA Server.

2. Использование OPC UA в контроллерах Simatic требует приобретение лицензии, поэтому покупаем лицензию, заходим в свойства Runtime licenses OPC UA и ставим тип приобретенной лицензии. Лицензии для 1500ой серии бывают трех типов: маленькая, средняя и большая, в зависимости от типа CPU. S7-1510 и S7-1512 требуют small.

3. По желанию можно задать Application name для OPC UA сервера, порт и временные интервалы. Интервалы сбора (sampling) и публикации (publishing) я выставил минимальными. Стоит помнить, что уменьшение интервалов повышает нагрузку на CPU. Имя приложения и номер порта оставил по умолчанию.

4. Базовая настройка закончена. Компилируем и грузим PLC.

5. Пора бы и проверить, работает ли вообще. Запускаем программу OPC UA Client (ее можно скачать с SIOS по первым двум ссылкам в начале заметки). Ставлю ip адрес моего контроллера 192.168.43.10 и нажимаю кнопку Get Endpoints. Получаю возможные точки входа

Захожу по самому первому варианту, без сертификатов, без шифрования, без пароля, нажимаю Connect to selected Endpoints и перехожу на вкладку Browse nodes. В контроллере загружена программа управления котельной, нахожу одну переменную (Node или узел так называется тэг или переменная в протоколе)

В правой верхней части есть строчка Node id (идентификатор узла или адрес переменной), выделяю его мышкой и жму Ctrl-C

Перехожу на вкладку Read/Write, вставляю скопированный node id и нажимаю кнопку Read

Получаю прочитанное значение переменной равное 3. Действительно, все совпадает, насосы отопительного контура должны чередоваться в третий день недели, и именно эта цифра вбита в переменную DayOfWeek блока данных OKPumpsAuto.

Закрываю программу. Базовый функционал есть, и он работает. Но этого мало. Сейчас OPC UA сервер настроен на режим заходи, кто хошь, бери, че хошь. Необходимо добавить немного безопасности.

6. Включаем глобальные настройки безопасности в свойствах CPU, Protection&Security Certificate Manager, ставим галочку Use global settings

7. В навигации всего проекта находим Security Settings Settings. Смело нажимаем кнопку Protect this project. Действие необратимое. Снять защиту с проекта уже не получится. Дело в том, что оффлайновый проект будет содержать сертификаты серверной и клиентской машины, они должны быть защищены во избежании покражи. После нажатия кнопки Protect система предложит создать администратора проекта:

Теперь любое открытие проекта TIA Portal будет требовать ввода логина и пароля. Кроме администратора проекта, разумеется, можно и нужно создать пользователей с меньшими правами.

8. После того, как мы активировали глобальные настройки безопасности, необходимо заново вручную сгенерировать сертификат контроллера. В дальнейшем лучше, конечно же, сразу защищать проект, создавать администратора проекта и ставить контроллерам глобальные настройки безопасности, но данная заметка частично носит общеобразовательный характер. Возвращаемся в настройки CPU, ищем OPC UA Server Security

Нажимаем кнопку рядом с надписью Server certificate,а в появившемся окне кнопку Add new.

Создаем новый сертификат устройства, все значения остаются по умолчанию. Сертификат, как видно, подписан серьезной организацией! В итоге все становится вот так:

Сейчас предлагаю скомпилировать проект, загрузить его в ПЛК и проверить программой, как работает связь. На самом деле, в результате последних изменений в настройках уровень секьюрности не поднялся ни на йоту. Все это было лишь подготовительным процессом. Потихоньку приходит время приступать к настройкам контроллера, который будет играть роль OPC UA клиента, проверить обмен данными, ну а потом уже закрыть все бреши в безопасности. Но вначале необходимо выгрузить xml файл с описанием всех тэгов (узлов, nodes) контроллера-сервера. Этот файл формируется достаточно просто система выбирает только те переменные, которые помечены флагом Accessible from HMI/OPC UA и разрешает их запись, если стоит флаг Writable from HMI/OPC UA . При этом блок данных тоже должен быть доступен по OPC UA (по умолчанию доступен). Например:

Для экспорта снова заходим в настройки CPU и ищем там OPC UA Server Export, нажимаем кнопку Export OPC UA XML file

Переходим к настройкам OPC UA клиента, то есть той стороны обмена, которая будет инициировать связь, запрашивать и записать переменные. В качестве клиентской части у меня выступает S7-1510 с прошивкой FW2.6.

9. Добавляю контроллер в проект и сразу активирую глобальные настройки безопасности.

10. Активирую OPC UA клиента

11. Активирую лицензию OPC UA

12. Генерирую сертификат этого второго, клиентского контроллера. В дальнейшем контроллер-сервер и контроллер-клиент обменяются (не без моей помощи) своими сертификатами, а подключение незнакомых устройств будет запрещено. В свойствах CPU идем на Protection & Security, жмем Add new.. в таблице Device certificates, жмем на кнопку в появившейся пустой строке, жмем Add new в появившемся окне, наблюдаем уже знакомое окно создания нового подписанного сертификата:

В поле usage я дополнительно указал, что сертификат используется для OPC UA Client'а, по умолчанию у меня был выставлен Tls.

13. Наступает одно из самых интересных: настройка клиентского интерфейса,а точнее настройка соединения к серверу и создания наборов данных для чтения и/или записи. В структуре проекта у второго (клиентского) контроллера:

PLC_2 OPC UA communication Client Interfaces Add new client interface

Жмем кнопку Import interface и подгружаем ранее экспортированный XML файл

Теперь открыты все Nodes серверного контроллера. Поскольку стоит задача учебного характера, требуется немного просто считать 4 переменных блока OKPumpsAuto.

Для этого я создаю Readlist и перетаскиваю интересные мне переменные из правой части экрана в левую. Разумеется, в боевых задачах список чтения может быть больше. Разумеется, в боевых задачах будет не только чтение, но и запись переменных. В этой заметке ограничился одним чтением. В итоге у нас получается следующее:

Итого у нас создан один интерфейс, состоящий из одного списка чтения. Набор данных для чтения подготовлен. Но чего-то не хватает, необходимо еще настроить само соединение интерфейса. Для этого открываем вкладку Properties в нижней части экрана

Необходимо прописать ip-адрес сервера, в моей случае 192.168.43.10.

На странице Security выбираем ранее созданный клиентский сертификат и пока ничего более не меняем.

Создание и заполнение клиентского интерфейса привело к автоматическому созданию двух блоков данных: Client interface_1_Data и Client interface_1_Configuration.

Смотрим блок данных Data, там уже указаны те переменные, которые планируем читать. Чертовски удобно.

14. Теперь необходимо написать программу, которая будет устанавливать связь с OPC UA сервером, готовить канал связи, читать информацию и закрывать соединение. Программа носит строго демонстрационный характер, в боевых задачах она должна быть написана по-другому. В онлайн справке на вызываемые блоки находится все необходимая информация. Там же приводится пример на языке SCL, лучше подходящий к промышленному применению, но не такой наглядный, как в моем случае.

В проект добавляются следующие меркерные переменные

Ищем функцию OPC_UA_Connect и перетаскиваем ее в нетворк OB1

Имя экземплярного блока я оставил по умолчанию. Что радует этот вызов имеет графический конфигуратор, как, например, вызовы S7-связи в TIA Portal'е или вызов PID-регулятора. Этот конфигуратор экономит просто уйму времени, а это не может не радовать.

Остается выбрать только созданный клиентский интерфейс (он один) и обвязать блок вспомогательными переменными.

Для лучшего понимания привожу скриншот из онлайн справки Step 7. Именно в таком порядке необходимо выполнять вызовы (как минимум три) перед тем, как приступить к чтению/записи данных. Любой вызов выполняется по переднему фронту входа Req. Успешное или неуспешное выполнения вызова я фиксирую (не сбрасывая, сброс только ручной) в переменных с именами done или err.

Теперь привожу скриншоты всех нетворков программы уже после того, как я последовательно сделал запрос на выполнение функциональных блоков. Как вы видите бит запроса req у меня выставлен в истину (блок отрабатывается только по переднему фронту), биты успешного исполнения (done) выставлены в истину. Если у вас ни done, ни error не выставляется в истину,а connectionid первого вызова остается равным нулю, значит, что-то сделано не так. Например, используется не тот Server Endpoint или неправильно установлен сертификат. Эти вызовы должны вызваться последовательно один за другим. Я взводил биты руками и смотрел на результат вызова, а только потом переходил к следующему. Очевидно, что полноценная программа должна осуществлять вызов автоматически и переходить на следующий шаг в зависимости от результата текущего.

Нетворк 4 самый важный, это цепочка чтения данных с сервера. Ради него все и делалось. Остальные нетворки вызывают функциональные блоки закрытия соединения и освобождения ресурсов. Их я пока не вызывал.

В результате вызова нетворка 4 в блоке данных DB2 появились прочитанные данные:

15. В настоящий момент два контроллера общаются по протоколу OPC UA, цель почти достигнута. Но не полностью. Настройки безопасности до сих пор находятся на уровне бери, чо хошь. Я спокойно могу подключиться программой OPC UA Client и читать/записывать все возможные данные. Давайте ограничим круг общения этих ПЛК, пусть они дружат только друг с другом. Переходим на серверный контроллер, свойства CPU, OPC UA Server Security Secure channel, убираем из Endpoint'ов политику No Security

Проматываем ниже до Trusted Clients. Добавляем сертификат контроллера-клиента (PLC_2). Снимаем галочку Automatically accept client certificates during runtime. Сервер теперь не будет общаться ни с кем, кроме как с клиентским PLC.

Переходим на User authentication, запрещаем гостевой доступ, создаем логин/пароль для пользовательского доступа: user1 / password1.

Прогружаем серверный PLC. Возвращаемся к клиентскому PLC, открываем Client interface, закладка Configuration, выбираем Security, в поле General выставляем режим и политику безопасности:

Проматываем ниже, выбираем тип аутентификации пользователь и пароль, указываем имя пользователя user1, пароль password1

Снимаем галочку Automatically accept server certificate during runtime

Жмем на зеленую стрелочку, сразу переходим на другую закладку настроек ищем там поле сертификаты партнерских устройств и добавляем в него сертификат сервера

Компилируем и прогружаем клиентский ПЛК (PLC_2), открываем мониторинг OB1 и последовательно вручную исполняем блоки в нетворках 1..4 Если все сделано правильно, то все блоки отработают успешно, а данные будут успешно прочитаны в DB2.

16. Осталось лишь проверить, пустит ли кого-нибудь еще серверный контроллер. Запускаем OPC UA Client и пробуем подключиться. Список Endpoint'ов возвращается. Подключаемся по Basic256 SignAndEncrypt, указав имя пользователя user1 и пароль password1.

Предлагается проверка сертификата сервера, принимаем его

Но соединение не устанавливается, сервер не принимает сертификат левого клиента.

Итого, поставленная цель достигнута. Настроен безопасный обмен данными на уровне ПЛК, то есть - "горизонтальное" взаимодействие.

Подробнее..

Веселые уроки WinCC OA. Установка WinCC OA под Debian и перенос прикладного проекта

30.12.2020 08:08:41 | Автор: admin

Скачивая недавно с сайта winccoa.com установщик последнего патча версии 3.17, с некоторым удивлением, постепенно перешедшим в ликование, обнаружил, что список поддерживаемых дистрибутивов Linux расширился и до Debian. Дело в том, что посмотреть на работу системы в ОС, отличной от Windows, мне хотелось давно, но из всех дистрибутивов Linux я более-менее понимаю только Debian, а привыкать к новому ради баловства откровенно не хотелось. Собственно, и под Debian установка проходит не сильно гладко.

Итак, по порядку. Считаем, что дистрибутив уже скачен с сайта. Лицензия у меня установлена на виндовую машину, да она особо и не нужна. В домашней директории пользователя (он должен находится в группе sudoers'ов) создаю директорию winccoadist, куда распаковываю содержимое скаченного архива.

Запускаю терминал (как обычно, нажатием CTRL+ALT+T) и перехожу в свою директорию с дистрибутивами. Смотрю список файлов.

В связи с тем, что никаких репозиториев тут нет, пакеты являются файлами, необходимо провести установку в правильной последовательности. Вначале установить пакет системы лицензирования codemeter, потом базовый пакет WinCC OA, а далее опциональные пакеты, среди которых мне интересны демо-проекты (Applications), справка на русском и английском (Help) и драйвер S7Plus. Как это частенько бывает в чудесном мире бесплатного линукса некоторые вещи сделаны через такое место, которое в приличном обществе все или почти все называют задницей. Касается это как самих дистрибутивов, так и поставщиков ПО под них. Предвижу ворчание со стороны опытных *nix'оидов, однако с обывательской точки зрения вот так... а я простой обыватель, поймите правильно Для установки пакетов в Debian обычно применяются команда apt, которая сама умеет проверять зависимости пакетов. Поэтому первые два ставим через apt. Для этого в терминале вводим команду

sudo apt install ./codemeter_7.10.4196.501_amd64.deb

и ждем ее завершения.

Далее устанавливаем базовый пакет WinCC OA, который содержит основную инсталляцию все менеджеры, ядро и т.д.

sudo apt install ./WinCC_OA_3.17.9-Base-debian.x86_64.deb

Установка так же завершается успешно. Можно даже посмотреть и убедиться, что система установилась, и ее можно запускать. Правда, в моем случае мне потребовалось вначале закрыть текушую сессию пользователя и залогиниться в систему заново.

Пока что все неплохо, тот же Project Administrator успешно запустился.

А вот с дополнительными пакетами все сложнее. Команда apt по непонятным мне причинам находит неразрешенную зависимость и отказывается ее устанавливать. Причем, ругается на, якобы, неустановленный базовый пакет WinCC OA. Складывается ощущение, что apt проверяет зависимости с учетом регистра. А вот команда dpkg не учитывает регистр при проверке. Поэтому далее нужные мне опции я устанавливаю командой dpkg

sudo dpkg -i ./WinCC_OA_3.17.9-Applications-debian.x86_64.deb

Аналогично устанавливаю справку и драйвер S7plus

sudo dpkg -i ./WinCC_OA_3.17.9-Help_EN-debian.x86_64.deb

sudo dpkg -i ./WinCC_OA_3.17.9-Help_RU-debian.x86_64.deb

sudo dpkg -i ./WinCC_OA_3.17.9-S7Plus-debian.x86_64.deb

Вся система и демо-проекты установились успешно в директорию /opt/WinCC_OA/3.17

Теперь я хочу перенести сюда прикладной проект, получившийся в результате моего базового учебного курса (https://vk.com/wall183956096_8006) и запустить его.

Копирую всю папку с проектом Workshop в свою домашнюю директорию в Debian. Убеждаюсь в том, что я являюсь владельцем (owner) директории Workshop и всех вложенных файлов и директорий. Теперь необходимо скорректировать вручную конфиг-файл проекта. Открываю файл /home/earl/Workshop/config/config

Необходимо скорректировать пути pvss_path (путь к установке WinCC OA) и proj_path (путь к самому проекту WinCC OA). Изменяем эти пути.

Запустим Project Administrator и зарегистрируем в системе мой проект.

Проект запускается, данные с ПЛК читаются, модель клапанов работает.

Если начнутся проблемы с запуском менеджеров архивов в Linux, то способ решения приведен по ссылке:https://www.winccoa.com/knowledge-base/detail/can-a-wincc-oa-project-be-copied-from-windows-to-linux.html

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

Подробнее..

Самоучитель по WinCC OA. Часть 3. Глобальные скрипты (control scripts)

30.11.2020 14:07:23 | Автор: admin

Запрограммированое в предыдущей части поведение задвижки нелогично. В обработчике нажатия кнопки Открыть или Закрыть мы непосредственно задавали значение элемента под названием Position. При том, что в самом DPT у нас уже предусмотрены команды Открыть и Закрыть.

Datapoint type FlapDatapoint type Flap

Разумеется, в реальной жизни для управления каким-либо агрегатом мы, как правило, задаем значение соответсвующей команды, представленной в виде переменной контроллера. Поскольку реального контроллера в этом workshop пока нет, мы будем имитировать поведение технологического оборудования посредством скрипта.

Но для начала изменим обработчик нажатия на кнопки Открыть и Закрыть.

Скрипт на нажатие кнопки OpenСкрипт на нажатие кнопки Open

Меняем на

main(mapping event){  dpSet("System1:Flap1.Commands.Open", 1, "System1:Flap1.Commands.Close", 0);}
Измененный скрипт кнопки OpenИзмененный скрипт кнопки Open

Обратите внимание, что этот скрипт задает значение двум DPE, но, как было сказано в конце прошлой части, это выполняется одним сообщением. Выставляется команда Открыть и сбрасывается команда Закрыть, это своего рода защита от дурака (которая, в принципе, должна и так быть в прикладной программе контроллера, но мы перестраховываемся).

Аналогично поступаем со скриптом кнопки Close

Проверим выполнение скрипта нажатия кнопок, меняются ли переменные команд в модуле Para

Нажатие кнопки OpenНажатие кнопки OpenНажатие кнопки CloseНажатие кнопки Close

Разумеется, в настоящий момент положение заслонки не меняется, так как нет обработчика команд. По нажатию кнопок сейчас должны менять свои значения тэги open и close соответствующей точки данных.

Для создания скрипта мы должны в gedi найти в дереве проекта Scripts, нажать правую кнопку мыши и выбрать Add New CTRL Script

Дадим осмысленное имя файла скрипта, я его назвал Model

После нажатия ОК скрипт появляется в дереве проекта

Далее двойным кликом на файле открываем скрипт для редактирования. Теперь необходимо продумать поведение модели и структуру самого скрипта. С учетом ярко-выраженного событийного поведения всей системы WinCC OA, этот скрипт должен вызывает функцию dpConnect, завязанную на одну из переменных команд управления задвижкой. Разберемся по шагам.

  1. Вызываем dpConnect на изменение значения переменной команды. В данном случае у нас очень упрощенная модель, защита от дурака реализована в скриптах нажатия кнопки, поэтому достаточно будет привязаться и к одной команде.

  2. Создаем callback функцию на изменение значения команды в рамках модели поведения.

Другие варианты поведения модели неверны с точки зрения идеалогии WinCC OA. Если в самом глобальном скрипте вызывать dpGet для чтения значения переменной команды, то этот скрипт надо вызывать постоянно, с определенной периодичностью.

Напоминаю, что у функции dpConnect есть два аргумента. Первый аргумент имя callback-функции (я назвал ее OnOpen_CB), второй имя точки данных, на которую происходит подписка. Итого, в упрощенном виде, без каких-либо проверок функция main скрипта Model выглядит так:

main(){dpConnect("OnOpen_CB", "System1:Flap1.Commands.Open");}

Далее напишем саму callback-функцию. У нее тоже два аргумента имя точки данных (тип данных string) и новое значение этой точки данных (должно соответствовать типу данных исходной точки). Получается вот такая заготовка.

void OnOpen_CB(string dp1, bool bNewValue){;}

Дописываем обработчик, он очень простой. Если значение команды открыть равно истина, то задаем положение задвижки, равное 90. Если значение равно ложь, то значение 0.

void OnOpen_CB(string dp1, bool bNewValue){if (bNewValue) {dpSet("System1:Flap1.Inputs.Position", 90);} else {dpSet("System1:Flap1.Inputs.Position", 0);}}

Теперь этот созданный скрипт необходимо как-то вызвать. Для исполнения глобальных скриптов используется Control Manager. Следовательно, требуется добавить в список менеджеров системы вызов еще одного менеджера (Control), где в качестве параметра задается имя исполняемого скрипта. В системе есть уже один вызов Control. И его трогать не следует во избежание нехороших последствий. Разве что, вы работаете с системой на уровне эксперта, но тогда зачем вам читать эти заметки?

Существующий список менеджеровСуществующий список менеджеров

В консоли WinCC OA нажимаем кнопку Append new manager, выбираем в появившемся окне менеджер Control. Для первого запуска свежесозданного скрипта имеет смысл выбрать режим запуска (Start mode) ручной (manual), чтобы не наблюдать попытки перезапуска в случае ошибок в самом скрипте. В качестве параметров вызова менеджера необходимо указать его номер в системе. В нашем случае это будет номер 2. Почему 2? Потому что менеджер с номером 1 в системе уже существует. Менеджеры одного типа в системе должны запускаться со своим уникальным номером. Именно одного типа. Это значит, что в системе может быть ui с номером 1 и ctrl с номером 1, а вот два ui (или ctrl) с одним и тем же номером быть не должны. Поэтому в качестве агрумента запуска я указываю строку -num 2. Кроме того, требуется передать имя исполняемого скрипта. Вызов нового менеджера выглядит следующим образом:

Свойства Control менеджера для симуляции задвижкиСвойства Control менеджера для симуляции задвижки

Остается нажать кнопку ОК и запустить менеджер вручную кнопкой Manager Start либо мышью через вспывающее меню (новый менеджер при этом должен быть выделен в списке). Если все сделано правильно, то добавленный менеджер позеленеет и примет статус 2.

Скрипт симуляции успешно запущенСкрипт симуляции успешно запущен

Теперь остается проверить работу симуляции.

По нажатию кнопки Open визуализируется открытиеПо нажатию кнопки Open визуализируется открытиеКнопка Close визуализирует закрытиеКнопка Close визуализирует закрытие

Следует обратить внимание на то, что Control Manager запускает скрипт (точнее, свою функцию main) один раз при старте. После выполнения функции main() необходимые callback функции продолжают находится в памяти ПК, они исполняются при выполнении условий, указанных в dpConnect (по изменению значения переменной). Однако, если в сам скрипт были внесены изменения, то необходимо вручную остановить соответствующий экземпляр control-менеджера и запустить его заново. Без останова-запуска изменения не будут приняты.

Сам control manager при запуске создает свой отдельный процесс. Его функция main выполняется в отдельной нитке (потоке, thread). Callback функция (в нашем случае OnOpen_CB) так же запускается в отдельном потоке. После выполнения функция main перестает работать, но callback продолжает находится в памяти ПК (в своем потоке) и вызывается при изменениях подписанной переменной.

Подробнее..

Самоучитель по WinCC OA. Часть 4. Повторное использование объектов. -параметры

02.12.2020 06:07:25 | Автор: admin

В предыдущей части мы завершили создание визуализиции задвижки и создали простейший скрипт, имитирующий ее поведение.

У нас есть одна панель под названием Flap, которая отображает и шлет команды для одной задвижки Flap1. Именно такая точка данных указана во всех скриптах этой панели. Возникает закономерный вопрос что делать, если задвижек не одна? И даже не две. А несколько десятков, сотен и даже тысяч (для распределенной системы WinCC OA и несколько миллионов сигналов не помеха, смотрим на Большой Андронный Коллайдер, где применяется именно это система, и завидуем).

Очевидный вариант создать несколько десятков, сотен и тысяч панелей, где каждая точки данных приведена явно, отметаем долго, хлопотно и грозит огромными трудозатратами в случае малейших изменений, неизбежных во время ПНР.

Другой вариант, но не единственный, создание шаблона на основе имеющейся панели. Создадим копию имеющейся панели Flap, для чего выберем пункт меню Panel Save Panel As. Зададим имя Panel_ref.pnl (окончание _ref подразумевает reference, т.е. ссылку, или, если будет угодно, шаблон)

Откроем панель Flap_ref (она и так должна быть открытой после сохранения). Отредактируем скрипты панели, выбрав в меню Edit Edit Panel Scripts. Откроется окно, содержащее все скрипты всех графических примитивов данной панели.

Для задвижки у нас создан собственный тип точки данных, и такие вещи, как положение или команда открытия в любом скрипте будут одинаковыми для всех задвижек. Различаться будут только имена задвижек, т.е. имена точек данных: Flap1, Flap2 и Flap3 в нашем простом случае. Для того, чтобы создать шаблон необходимо заменить имя задвижки, Flap1 на конструкцию, содержащую $-параметр (он так и называется в документации доллар-параметр). Проще все замены выполнять посредством Find&Replace в редакторе. Скрипты теперь выглядят так.

// [RECTANGLE3] [3] - [Initialize]// SimpleCtrlScriptStart {invalid}main(){  EP_setRotation();}void EP_setRotation(){  dyn_errClass err;  if( !dpExists( "System1:" + $dp + ".Inputs.Position:_online.._value") )  {    setValue("", "color", "_dpdoesnotexist");    return;  }  dpConnect("EP_setRotationCB",            "System1:" + $dp + ".Inputs.Position:_online.._value");  err = getLastError();  if (dynlen(err) > 0)    setValue("", "color", "_dpdoesnotexist");}void EP_setRotationCB(string dp1, int iNewValue){  float MIN_VALUE = 0;  float MAX_VALUE = 90;  float MIN_ROTATION = 0;  float MAX_ROTATION = 90;  float fRotation;  fRotation = ( 1.0 * (MAX_ROTATION - MIN_ROTATION) / (MAX_VALUE - MIN_VALUE)) *              (iNewValue - MIN_VALUE) + MIN_ROTATION;  if (fRotation > MAX_ROTATION) fRotation = MAX_ROTATION;  else if (fRotation < MIN_ROTATION) fRotation = MIN_ROTATION;  setValue("", "rotation", fRotation);}// SimpleCtrlScript {EP_setRotation}// DP {System1:" + $dp + ".Inputs.Position}// DPConfig {:_online.._value}// DPType {int}// PVSSRange {0}// Min {0}// Max {90}// MinRotation {0}// MaxRotation {90}// SimpleCtrlScriptEnd {EP_setRotation}// [PUSH_BUTTON1] [4] - [Clicked]main(mapping event){  dpSet("System1:" + $dp + ".Commands.Open", 1, "System1:" + $dp + ".Commands.Close", 0);}// [PUSH_BUTTON2] [5] - [Clicked]main(mapping event){  dpSet("System1:" + $dp + ".Commands.Open", 0, "System1:" + $dp + ".Commands.Close", 1);}

Было:

System1:Flap1.Inputs.Position:online..value

Стало

System1:" + $dp + ".Inputs.Position:online..value

Строка, которая ранее содержала непосредственно элемент точки данных, теперь формируется из первой постоянной части (System1), к которой добавляется $dp, после чего добавляется вторая постоянная часть, которая так же не зависит от точки данных, т.е. от конкретной задвижки. Знак + подразумевает объединение строк. Сами строки в данном случае заключены в кавычки. В явном виде такую панель использовать, разумеется, не получится. Необходимо задать подстановку для $dp (Flap2, например) при вызове этой панели.

Используя метод аналогии, можно сравнить $-параметры с формальными и фактическими параметрами функции в любом языке программирования. При вызове функции мы всегда должны задавать фактические параметры, значения которых заменят формальные, и функция отработает.

Теперь создадим новую панель. Пусть она называется Flaps. Сделаем новую панель чуть побольше.

Далее необходимо перетащить мышью из дерева проекта панель Flap_ref на рабочее поле открытой панели Flaps. При этом система автоматически определит присутствие $-параметров и предложит подставить вместо формального значения фактическое.

Drag'n'dropDrag'n'drop

Зададим имя клапана, вместо $dp укажем Flap1. Нажмем на кнопку Save and Run in QuickTest Mode и убедимся, что клапан 1 реагирует на нажатия кнопок Open и Close то есть, открывается или закрывается. Если клапан вдруг не реагирует на команды, посмотрите состояние контрол-менеджера, добавленного в предыдущей части, он может быть остановлен (тогда его надо, разумеется, запустить, или просто перевести режим запуска из ручного в автоматический, чтобы каждый раз не отвлекаться).

Все работаетВсе работает

Добавим точно так же панель для Flap2

Проверяем. Первый клапан работает (управляется), второй- не работает. Почему? Все просто, созданная вчера модель (в виде скрипта) управляет всего лишь одним клапаном Flap1. Остальные клапаны в модели не описаны.

Второй клапан не работаетВторой клапан не работает

Доработаем имеющуюся модель для того, чтобы она управляла и вторым клапаном тоже. Модифицируем быстро, но неправильно, путем копи-паста. Создаем еще две функции dpConnect и две разных callback-функции, переименовываем первую callback-функцию. В итоге получается такой код.

Не забываем перезапустить Control Manager этого скрипта (тот, что с опцией -num 2). После модификации модели проверяем изменения и видим, что оба клапана управляются независимо.

В связи с тем, что на DPE Position у нас натравлен конфиг с функцией, третий клапан на экран пока не выносим (собственно, я его и в модель-то напрасно внес).

Подробнее..

Самоучитель по WinCC OA. Часть 5. Работа с журналом тревог

04.12.2020 04:07:31 | Автор: admin

(* Начиная с этой части я перешел на версию WinCC OA 3.17. Никаких отличий в масштабах базового курса не будет. Изменятся лишь надписи на скриншотах.*)

При создании типа точки данных Flap мы уже предусмотрели битовый DPE для аварии Момент (FlapAlarmsTorque). Однако в настоящий момент для всех трех точек данных (Flap1, Flap2, Flap3) это всего лишь элемент, переменная. Для того, чтобы изменение этой переменной фиксировалось в подсистеме сообщений, необходимо повесить на этот DPE соответствующий конфиг. Для этого открываем модуль para и ищем наши точки данных.

Добавляем к DPE Torque точки данных Flap1 конфиг Alert Handling

Открываем настройки добавленного конфига. Обратите внимание, что внешний вид настройки Alert Handling зависит от типа переменной, к которой относится сам аларм. В настоящий момент мы работаем с типом данных bool, внешний вид окна следующий.

Good range касается значения самое переменной какое из значений является плохим (т.е. при каком значении считаем, что аларм сработал), а какое хорошим (аларма нет). Так же задаем текст при появлении аларма и его исчезновению. Зададим этот текст, как came (пришло) и went (ушло). За хорошее значение будем считать битовое значение ложь, т.е. аларма нет.

Класс аларма весьма важный параметр. Он определяет многие аспекты отображения сигнализации: какой будет цвет, задействовано ли мерцание, будет ли звуковое уведомление, требуется ли квитирование и т.д. Выбираем класс S7_Alarm и ставим галочку рядом со словом Active. После выставления аларма активным все настройки становятся недоступны. Обратите внимание, что настройки активного аларма недоступны для редактирования не только на визуальной форме, но и средствами скриптов (а скриптами в WinCC OA можно много чего сделать, включая и динамическую работу с алармами). Настройки допускается менять только для неактивных алармов.

Перейдем в модуле para на конфиг original, посмотрим текущее значение и поменяем его на истину.

Текущее значение переменной FALSE, аларм неактивенТекущее значение переменной FALSE, аларм неактивенТекущее значение переменной TRUE, аларм активен, текст мигает очень быстроТекущее значение переменной TRUE, аларм активен, текст мигает очень быстро

Вернем значение переменной в FALSE. Текст аларма остается came, продолжает мигать, изменилась лишь интенсивность его мигания.

Данный класс алармов подразумевает необходимость квитирования. Для подтверждения аларма в этом окне необходимо нажать кнопку Acknowledge, после чего все вернется в нормальное состояние.

Возникает вопрос где можно ознакомиться с настройками каждого класса алармов? Как можно модифицировать существующий класс алармов или задать свой класс? Это реализуется через точки данных (вообще любые настройки системы живут либо в точках данных, либо в конфиг-файлах). Ну, а если что-то доступно через точки данных, то это что-то вполне возможно модифицировать через программный код. Правда, сейчас мы этого делать не будем. Лучше посмотрим модуль para и поищем нужные точки данных.

На первый взгляд тут есть много точек данных, но где же DP, ответственные за классы алармов? Выставляем галочку Internal datapoints (внутренние точки данных) и видим, что полку точек данных заметно прибыло.

Ищем точки данных типа _AlertClass, тут и содержатся все классы алармов, которые можно изменить (на свой страх и риск, разумеется), либо создать свой новый класс. Поскольку мы выбрали для нашего единственного аларма класс S7Alarm, смотрим его настройки, развернув соответствующую точку данных.

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

Только что мы смотрели, как работают алармы в модуле para. Это очень интересно и познавательно для разработчика, однако не очень удобно. Ознакомимся еще с одним способом просмотреть список событий. Для этого в меню gedi найдем и нажмем кнопку System Management

Перейдем в Diagnostics

Откроем Alarmscreen

И в появившемся окне нажмем на зеленый треугольник внизу панели

Откроем модуль para, найдем Flap1.Alarms.Torque и поиграем с его значениями

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

Если задать Time range в Open и выбрать Historical Data, то мы сможем увидеть историю алармов.

В связи с тем, что тема алармов весьма обширная, а это всего лишь первый взгляд, не стоит удивляться некоторым непонятным вещам. Например, мне самому непонятно, почему в этой таблице Alarm text у нас везде состоит из одного слова came (нуууу когда-нибудь, наверное, может быть, если фаза луны сойдется, то разберусь).

Alarmscreen тоже очень интересен. Смотреть на нем алармы куда лучше, чем в модуле para. Однако, мы делаем конечное приложение для конечного пользователя, т.е. для оператора. Удобно ли будет оператору каждый раз открывать через менюшки отдельное окно аварий? Лично я в этом сильно сомневаюсь. Давайте лучше займемся интеграцией окна сообщений в наше приложение пользователя.

Перейдем обратно в редактор gedi и откроем созданную ранее панель Flaps. Далее посмотрим внимательно на левую часть редактора gedi. Кроме нашего проекта (у меня он называется Workshop) есть еще один проект с названием 3.17 (в самом начале этой главы я уже признался, что перешел на новую версию, а так был бы проект с названием 3.16), который мы точно сами не создавали. Его можно развернуть и поизучать, там много всего интересного скриптов, библиотек, панелей и т.д. Пытливые умы потратят немало времени на ознакомление.

По сути, это и есть ядро системы WinCC OA. Этот проект содержит все или почти все, относящееся к самой платформе gedi, para, панель Project Administrator, панель консоли, вся логика. И, вуаля, всем этим можно пользоваться в своих приложениях. Вот, например, я открыл в редакторе gedi панель para. Его можно изменить. И использовать в своих целях измененную копию. Про модификацию стандартных (или системных?) компонент WinCC OA поговорим чуть попозже в этой же части. А сейчас наша задача разместить окно с алармами в окне пользовательского приложения.

Редактировать модуль para пока не будем (хоть и очень хочется)Редактировать модуль para пока не будем (хоть и очень хочется)

Для этого в дереве системного проекта 3.17 ищем панель по следующему пути: 3.17 (версия Вашей копии WinCC OA) Panels vision aes AESRow.pnl. Перетаскиваем ее на свободное место открытой панели Flaps. Система попросит задать значение $-параметра $SCREENTYPE. Цинично проигнорируем эту просьбу, нажав кнопку Cancel.

Внизу у нас появился небольшой элемент отображения

Проверим, работает ли оно вообще, для чего зададим в модуле para значение истина для аварийного сигнала.

Как видно, работаетКак видно, работаетСкрыл модуль para, аларм есть и активно мигает (чего на видно на скриншоте)Скрыл модуль para, аларм есть и активно мигает (чего на видно на скриншоте)

Теперь поговорим немного о модификации стандартных компонент WinCC OA. Например, сейчас я растянул в высоту окно отображения алармов. В нем добавилось строк, однако кнопки и цифры в правой части растянулись в высоту, что плохо влияет на эстетику. Упростим себе задачу и просто уберем эти кнопки.

Для этого в редакторе gedi кликнем правой кнопкой на AESRow и выберем Open panel reference

Откроется оригинальная панель

Удалим некрасивые кнопки и цифры

Нажмем Save и увидим следующее окно

Ответим утвердительно, после чего редактируемая нами панель сохранится в виде копии в структуре нашего проекта Workshop, а не по системному пути. В нашем проекте мы будем работать с этой копией. Теоритечески можно сохранять по системному пути (например, путем подмены файлов), то эти изменения становятся общими для всех проектов WinCC OA, что нежелательно. Особенно негативно сохранение по системному пути, а не в виде локальной копии, может сказаться после установки патчей. Патчи могут корректировать, в том числе, и системный проект, и даже ту панель, которую вы изменили. Вероятность этого всегда отлична от нуля. Соответственно, устанавливая патч, вы рискуете утратить свои изменения, если сохранили их в системный проект.

Есть еще один нюанс, связанный с модификацией системных панелей и патчами. Если вы работаете с локальной сохраненной копией проекта, то натравленный на систему патч исправит только системный проект, но не вашу локальную копию панели.

В общем, модификация ядра это ответственное занятие, требующее внимательности. Не забывайте читать readme патчей, затронуты ли там модифицированные вами панели. У вас в руках очень мощный инструмент, но пользоваться им надо уметь.

После внесения изменений в панель AESRow нашу панель Flaps необходимо переоткрыть, чтобы изменения вложенной панели вступили в силу.

Последний пример в этой части визуализация пиктограмм технологического оборудования, находящегося в аварином состоянии, тем же способом (цвет, мерцание и т.д.), который задан соответствующему классу аварий. Для этой демонстрации разместим на панели Flaps окружность (Circle).

Зададим динамизацию события Initialize через визард, как уже делали ранее для задвижки. Выбираем в визарде Change color

Выбираем Background color и Alert Handling, жмем Next. Выбор Alert Handling позволит системе подтянуть значение цвета от аларма.

Выбираем Datapoint element

Жмем Next, а в следующем окне Finish. Запускаем на проверку и смотрим, что получилось. В настоящий момент аларм у меня активен и не подтвержден, круг быстро моргает серым и красным (как и класс алармов S7_Alarm).

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

Взглянем на полученный скрипт

В данном случае происходит подписка на актуальный цвет аларма из соответствующего конфига, который назначается непосредственно в качестве фонового цвета нашего графического объекта.

Подробнее..

Самоучитель по WinCC OA. Часть 6. Навигация Открытие новых окон

07.12.2020 10:20:40 | Автор: admin

До настоящего момента весь наш прикладной проект состоял, фактически, из одной экранной формы Flaps (панель Flap можно уже не рассматривать, она неактуальна, а Flap_ref является шаблоном). Реальные боевые проекты содержат, как правильно, (значительно) больше одной мнемосхемы, отображающие целую картину, отдельные технологические участки, настройки, тренды, алармы и т.д. Рассмотрим, каким образом в системе WinCC OA возможно осуществлять переход между экранами.

Создадим еще одну панель в проекте и назовем ее Trends (на будущее), сделаем ее размер сопоставимым с размером панели Flaps и поместим на нее что-нибудь читаемое. Например надпись Это тренды, чтобы быть уверенным наверняка.

Панель TrendsПанель Trends

Для вызова панели Trends из панели Flaps разместим на последней кнопки и назовем ее Panels, для чего изменим имя объекта (Name) и метку (Button label). Разумеется, имя и метка разные вещи, имя идентифицирует объект в проекте, а метка содержит текст, видимый оператору.

Посредством визарда зададим кнопке функцию открытия новой панели. Выбираем кнопку, ищем событие Clicked и выбираем рядом с событием Clicked вызов мастера Property Wizard. В визарде выбираем Panel Functions и жмем Next.

Выбираем Open panel (in new module) и снова жмем Next.

Вдумчиво смотрим на следующее окно визарда

Рассмотрим параметры визарда:

Panel file файл панели, которую мы будем показывать. Выбираем (можно через кнопку справа, только там выбор файла по умолчанию идет по расширению xml, не забудьте его изменить на all files) файл Trends.pnl

Panel name имя экземпляра панели. Очень важный параметр! На этапе повторного использования графических объектов при помощи $-параметра мы убедились, что одну и ту же панель можно вызывать множеством экземпляров. При этом (при множественном использовании панели) каждый вызываемый экземпляр должен быть четко и уникально идентифицирован. Для этого и предназначен этот параметр. Обратите внимание, что за уникальностью имени экземпляра должен следить непосредственно разработчик, система не отслеживает дубли (два или больше разных вызов с одинаковыми именами панели). Наличие таких дублей в системе чревато очень веселыми чудесами, а точнее непредсказуемым поведением окон. Зададим в визарде имя Trends. Никакие параметры в эту панель не передаются (панель содержит одну-единственную надпись), поэтому тут заполнять не требуется.

Жмем Next и смотрим следующие настройки

По умолчанию будет выполнено открытие экрана в дочерней панеле. Добавим еще опцию Panel always on top, поставим эту галочку и нажмем Finish.

Выполним панель Flaps и нажмем кнопку PANELS, появится окно Trends.

Открылось дочернее окно, при этом перейти на родительскую панель или что-нибудь на ней нажать невозможно (из-за выбранной опции modal).

Проверим следующий режим вызова, для чего вернемся к визарду кнопку PANELS. Уберем модальный режим и проверим исполнение. В этом случае родительское окно доступно, хоть и перекрыто дочерним. По крайней мере, можно нажимать кнопки управления задвижками родительского окна.

Открыл клапан 1Открыл клапан 1

При этом, если закрыть родительское окно, то дочернее так же закроется оно существует только в связке с родительским.

Выберем следующий режим открытия панели Root panel in own module

Проверяем.

До нажатия кнопки

После нажатия кнопки

Происходит полное замещение панели: Flaps пропала (все ее объекты стерты из памяти рантмайма), появилась панель Trends. Модуль при этом остался тот же, в нашем случае модуль называется _QuickTest_

Следующий режим открытие в новом модуле

В этом случае создается новый модуль (можно еще назвать его контейнером), в котором уже, в свою очередь, открывается наша панель. Если не задавать имя новому модулю (оставить пустым поле Module name), то этот вызов сводится к предыдущему панель будет открыта в исходном модуле. За уникальностью имени модуля так же необходимо следить самостоятельно. В рамках одного ui система позволяет обратиться к любому графическому элементу. Надо лишь знать его имя. Полное имя объекта складывается из имени модуля, имени панели и имени графического объекта. Пусть новый модуль будет незамысловато называться Module

Жмем Finish и проверяем.

В этом случае у нас получается два полностью независимых окна. Обратите внимание на имена модуля и панели каждого окна все соответствует. При закрытии изначального окна (_QuickTest_) новое окно остается.

Подробнее..

WinCC OA Workshop. Часть 7. Навигация Создание интерфейса АРМ

11.12.2020 08:05:27 | Автор: admin

В прошлый раз мы разбирались с тем, как в WinCC OA можно открывать дополнительные окна. Сейчас давайте приступим к созданию полноценного интерфейса операторской системы. Как правило, в АСУ ТП операторская система состоит из области навигации (переход между мнемосхемами), расположенной в верхней части экрана, основного рабочего поля и области сигнализации, расположенной в нижней части.

Создаем панель Main, в которую будем встраивать остальные компоненты. Ее размер делаем больше размера панели Flaps.

Через Cut и Paste (вырезать/вставить) переносим панель алармов с панели Flaps на панель Main и корректируем размер панели алармов.

Создадим кнопки для открытия панелей Flaps и Trends.

Осталось определить главную рабочую область, где будут находиться основные мнемосхемы. В WinCC OA эта рабочая область называется Embedded Module (можно провести аналогию со Screen Window или Picture Window портальной или классической WinCC). Embedded Module дословно означает Встроенный модуль. Если в предыдущей части создавался некий внешний модуль, то в данном примере модуль, предназначенный для отображения панелей, интегрирован в панель. Embedded Module расположен среди инструментов графического редактора

Разместим его в свободном месте панели Main. Сразу после размещения система предлагает задать анимацию, с которой будут открываться новые окна. Можно задавать, а можно и нет. Давайте пока обойдемся без рюшечек, анимацию не задаем.

Тут возникает еще один тонкий нюанс. У каждого графического объекта и, конечно же, у каждого модуля в системе должно быть свое уникальное имя. По причинам, известным лишь разработчикам, имя только что созданного модуля, по которому с ним можно работать скриптами (и визардами, которые на выходе тоже создают скрипт) задается не на вкладке Standart редактора свойств, а на вкладке Extended.

Ниже привожу скриншот вкладки стардарт. Там указано имя модуля EMBEDDED_MODULE1, и это неправильное имя.

Это неправильное имяЭто неправильное имя

Правильное имя модуля указывается на другой вкладке, и по умолчанию в моем случае равно Vision_1

Давайте переименуем этот встроенный модуль и дадим ему имя Module. Предвидя вопросы, что у нас уже есть модуль с таким именем, отвечу, что по предыдущей схеме с созданием модуля Module в скрипте кнопки мы более работать не будем, хотя, вопрос, конечно же, хороший и правильный.

Теперь необходимо задать действия по нажатию кнопок FLAPS и TRENDS. Задаем событие Clicked, работаем в текстовом режиме (не визардом на этот раз). Нам необходима функция RootPanelOnModule. Можно и нужно использовать автоподстановку. Например, сейчас я набрал текст RootPanel и нажал кнопки CTRL+TAB.

Если функция подсвечивается синим то все неплохо. Если же черным, то в имени фунции допущена ошибка. Не забывайте, что регистр в имени функции тоже играет роль.

Первый параметр этой функции имя панели. У меня это Flaps.pnl. Второй параметр имя панели, пусть будет Flaps. Далее имя модуля, мы его только что задали, Module. Последний параметр функции это параметры, передаваемые непосредственно панели. Тип этой переменной dyn_string, динамический массив строк неопределенной заранее размерности. Сейчас никаких дополнительных параметров мы передавать не будем, однако это значении необходимо указать. Объявим переменную типа dyn_string и укажем ее в вызове функции открытия панели. Получаем следующий код открытия окна

Аналогично выглядит и скрипт кнопки TRENDS

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

Внесем косметические изменения в панели Flaps и Trends, уберем ненужные элементы (панель алармов и кнопку справа), изменим размер панелей.

Запускаем окно Main.pnl на исполнение и проверяем поведение кнопок FLAPS и TRENDS. Все должно работать. Если не работает, ищите ошибки.

Подробнее..

Самоучитель по WinCC OA. Часть 8. Тренды

14.12.2020 08:18:37 | Автор: admin

Оживим уже созданную (но пустую) панель Trends графиком изменения переменной во времени. Однако, перед тем, как смотреть на тренды, их необходимо сконфигурировать и каким-то образом задать значения, чтобы они скопились в базе данных. Необходимо, чтобы в системе была переменная, которая меняла свое значение. Необходимо повесить соответствующий конфиг на эту переменную, чтобы значения складывались в архив. Для типа точек данных Flap у нас есть DPE с названием Flow (расход) и типом int. Этот DPE и будем использовать для ознакомления с трендами. Для имитации поведения системы у нас уже есть созданный control-скрипт Model. Предлагаю его и использовать для иммитации расхода. Откроем скрипт Model

Напомню, что точкой входа в скрипт (как и в языке C) является функция main(). В настоящий момент функция main() исполняется, происходит связывание изменения DPE с его функцией-обработчиком (callback-функцией), после чего main завершает работу, но в памяти остаются сами callback-функции.

Изменяем функцию main следующим образом

main(){  dpConnect("OnOpen_CB1", "System1:Flap1.Commands.Open");  dpConnect("OnOpen_CB2", "System1:Flap2.Commands.Open");  dpConnect("OnOpen_CB3", "System1:Flap3.Commands.Open");  for (;;) {    dpSet("System1:Flap1.Inputs.Flow", rand());    dpSet("System1:Flap2.Inputs.Flow", rand());    delay(1);  }}

Теперь после выполнения связывания DPE с callback у нас стоит бесконечный цикл (при помощи конструкции for(;;)), который задает случайным образом значения расхода для клапанов 1 и 2, после чего ожидает 1 секунду при помощи функции delay. В этом случае функция main не будет завершаться и будет работать, пока запущен ее CTRL-менеджер.

(Кстати, да тут достаточно и одного вызова dpSet, а не двух.. Совершаю ошибки, про которые сам же и говорил ранее)

После перезапуска CTRL-менеджера (в связи с изменением скрипта) нужно убедиться, что модель работает, взглянув на значения расхода в модуле para.

Пришло время визуализировать изменения расхода. Откроем панель Trends. Паренесем на панель графический элемент Trend из палитры инструментов редактора gedi.

Необходимо выбрать режим отображения тренда

Стандартный режим значение по времени. Второй режим Value over value был разработан для специфических требований некоторых заказчиков для сопоставления невременных значений. Например распределение давления по трубопроводу, где по оси X километровая отметка трубы, а по оси Y значение давления на отметке. В нашем случае выбираем первый вариант, расположение горизонтальное, нажимаем ОК. Далее выбираем точку данных для отображения, выбираем расход первого клапана.

Далее через кнопку Append добавляем еще одну кривую расход второго клапана. Итого закладка Curve (кривая) выглядит так

если выбрали график #1_1, и так:

если выбрали (для настроек отображения, конечно же) график с именем #1_2. Нажимаем кнопку Close. Панель Trends в редакторе теперь выглядит так

Сохраняем и закрываем панель Trends и запускаем панель Main, нажимаем в исполнении кнопку TRENDS. После я вижу, что окно с трендами как-то меняется, то есть я вижу динамику, но пока она очень ненаглядна и весьма непонятна.

Связано это с тем, что значение меняется каждую секунду, отображается сейчас текущее значение (архивация еще не настроена), а по умолчанию выбрана временная шкала в два часа. Разумеется, график выглядит очень сжатым. Поиграв колесиком мышки на шкале времени, на шкалах оси X для каждого из трендов, а так же на основном рабочем поле, можно получить более наглядное изображение. Оси можно не только масштабировать колесиком, но и двигать, перемещая мышь с зажатой на оси левой кнопкой. Можно выделить мышью на рабочем поле тренда любую его часть, экран будет масштабирован под выделенное. Если вы что-то нажали, и все сломалось, просто нажмите кнопку 1:1 в верхней части экрана, масштабы вернутся к изначальной конфигурации.

Однакратный щелчок мышью на рабочем поле показывает линейку или ruler

При активном рулере можно с нажатым Shift снова кликнуть на рабочем поле, тогда отобразится т.н. диференциальный рулер

Функционал этого окна очень широк и дает гораздо больше возможностей, чем может показаться с первого взгляда. Можно синхронизировать оси. Можно выставлять несколько рулеров. И т.д. Очень много чего можно. На официальных курсах трендам уделяется примерно половина учебного дня из пяти, и это только базовый курс.

В настоящий момент, если полностью закрыть окно тестирования и открыть его заново, то все значения начнут отображаться только с момента открытия окна графиков. Это вполне закономерно, так как на точках данных не размещен конфиг архивации, т.е. данные не пишутся в базу. Вернемся в модуль para. Встанем на элемент точки данных Flap1.Input.Flow и добавим к нему конфиг _archive

Тут необходимо выбрать Archive Settings. Появился конфиг _archive, выберем его.

Тут необходимо выбрать один из шести типов архивов

Если посмотреть на консоль системы, то и менеджеров архива у нас запущено тоже шесть экземпляров

То, что я сейчас рассказываю про тренды (точнее, про архивирование) касается исключительно встроенной файловой базы данных. В WinCC OA есть возможность архивации в базу Oracle. В версии 3.17 появилась возможность использования InfluxDB, которая при создании проекта обозначена, как NextGen архиватор. Сейчас же говорим про классическую файловую базу. В качестве индекса (первичного ключа) в ней выступает метка времени сигнала. Если говорить очень приблизительно, то на все заданные тренды у нас создается одна таблица. А значения сигналов с поля меняются по-своему, но записываются в базу данных по изменению. Если свести все тренды в одну таблицу, то ее использование будет весьма неоптимальным, в таблице будет очень много пробелов. Для оптимизации нам предлагается в рамках одного менеджера архивов (у которого есть свои настройки, и они могут отличаться или отличаются от настроек соседниех архивных менеджеров) хранить переменные, интенсивность изменений которых более-менее одинаковая. Не рекомендуется совмещать в рамках одного архива переменные, которые меняют свои значения с очень разной частотой, например раз в секунду и раз в час. Это очень неточное описание, которое лишь приблизительно объясняет наличие нескольких архивных менеджеров в системе. А при наличии NextGen архиватора на базе InfluxDB, возможно, данное описание вообще теряет смысл, однако в настоящей заметке дублируется оригинальный курс, так что это объяснение сохраняется по соображениям совместимости.

В нашем демонстрационном примере обе переменные, меняющиеся раз в секунду, необходимо архивировать в рамках одного менеджера. Пусть это будет менеджер ValueArchive_0000.

Выбираем Active, нажимаем Apply.

То же самое проделываем для второго клапана. Запускаем снова на исполнение панель Main, открываем тренды, подгоняем масштаб и смотрим, что изменилось

Красной линией рисуется расход первого клапана, синим второго. На этом скриншоте видно, что синяя линия начала рисоваться позже красной. Это связано с тем, что архивные настройки для второго клапана были применены после того, как я настраил архивацию первого клапана. Запись данных началась сразу после выставления Active и нажатия кнопки Apply.

На практике может потребоваться не просто визуально отобразить исторические значения переменной, но и получить их в числовом виде (в виде массива, например) для какой-либо дальнейшей обработки. Универсальным инструментов для этого является старый-добрый SQL-запрос. Для более удобного визуального формирования запроса к базе данных WinCC OA предоставляет отдельный инструмент SQL Query. Чтобы добраться до него необходимо запустить (в том же gedi в меню Module) System Management

Далее открыть Reports

И SQL-Query. Ставим тут галочку напротив слова ALL в рамке Value type (в скриншоте не проставлена, а должна быть).

На вкладке SELECT выбираем те значения DPE, которые необходимо включить в выборку. Система архивирования, на самом деле, запоминает не только пару метка времени значение, но и массу другой информации. Но мы сейчас прочитаем из базы только значение и метку времени originalvalue и originalstime. Для этого из выпадающего списка Configuration выбираем искомое и добавляем его в список Elements of the SELECT Statements при помощи кнопок Append или Insert, расположенных справа от списка. Кнопки не подписаны. К этим кнопкам и этому диалоговому меню необходимо привыкнуть, на первый взгляд там все немного неоднозначно.

На следующей вкладке From мы определяем, из каких точек данных мы хотим вытащить значения.

Тут можно воспользоваться механизмом шаблонов, написать в текстовом поле Flap* и добавить этот текст в список Elements of the FROM statement.

Все остальные параметры пока игнорируем и переходим на вкладку Data

Нажимаем вначале кнопку Create query, после чего кнопку Start query, получаем набор данных.

Попробуем эти же данные получить в программном коде. Скопируем куда-нибудь SQL-запрос. Откроем панель Main и добавим на нее кнопку с меткой EXPORT

Начнем программировать скрипт на событие Click этой кнопки. SQL-запрос, скопированный из окна SQL-query я временно разместил в комментарии к этому коду

Сейчас нам потребуется применить функцию dpQuery. dpQuery отличается от функции dpGet тем, что возвращает массив значений, которые удовлятворяют SQL-запросу, в то время, как dpGet возвращает лишь одно значение. Первый параметр функции запрос SQL. Второй параметр в переводе на русский звучит как двумерный массив неопределенного типа и неопределенной размерности, а в типах данных WinCC OA как dyndynanytype. Объявим в скрипте переменную этого типа. Разбирать полученные данные мы будет, конечно же, имея представление что именно мы запрашиваем. И это представление мы имеем, как авторы запроса.

main(mapping event){  dyn_dyn_anytype Tab;  dpQuery("SELECT ALL '_original.._value', '_original.._stime' FROM 'Flap*'", Tab);}

Результат запроса складывается в Tab, но этот результат необходимо еще куда-то вывести. В качестве примера выводить полученные данные будем Log Viewer при помощи функции DebugN. Данная функция незаменима для дебага во время разработки, тестирования и наладки системы. В качестве параметров допускается приводить несколько строк. Совет из практики указывать дополнительно в DebugN не только отладочную информацию, но и заголовок отладочной информации. Если проект очень большой и над ним работает большой штат, то не помешает так же указывать, кто именно выводит в лог. Причина на то простая разработчиков может быть много, а лог в системе один. Зная, что выводится и кто выводит можно подойти к коллеге и вежливо поинтересоваться, а что тут, собственно, происходит. Зная заголовок вывода можно провести глобальный поиск в проекте и найти этот вызов на тот случай, если вызов DebugN был оставлен после ПНР, его вывод осуществляется далеко не на постоянной основе, сам проект давно в работе, а разработчик давно уволился. Культура разработки, если двумя словами.

В конечном итоге обработчик кнопки EXPORT выглядит следующим образом

main(mapping event){  dyn_dyn_anytype Tab;  dpQuery("SELECT ALL '_original.._value', '_original.._stime' FROM 'Flap*'", Tab);  DebugN("SQL", Tab);}

Сохранив скрипт, запустим снова окно Main на исполнение. Найдем окно Log Viewer (оно открывается всегда автоматически при запуске системы), очистим вывод журнала кнопкой крестик для нашего удобства

Нажмем в рантайме кнопку EXPORT и посмотрим на вывод в журнале

Выгрузка получилась очень большая, и показано далеко не все, о чем LogViewer честно сообщает

Обидно, но логично. Выводить несколько мегабайт текста в журнал не лучший выбор. На практике переменную Tab можно разобрать и натравить на нее свою математику. Можно вывести информацию в таблицу и так далее.

Подробнее..

Самоучитель по WinCC OA. Часть 10. Подключение к живому S7-1200

26.12.2020 12:22:33 | Автор: admin

рамках базового курса в системе WinCC OA используются только внутренние переменные системы. Никаких внешних подключений не предполагается. Однако, слушатели базового курса всегда под завершение учебы просят продемонстрировать, как же считать переменную с настоящего живого ПЛК. Поскольку WinCC OA относится к продуктам компании Siemens, то логичным будет продемонстрировать подключение к контроллеру компании Siemens и чтению с него нескольких переменных. В нашем случае будем подключаться к PLC серии S7-1200.

Набор драйверов WinCC OA включает в себя два вида драйверов для контроллеров Simatic это s7 и s7plus. Разница в них следующая: s7 предназначен для связи с ПЛК классической серии S7-300 / S7-400, а s7plus для современной линейки S7-1200 / S7-1500. Драйвер s7plus указывается при установке отдельно. Он может отсутствовать в вашей системе, если вы его не устанавливали. Вне зависимости от того, какой используется драйвер (хоть iec104), общие принципы сохраняются. Необходимо в консоли добавить соответствующий драйвер. Далее сконфигурировать соединение с устройством и задать этому соединению номер добавленного драйвера, активировать. Так же требуется на DPE навесить конфиг Periphery Address и выполнить настройки, указав корректный адрес переменной.

Для начала необходимо прописать в консоли драйвер. Технически добавление драйвера в систему не отличается от добавления менеджера. Откроем консоль, нажмем в ней Append a new manager

Выберем в списке драйвер S7plus и зададим в опциях -num 2. Это связано с тем, что в системе уже есть драйвер с номером 1, это Simulation Driver, а номер драйвера в системе должен быть уникален. К слову, по словам разработчиков WinCC OA, симуляционный драйвер в реальных проектах не используется.

Теперь новый драйвер добавлен в систему и запущен

Теперь добавленный драйвер с номером 2 в системе необходимо сконфигурировать. Для этого (например через меню редактора gedi) необходимо открыть модуль System Management.

Далее открываем Driver S7

Выбираем S7+ Driver

В настоящий момент в системе нет сконфигурированных соединений. Для создания связи с существующим контроллером нажимаем кнопку Create.

Тут необходимо указать имя для соединения и способ работы с данными либо оффлайновый проект, находящийся во вложенной папке проекта WinCC OA, либо онлайн связь с уже готовым и настроенным ПЛК. В нашем случае S7-1214 с залитой конфигурацией и программой лежит на столе рядом с ПК и доступен по протоколу TCP/IP, так что, работаем онлайн. Указываем номер только что добавленного и запушенного драйвера, это номер 2. Имя соединения далее превратиться в системную точку данных, с которой возможно работать посредством программного кода.

Далее требуется указать тип контроллера, я задам его явно S7-1200, а так же ввести ip-адрес моего ПЛК. Дополнительно, если вы еще не настраивали, требуется вызвать окно настройки сетевой карты компьютера, нажав кнопку Set PC/PG Interface. По нажатию этой кнопки откроется окно, знакомое всем, кто работал с классическим Step 7 или настраивал запуск операторской системы WinCC 7, TIA Portal WinCC и т.д. Если вы незнакомы с этим окном, то там необходимо указать ту сетевую карту, при помощи которой ваш ПК подключен к вашему ПЛК. У меня данный интерфейс давно настроен, и это окно выглядит следующим образом

Моя сетевая карта присутствует тут в трех экземплярах, с окончаниями ISO, TCPIP и TCPIP.Auto. Как правило, применяется последний вариант, TCPIP.Auto. После внесения настроек связи данное окно имеет следующий вид

Ставим галочку напротив Establish Connection и нажимаем кнопку Apply. После чего WinCC OA несколько секунд тратит на установление связи. Eсли все было сделано правильно, окно приобретает следующий вид

Нажимаем кнопку ОК, а после закрываем окно модуля System Management. Далее необходимо связаться с тэгами контроллера, которые в нем уже прописаны. Ограничимся двумя дискретными переменными и одной вещественной. Для работы с точками данных у нас есть модуль para, открываем его. В нем уже есть несколько готовых типов точек данных ExampleDP_bit и ExampleDP_float, их и будем использовать. Создадим точку данных MyBlinker типа ExampleDP_bit

Добавим к точке данных конфиг переферийный адрес.

Выбираем тип драйвера SIMATIC S7PLUS

Конфигурируем

Указываем номер драйвера 2. Указываем направление данных Input, только чтение. Указываем тип преобразования Bool. Вводим способ сбора данных Polling (непрерывный опрос).

Далее нажимаем на кнопку Poll groups, надо создать группу циклического (непрерывного) опроса данных. В следующем окне жмем Create, задаем имя группы и ее настройки. Переменные этой группы будут опрашиваться кажые 100 мс. В соответствии со справкой организовать опрос быстрее таким способом невозможно, любые значения цикла опроса меньше 100 мс будут считаться за 100 мс. Делаем группу активной и жмем ОК.

В графе Reference необходимо указать имя переменной в контроллере. Поскольку ПЛК у меня сконфигурирован и на связи, я могу просматривать его тэги в режиме онлайн. Нажимаем кнопку Selection в верхней части окна.

Открывается окно со всеми живыми тэгами контроллера, доступными для операторской системы. Я выбираю двоичный тэг Clock_1Hz, который меняет свое значение каждую секунду.

Теперь ставим галочку Address active, жмем Apply и можно перейти на конфиг original и посмотреть, меняется ли значение тэга в нашей SCADA.

Да, значение тэга меняется каждую секунду

Точно так же пропишем в системе бит Emulation, находящийся в блоке данных Modes. Действуем по аналогии с предыдущим битом за исключением Направления (Direction), тут ставим режим доступа чтение и запись. Все остальные настройки (кроме, разумаеется, символьного имени тэга ПЛК) аналогичны.

Сейчас значение бита FALSE, бит читается.

Изменим в ПЛК его значение на TRUE

В модуле para его значение так же изменилось

Теперь попробуем поменять его значение на FALSE и посмотрим состояние бита средствами TIA Portal. Выполнить эту операцию средствами para не удается. Скорее всего, это связано с тем, что поллинг переменной идет 10 раз в секунду, в para он обновляется так же быстро, и я просто физически не успеваю внести в Original value значение FALSE, вместо TRUE. Даже выделить значение дабл-кликом или кнопками Ctrl+A не удается. Пробуем изменить DPE кнопками на панели операторской системы. Для этого в верхнюю часть главного экрана Main я размещаю две кнопки Turn On и Turn Off и создаю скрипты для них, соответственно

dpSet("System1:Emulation.:_original.._value", 1);

и

dpSet("System1:Emulation.:_original.._value", 0);

Пробуем теперь отключить тэг.

По нажатию кнопки в модуле para значение изменилось на FALSE

Значение изменилось и в блоке данных контроллера.

Поскольку средствами скриптов операторского интерфейса удается изменить значение тэга, значит со связью все в порядке. Но, все таки, хочется иметь возможность задавать значение и через para. Я рассуждаю следующим образом. Драйвер обновляет значение сигнала принудительно 10 раз в секунду (poll time равен 100 мс). Драйвер ничего не знает про то, изменилось ли значение сигнала или нет он просто поллит заданую переменную и отдает ее в event manager. EV тоже не знает, изменился ли тэг или нет, и точно так же передает любое новое значение туда, где на них существует подписка. 100 мс это очень быстро для человеческой реакции, поэтому в модуле para я просто не успеваю вбить новое значение, оно тут же перезатирается обновленным от драйвера. Значит, необходимо настроить систему таким образом, чтобы сообщения с новым значением тэга летели адресатам только в том случае, когда значение действительно изменилось. Для этих целей на DPE необходимо разместить конфиг Smoothing. Возвращаемся в модуль para и добавляем конфиг на точку данных.

Оставляем его настройки, как есть сравнение старого значения с новым. Не забываем нажать Apply.

Переходим на конфиг original этой точки данных и наблюдаем, что метка времени тэга (как online, там original) перестала меняться, как сумасшедшая. Обращаем внимание и на то, что теперь в модуле para возможно изменить значение бита, и оно доходит на контроллера.

Теперь пропишем вещественную переменную, которая находится в ПЛК по адресу Robicon.SCADAmanSP. Для переменной в WinCC OA воспользуемся готовым типом DP ExampleDP_float. Ее создание и настройка переферийного адреса аналогична предыдущим настройкам, за исключением очевидных деталей имя, адрес, тип данных. Направление зададим, как чтение/запись. На этот раз я не выбирал тэги онлайн, а вбил символьное имя переменной непосредственно в поле ввода Reference. Не забываем добавить конфиг smoothing и для этой DP.

Делаем адрес активным и смотрим конфиг original. Видим, что связь установлена, значение с ПЛК приходит.

Изменение значения так же доходит и до контроллера.

Напоследок отобразим значение этой переменной на мнемосхеме FLAPS (не создавать же новую панель ради одной проверки). Разместим на панели элемент Textfield из палитры.

Визардом на событии Initialization создами скрипт отображения значения DPE (Display value)

Значение с ПЛК отображается

Добавим еще один скрипт при помощи визарда для возможности редактирования значения прямо с операторского экрана. Для этого нам потребуется вызвать визард на событие Command.

Изменим значение сигнала с операторской системы

До блока данных изменения долетели

Подробнее..

OPC UA для CPU S7-1200 (FW4.4). Настройка сервера

31.12.2020 20:05:20 | Автор: admin

Начиная с версии 4.4 операционной системы контроллеров линейки S7-1200 появилась возможность опрашивать их по протоколу OPC UA. В настоящий момент времени поддерживается только серверная часть (ПЛК может отвечать на запросы клиентов), клиентская часть не поддерживается.

В настройке OPC UA сервера на S7-1200 есть отличия от S7-1500 (забегая вперед, скажу, что серверный интерфейс требуется создавать вручную, без этого ПЛК не будет отдавать никаких пользовательских данных, хотя и разрешит входящие подключения).

В первую очередь заходим в свойства и включаем сервер OPC UA.

Не забываем так же указать в настройках, что лицензия на OPC UA была приобретена.

То есть, если не вдаваться в важные тонкости, вроде шифрования трафика и вопросов ограничения доступа, все делаем, как и для S7-1500. Чтобы продемонстрировать ошибочность этого подхода, выполним загрузку CPU прямо сейчас и подпробуем к нему подключиться. В качестве клиента OPC UA применяется та же программа, которая использовалась в примерах работы протокола для линейки S7-1500. Единственное отличие заключается в том, что при установленной на программатор Windows 10 программу-клиент мне приходится запускать с администраторскими полномочиями.

Подключимся к ПЛК.

Сколько ни крути, сколько ни ищи, но никаких переменных пользовательской программы мы сейчас не найдем. Только разного рода вспомогательная информация по серверу.

Связано это с тем, что у нас не создан серверный интерфейс, то есть, не указаны переменные, которые сервер будет отдавать клиенту. В серии S7-1500 этот интерфейс создается по-умолчанию в настройках CPU, и по умолчанию OPC UA сервер отдает все тэги, для которых проставлены разрешения к доступу по OPC UA. Посмотрим скрин-шот настройки серверы для CPU S7-1516

Для 1200ой серии необходимо найти в дереве проекта OPC UA Communications Server Interfaces и нажать там Add new server interface

Далее перетащим из правой части экрана в левую те тэги, доступ к котором необходимо предоставить по протоколу OPC UA

Выполним компиляцию и загрузим ПЛК. Теперь попробуем подключиться к OPC UA заново. Теперь у нас появился интерфейс Server interface_1 и все заданные в нем переменные.

Значение переменной успешно читается.

Подробнее..

Сервер Modbus TCP для Simatic S7-1200 S7-1500

06.01.2021 08:23:22 | Автор: admin

Первая спецификация протокола Modbus была опубликова в 1979 году. Протокол предназначен для опроса подчиненных устройств по принципу запрос-ответ. Modbus RTU (Remote Terminal Unit) работает по последовательному интерфейсу передачи данных (RS-232, RS-485, RS-422). Сегодня речь пойдет о немного измененном протоколе, Modbus TCP, работающий на прикладном уровне стека протоколов TCP/IP.

Для начала посмотрим, как настраивается (программируется, если быть точнее) серверная часть. Modbus TCP Server аналог Modbus RTU Slave, то есть, является подчиненным устройством. Это важно, не путайте. Сервер лишь отвечает на запросы, но не генерирует их.

В данном примере применяется CPU S7-1516 с версией прошивки 2.6. Серия S7-1200 программируется аналогично.

Для начала разместим в OB1 экземпляр функционального блока MB_SERVER (Instructions Communications Others MODBUS TCP).

Далее необходимо сделать три вещи. Во-первых, подать что-нибудь на вход MB_HOLD_REG. Этот входной пин экземпляра ФБ должен содержать область памяти, которая выделяется на регистры хранения (holding registers).

Небольшое отступление. В версиях библиотек Modbus TCP до 5.0 переменные дискретные входы (Discrete inputs), т.е. те двоичные переменные, которые можно только читать это непосредственно все BOOL'евые переменные из области процесса %I. Coils, катушки дискретные переменные, которые можно и читать, и записывать, это область %Q. Input Registers, входные регистры это слова данных из области %I, точнее %IW. Грубо говоря, все дискретные переменные протокола Modbus и аналоговые входа являются переменными областей памяти I или Q. Это дает возможность читать непосредственно значение входов, а так же записывать значения дискретных выходов напрямую. С моей точки зрения нелогично отдавать возможность управлять дискретными выходами какой-нибудь сторонней системе, пусть даже и теоритическую, поскольку в зависимости от построения прикладного ПО контроллера, на эти выхода будет приходить правильное с точки зрения системы значение. Для того, чтобы ограничить клиентам Modbus TCP возможность прямого обращения к выходам, в экземпляре функционального блока есть несколько переменных.

Нас интересуют все переменные, которые начинаются на IB и QB. Указав в качестве значений QB_Count, QB_Read_Count и IB_Count нули, вместо значения по умолчанию 65535, мы запрещаем полностью чтение/запись входов/выходов напрямую.

Для чтения/записи регистров хранения, в свою очередь, необходимо отдельно вручную задать область данных. Мой личный опыт показывает, что наиболее удобный способ это структура, объявленная в глобальном блоке данных со стандартным (а не оптимизированным) доступом. Я сейчас продемонстрирую, как надо, а под конец данной заметки мы пройдемся по граблям и посмотрим типичные ошибки, которые возникнут, если заполнить данное поле неправильно.

В версии библиотеки, начиная с 5.0 (требуется прошивка 2.5 для S7-1500 и 4.2 для S7-1200) можно иначе переназначать входные дискреты, катушки и прочие переменные модбас. Например завести все в битовые переменные глобального блока данных. Необходимо дополнительная конфигурация, которая описана в пункте Access to data areas in DBs instead of direct access to MODBUS addresses as of version V5.0 встроенной справки.

Итак, добавляем глобальный блок данных с неоптимизированным доступом в картинках.

Нажать Add new block

Выбрать Data block и дать ему осмысленное имя, далее нажать ОК

Вызвать свойства свежедобавленного блока данных

Найти в атрибутах блока галочку Оптимизированный доступ, снять ее, подтвердить снятие и нажать ОК

Открыть в редакторе блок данных и создать в нем отдельную структуру

Заполнить поля этой структуры. Имеет смысл сразу в коментариях делать пометки о номере(адресе) регистра хранения. Откомпилировать блок данных.

Подать созданную структуру на входной пин MB_HOLD_REG

Во-вторых, требуется создать и заполнить структуру типа TCON_IP_v4 или TCON_Configured. Данная структура содержит некоторые подробности для коммуникации контроллера. Лично я предпочитаю первый способ, он мне кажется более аскетичным, а кроме того он не требует загрузки Hardware, в отличии от второго. В связи с тем, что структура относится к настроечной части протокола Modbus, ее можно разместить в уже созданном блоке данных (хотя, никто не запрещает объявить ее, где угодно).

Добавление структуры типа TCON_IP_v4

Поле InterfaceID заполним чуть позже, а сейчас пройдемся по остальным полям.

ID внутренний идентификатор соединения. Допустимые значения от 1 до 4096. Каждое соединение (экземпляр блока MBSERVER, хотя на самом деле все немного сложнее). должно иметь свой уникальный идентификатор. Ставлю равным 1.

ConnectionType тип соединения. По умолчанию стоит 11 (0B в шестнадцатиричной системе): TCP. Его и оставляем.

ActiveEstablished оставляем false, в данном случае сервер не является инициатором связи, инициатором связи являютя клиенты.

RemoteAddress если оставить нули, то к серверу сможет подключиться любой клиент. Если задать удаленный IP-адрес конкретно, то к серверу может обратиться только один явно заданный клиент. Оставляем нули.

RemotePort оставляю ноль, не органичиваю и номер порта со стороны клиента

LocalPort номер TCP порта, по которому будет отвечать сервер. В соответствии со старой-доброй традицией (и RFC) протокол Modbus TCP работает на порту 502 (а игра Doom по порту 666, но это совсем другая история). Порт 502 я указываю явно.

В итоге получаем следующее:

Осталось задать лишь ID интерфейса. Это присвоение я делаю в программное коде, разместив network с присвоением (MOVE) до вызова блока Modbus. Идентификаторы интерфейсов уже созданы в Step 7 автоматически, необходимо лишь найти нужную переменную. В моем случае Modbus будет работать на интерфейсе X1. Его я и нахожу в списке переменных, выпадающем автоматически.

Можно так же подсмотреть название нужной переменной, зайдя в аппаратную конфигурацию, выбрав нужный интерфейс и вкладку System Constants этого интерфейса. Привожу скриншот всего экрана, чтобы было понятно, где искать.

Можно так же просто указать значение 64 для переменной "ModbusData".CONNECT_Struct.InterfaceId

Далее подаем на вход CONNECT заполненную структуру и получаем следующую программу:

И, наконец, в третьих, не забываем про переменные экземпляра MB_SERVER_DB. Я о них говорил выше, описание этих переменных можно почитать во встроенной справке. Если их не трогать, то обмен, все равно, будет работать, это уже вопрос доводки обмена и доступа ко входам и выходам.

Компилируем программу, загружаем ее в контроллер и выходим Online:

Статус 7002 не означает ошибку, он говорит о том, что соединиение устанавливается. Обязательно почитайте описание возможных значений поля STATUS, пригодится. Перед тем, как начать читать/записывать данные при помощи стороннего Modbus-клиента, дадим переменным ненулевые значения (разумеется, мои любимые число зверя и три топора).

В качестве Modbus-клиента можно использовать любой проверенный софт. Главное правильно сформировать запрос со стороны клиента. В нашем случае объявлено всего 5 регистров хранения, и если запросить 10, то сервер Modbus вернет ошибку, и будет прав. Второй немаловажный момент не забывайте про порядок байт в слове: если little endian отображать, как big endian, или наоборот, то вместо разумных чисел на экране будет ерунда. На данном скриншоте клиент настроен на опрос 5 регистров хранения, представление данных, как float, настроено переворачивание байт в словах:

Чуть выше я говорил, что дискретные выхода контроллера (точнее, биты области %Q) это и есть койлы с точки зрения протокола Modbus, и что при настройках по умолчанию клиент получит возможность как читать сигналы напрямую, так и записывать их. Давайте в этом убедимся. Для начала на модуле дискретных выходов я объявляю переменную, для дальнейшего удобства:

Нулевой бит восьмого байта выходной области. Номер 64, если считать с нуля (8 * 8 + 0 = 64). Задам в контроллере значение истина и прочитаю в Modbus-клиенте:

Вижу значение истина (читаю один койл с начальным смещением 64). Изменю это значение на ложь со стороны modbus:

Значение, разумеется, так же изменилось и в Step 7, и в контроллере, и на выходе модуля (это одно и то же):

Как я уже говорил, нехорошо давать прямой доступ к управлению всяким сторонним системам. Для формирования выходных сигналов есть внутренняя логика программы, продуманные и прописанные алгоритмы управления, защит и блокировок. Поэтому снизим до нуля количество доступных к записи койлов (байт выходного простраства, если точнее):

После этого изменения в блоке данных (прямо в online, без перезаливки и перезагрузки контроллера) клиент протокола modbus в ответ на требование записи катушки показал табличку Illegal data address, а именно такое сообщение и вернул сервер. Дополнительную информацию читаем в справке: Restriction of read access to process images as of version V5.0.

Теперь давайте посмотрим, что происходит при некорректном назначении области памяти от регистров хранения. В первую очередь достаем встроенную справку Step 7 и читаем:

В качестве регистров хранения применять глобальный блок данных с оптимизированным доступом или битовую область. И вот тут очень интересно. Потому что справка в части MBHOLDREG parameter выглядит следующим образом:

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

Эксперимент 1. Регистры хранения это структура в блоке данных с оптимизированным доступом (почти, как сделано в этом примере). В этом случае получаем ошибку 8187 : The MBHOLD_REG parameter has an invalid pointer. Data area is too small.

Эксперимент 2. Массив переменных типа WORD, объявленный в оптимизированном блоке данных. Работает, со стороны клиента переменные меняются, ошибок нет.

Эксперимент 3. Меркерная область. Работает, с клиента удалось внести значения, ошибок нет.

С моей точки зрения, в документации недостаточно ясно. Должно быть написано используйте блок данных со стандартным доступом или битовую (меркерную) память, а не оптимизированным доступом. В случае оптимизированного доступа вполне подойдут массивы слов. И с моей точки зрения самым удобным способом является способ, описанный в изначальном примере. Эксперимент 2 в принципе тоже работоспособен (и тому есть объяснение), но с моей точки зрения неудобен для работы.

В следующий раз мы займемся клиентом Modbus TCP.

Подробнее..

Клиент Modbus TCP для Simatic S7-1200 S7-1500

07.01.2021 14:19:53 | Автор: admin

Продолжаем тему программирования протокола Modbus TCP на контроллерах Simatic S7-1500. В прошлый раз речь шла о серверной части, сегодня опишем клиентскую. Клиент Modbus TCP это узел, который генерирует запросы к серверу, т.е. запрашивает данные и передает уставки/команды. В терминологии Modbus RTU это мастер, ведущее устройство. В отличии от RTU, в протоколе TCP может быть несколько мастеров (правильно клиентов).

Программировать клиентскую сторону сложнее. Если для сервера достаточно одного вызова функционального блока и одного блока данных, то с клиентом не все так просто. Во-первых, клиент может обмениваться данными с несколькими серверами, что на практике и происходит. Во-вторых, к одному серверу может быть (и бывает) больше одного запроса прочитать входные регистры, прочитать регистры хранения, записать команды в выходные койлы, и все это с одним абонентским устройством. В-третьих, не забываем про остроконечный и тупоконечный порядок байт в словах разных аппаратных платформ, при несовпадении байты необходимо переворачивать самостоятельно.

По этой причине имеет смысл программировать клиента на языке SCL (ST в терминологии МЭК 61131-3) и завернуть всю обработку в функциональный блок. Для большей реалистичности в данном примере контроллер будет общаться с двумя серверами Modbus TCP с несколькими запросами к каждому.

В первую очередь создадим функциональный блок ModbusClient на языке SCL и добавим вызов его экземпляра в OB1.

Далее в области STAT переменных функционального блока необходимо прописать две структуры TCON_IP_v4. Зачем две? Затем, что у нас два соединения с двумя разными серверами. Фактически у нас два разных соединения (connection) и каждое необходимо описать. Как я говорил ранее, возможно применить и конфигурируемые соединения, но в данном примере они не используются.

Объявлено две структуры для связи с двумя серверами

Далее необходимо заполнить обе структуры. Это возможно сделать как программным кодом, так и просто занести необходимые значения данных. Пойдем по второму пути.

Первое поле, InterfaceId. Идентификатор интерфейса (или сетевой карты) нашего контроллера. Клиент Modbus работает на интерфейсе 1 контроллера, смотрим его ID в конфигурации устройства.

Его ID равен 64. Обращаю внимание, что нужен идентификатор именно интерфейса, а не его портов.

Следующее поле структуры, ID. Это идентификатор соединения. Не путать с идентификатором интерфейса. Не путать с номером модбас-устройства. Это некий внутренний логический номер коннекшена, который программист назначает самостоятельно в диапазоне от 1 до 4096. У каждого коннекшена должен быть свой уникальный идентификатор. Ответственность за корректное присвоение целиком на ваших плечах. Назначаем ID = 1 и едем дальше.

Далее идет тип соединения, ConnectionType TCP или UDP. По умолчанию значение этого поля 0x0B в hex или 11 в dec. Оставляем по умолчанию, TCP.

Флаг ActiveEstablished. Выставляем его в истину. В случае клиента именно наша сторона должна инициировать соединение.

RemoteAddress. Тут пишем IP-адрес нашего первого сервера. Пусть будет 192.168.43.100.

RemotePort. Номер порта, по которому сервер Modbus TCP будет отвечать на наши запросы. По умолчанию все сервера этого протокола должны слушать порт 502.

LocalPort. Оставляем равным нулю.

В итоге, описание соединения с первым сервером выглядит следующим образом.

Описание соединения с первым сервером

Вторая структура заполняется аналогично. Разумеется, пишем другой ID и другой IP адрес. В итоге получаем.

Сделаем первые робкие шаги и попробуем прочитать один регистр хранения с одного сервера. Для начала надо перетащить ФБ MB_CLIENT из библиотеки в программу.

После перетаскивания появится диалогое окно о создании экземпляра. Выбираем мульти-экземпляр и немного корректируем имя.

Выбираем мультиэкзепляр

Промежуточный итог

Приведем вызов в человеческий вид

Кратко пройдемся по параметрам этого вызова. Подробное описание в нашей горяч0 любимой документации, которую мало кто, почему-то, читает.

REQ активирует выполнение опроса. Пока REQ = TRUE, клиент проводит чтение данных с сервера или запись данных на сервер.

DISCONNECT разорвать соединение

MB_MODE режим работы клиента. В совокупности со входом MB_DATA_ADDR оказывает влияние на используемую функций Modbus TCP. Возможные значения описаны в документации. Для чтения одного или нескольких регистров хранения значение MODE должно быть равно 0.

MB_DATA_ADDR указывает адрес в адресном пространстве протокола Modbus TCP. Значение нашего примера 40001 первый регистр хранения

MB_DATA_LEN количество читаемых или записываемых величин. В нашем случае единица. В итоге все три указанных выше параметра означают читать один регистр хранения начиная с адреса 40001

MB_DATA_PTR переменная или структура данных, куда мы записываем прочитанное значение. Переменная может быть в любом блоке данных, я объявил локальную статическую переменную SingleHR типа INT, размер которой равен 2 байтам и совпадает с размером одного регистра хранения Modbus. При несовпадении размерности читаемой области данных с локальным хранилищем вызов функционального блока завершится ошибкой.

CONNECT уже созданная нами структура типа TCON_IP_V4

Остается только запустить на ноутбуке сервер Modbus, скомпилировать и загрузить программу контроллера, и не получить ничего. Сервер не отвечает. Ответов нет. Вообще ничего нет. Ничего. По буквам Николай, Илья, Харитон ( Остапа понесло ). Для того, чтобы уточнить ошибку, необходимо доработать программу следующим образом.

Дело в том, что флаги успешного (DONE) или неуспешного (ERROR) вызова блока живут всего один цикл сканирования программы. Естественно, невозможно заметить настолько быстрое изменение. Поэтому по флагу ошибки я копирую статус вызова в отдельную переменную. А по флагу успешного выполнения обнуляю статус.

Кроме того, добавлены флаги управления запросом и соединением.

Немного прокоментирую ошибку, которая возникла у меня. В моем случае код ошибки был 80C6. В описании на блок MB_CLIENT этой ошибки нет, поэтому я вбил код ошибки в поиск справочной системы и нашел ссылку на функцию TCON (так же при неоднозначных ошибках можно искать и среди TSEND, TRECEIVE и прочих похожих блоках). Описание: The connection partner cannot be reached (network error). Ошибки сети. Ответ был очень прост и заключался в том, что программа-иммитатор Modbus не была прописана в разрешениях встроенного в Windows Firewall. Точнее, разрешение на ее работу было настроено только на частные сети, а интерфейс программатора был назначен в качестве публичной сети. Это лишний раз подчеркивает, что техника виновата в последнюю очередь, а чаще всего ошибку надо искать в радиусе закругления рук и в соответствии этого радиуса ГОСТам. После изменения настроек брэндмауэра ОС обмен заработал.

Усложним теперь задачу самую малость, и попробуем считать с сервера одну вещественную переменную. Одна вещественная переменная (REAL) это 4 байта. Или 2 регистра. Итого, в вызове я увеличил количество читаемых регистров до 2, и изменил указатель на прочитанные данные. Этот указатель все еще весьма прост это внутренняя статическая переменная типа REAL (дальше будет интереснее).

Хотелось бы обратить внимание на одну важную деталь. Если прогружать измененное прикладное ПО на горячую, с переинициализацией переменных нашего функционального блока ModbusClient в то время, когда контроллер ведет опрос сервера Modbus, то обмен может прекратиться, и на выходе блока будет стоять статус 80A3. Связано это, разумеется, со вмешательством во внутренние структуры обмена (из-за переинициализации всего блока). В моем случае это приводило к полной невозможности коммуникаций до рестарта контроллера переключателем старт/стоп. Я намеренно изменил сейчас функциональный блок (добавил еще одну переменную), чтобы продемонстрировать эту ошибку:

После стоп/старта контроллера и поднятия флага Srv1Req обмен успешно возобновляется. Чтобы не допустить такого зависания обмена (как ни крути, это частный случай) необходимо поднимать флаг Srv1Disconnect, проводить изменения в переменных функционального блока (имеются в виду именно переменные, т.е. интерфейсная часть блока, а не сам программный код), выполнять загрузку с переинициализацией, а потом вручную возобновлять обмен. Помните же, что флаги REQ и DISCONNECT у нас подключены к переменным, и этими переменными можно управлять, как вручную, так и посредством программного кода.

Пока мы не продвинулись дальше, хочется продемонстрировать описанный выше случай с разноконечностью (little-endian и big-endian) данных. В моем примере сервер modbus держит в двух регистрах хранения вещественную переменную со значением 0.666. Наш клиент Modbus вместо этого числа читает 1.663175E+38, что сильно отличается от нужного (увы, вне зависимости от того, покупаем мы или продаем). Связано это, конечно же, с порядком байт в словах и порядком самых слов в двойном слове. Пробуем разрешить ситуацию. Доработаем программный код следующим образом.

Инструкция SWAP меняет порядок байт (конкретно тут в двойном слове). Но в данном случае она не помогает, на выходе (в переменной Data.Test) все еще находится неправильное значение. Скорее всего, это означает, что сервер отдает регистры в неправильном порядке, а байты в правильном, то есть информация перемешалась. Радует, что байта всего 4 и составить их в нужном порядке дело техники.

Итак, снова модифицируем запрос. Складываем результат чтения двух регистров в массив из 4 байт и объявляем еще один массив из 4 байт, которым и будем манипулировать.

Функция Deserialize складывает массив из байт в какое-либо конкретное значение, в данном случае в вещественную переменную. Потребовалась всего одна итерация, чтобы получить корректное значение переменной с сервера Modbus.

Перед тем, как вернуться к штатной рутинной работе, необходимо рассказать про одну очень частую ошибку, возникающую при обмене по протоколу Modbus TCP, а именно указание или неуказание адреса (номера) подчиненного устройства (сервера). В протоколе Modbus RTU все слейвы имеют свой уникальный адрес в сети. Мастер, формируя запрос, указывает адрес слейва, однобайтовое поле в заголовке пакета. Unit ID, Device ID, адрес неважно, как называется, смысл один. В протоколе Modbus TCP адресом абонентского устройства является его IP-адрес. Тем не менее, поле Device ID в заголовке сохранилось. И это часто вносит путаницу, непонимание и ошибки. Дело в том, что в соответствии со спецификациями обычный сервер Modbus TCP должен игнорировать поле ID в запросе к нему. Unit ID учитывается лишь для устройств, преобразующих Modbus RTU в Modbus TCP (гейты, шлюзы, конвертеры протоколов и так далее). На практике же многие сервера Modbus проверяют и однобайтовый адрес Unit ID. При несовпадении своего адреса и адреса в запросе, сервер в этом случае чаще всего не отправляют никакую ответную телеграмму, и клиент возвращает ошибку опроса. Если на практике вы столкнетесь с таким странным поведением, то откройте экземпляр функционалного блока клиента Modbus и поищите в его статических переменных байтовую величину MB_Unit_ID. Это и есть адрес подчиненного устройства, т.е. сервера Modbus. По умолчанию его значение равно 0xFF или 255. Нормальные сервера его игнорируют, достаточно уже самого факта установления соединения по протоколу TCP/IP. Если же попался ненормальный, то поставьте тут вручную Unit ID вашего устройства. Связь должна установиться.

Кроме того, в статических переменных есть ряд полезных настроек, таких, как таймауты, количество повторных попыток запроса и т.д. Изучить эти переменные можно во встроенной справке.

Закончив описание подводных камней, вернемя к изначальной задаче. Будем считывать с первого сервера 3 вещественных переменных (6 регистров), начиная с 40001, и записывать одну (начальный адрес 40011). Предполагаем, что порядок слов и байт правильный. Шесть регистров (шесть слов данных) и три вещественных переменных. Можно, конечно, просто в лоб читать информацию в локальный массив байт, а потом средствами дополнительной обработки представлять их в виде трех вещественных величин (тем же Deserialize, например), но не стоит создавать себе лишнюю работу. Гораздо удобнее будет сразу разложить читаемую информацию в собственную структуру. В блоке данных Data я создаю структуру, состоящую из трех полей типа REAL.

Обращаю внимание, что блок данных Data должен быть стандартным или неоптимизированным, в противном случае вы будете получать ошибку опроса, к примеру 818B.

Разумеется, содержание этой структуры полностью зависит от того, в каком порядке и в какой форме отдаются данные от сервера.

Программа обретает следующий вид, и данные успешно читаются.

0.5, 0.7, 0.33 (с) ВИА Несчастный случай

Теперь необходимо добавить еще один запрос на запись одной вещественной уставки (двух регистров). Необходимо понимать, что для обмена с одним сервером по одному соединению у нас выделен один экземпляр функционального программного блока коммуникаций. И если выполнять второй запрос, не дожидаясь результатов первого не будет работать ни один. Необходимо работать последовательно вначале выполнить один запрос, а после его завершения формировать следующий. Для этого достаточно добавить в наш программный блок переменную номер шага (или номер запроса, если вам так удобнее).

В итоге получаем вот такую программу.

Переменная, на основании который выбирается опрос, называется у меня Server1Query (будет еще Server2Query). Выбор запроса выполнется в операторе CASE. Номер запроса меняется на следующий лишь в случае успешного или неуспешего выполнения текущего опроса.

Для того, чтобы организовать опрос второго сервера, достаточно лишь подготовить хранилище для локальных переменных от сервера и к серверу и дописать существующую программу. Отличия в ней минимальные, тот же принцип, отличаются лишь все переменные (включая экземпляр функциональого блока MODBUS_CLIENT) и запрашивамые/записывемые данные.

Со вторым сервером у нас настроено отдельное соединение, есть отдельный экземпляр функционального блока modbus. Его мы можем вызывать одновременно с коммуникациями первого сервера, поэтому в общей программе есть два оператора CASE, которые работают независимо друг от друга.

В принципе, логичным будет добавить еще анализ ответа на конкретный запрос и формирование признака достоверности данных, и сделать некоторые другие доработки. Например оправлять команды и уставки не принудительно, а лишь по изменению.

Тем не менее, описание работы с протоколом Modbus TCP на этом я заканчиваю. В следующий раз посмотрим на программирование протокола Modbus RTU.

Подробнее..

Программирование Modbus RTU Master на примере Simatic S7-1200 и ПЧ Sinamics V20

08.01.2021 22:18:59 | Автор: admin

Давно хотел рассказать про тонкости программирования обмена по протоколу Modbus RTU в случае, когда контроллер (в нашем случае S7-1214) выступает RTU Master'ом. Недавно меня попросили помочь с обменом между ПЛК и частотным преобразователем Sinamics V20, ну и почему бы не написать заодно заметку, постаравшись приблизить решение задачи к боевым условиям.

Собственно говоря, сами немцы эту тему давно осветили:

SINAMICS V: Speed Control of a V20 with S7-1200 (TIA Portal) via USS protocol/MODBUS RTU with HMI

https://support.industry.siemens.com/cs/ru/ru/view/63696870/en

Смотрите этот пример, он сделан очень толково, с визуализацией,диалогами и квестамии возможностью расширить прикладную программу до опроса множества ПЧ V20 по нескольким интерфейсам (S7-1200 позволяет установить в свою корзину до 4 портов RS-485/422). Пример сделан очень хорошо и очень педантично. Вопросов коммуникаций по протоколу Modbus TCP я уже касался ранее, они есть на хабре.

Поэтому некоторые нюансы я повторно объяснять не буду, просто сразу напишу, как стоит делать правильно и удобно с моей точки зрения конкретно в случае опроса V20. Первоначальная настройка преобразователя частоты описана в документации, в том числе и в сопутствующей документации к вышеуказанному примеру. Вынесем лишь важные для нас пункты в качестве вводных.

Адрес подчиненного устройства модбас в сети: 1

Параметры связи: 9600 8-Even-1

Регистры хранения подчиненного устройства для чтения:

40110 ZSW Слово состояния

40111 HIW Текущая скорость

Регистры хранения для записи:

40100 STW Слово управления

40101 HSW Задание скорости

Параметр частотника Telegram off time (ms) P2014[0] рекомендую оставить по умолчанию, равным в 2000 мс (2 секунды), хоть пример и рекомендует снизить эту величину до 130 мс. Конкретно к протоколу Modbus это замечание не относится, разумеется, просто у меня при таймауте в 130 мс, ПЧ терял связь и выдавал ошибку Fault 72.

С частотником разобрались. Теперь о моей конфигурации ПЛК. Это S7-1214 с коммуникационным модулем 1241 под RS-485/422:

Среда программирования Step 7 V15.1 Update 4, версия прошивки CPU 4.3.

Итак, приступим. Для опроса подчиненных устройств с контроллера Simatic нам необходимо применить два функциональных блока: Modbus_Comm_Load (единовременно, только для конфигурации коммуникационного процессора) и Modbus_Master (циклически для чтения и/или записи регистров/катушек). Поэтому в программе экземпляр FB Modbus_Comm_Load у нас будет встречаться только один раз, а экземпляр Modbus_Master несколько раз, но с разными входными параметрами, в зависимости от адреса подчиненного устройства, типа читаемых данных и их количества, а так же направления передачи данных (чтение или запись). Обращаю ваше внимание, что для одного коммуникационного процессора (а их в системе может быть очень много) у вас не может быть больше одного экземпляра каждого блока данных.

С моей точки зрения весь обмен удобнее завернуть в один внешний функциональный блок, а сам блок, с учетом необходимости разбирать данные, реализовать на текстовом языке SCL. Поэтому создаем в проекте функциональный блок с именем ModbusMasterV20 на языке SCL. Сразу после создания открываем его свойства и снимаем настройку оптимизированный доступ, т.е. используем стандартный доступ. Личный опыт показал, что использование оптимизированного доступа рано или поздно приведет к ошибкам работы блока Modbus_Master и невозможности обмена. Это связано с порядком, в котором переменные идут в объявленной структуре данных, при стандартном доступе порядок соответствует заданному в программе, при оптимизированном система сама раскидывает переменные, как сочтет нужным.

Объявляем следующие входные переменные

Init (Bool) инициализация коммуникационного процессора, ее необходимо выполнить один раз перед началом обмена

PORT (PORT) аппаратный идентификтор коммуникационного процессора

BAUD (UDINT) скорость обмена по порту

STOP_BITS (USINT) количество стоповых бит кадра

PARITY (USINT) четность, где 0 нет четности, 1 odd, нечет, 2 even, чет

В статической области переменных так же прописываем переменную с именем Step и типом UInt, она отвечает за номер опроса или шаг работы алгоритма

Так же в статической области объявляем экземпляры ФБ для работы по протоколу Modbus RTU

Строки программы, отвечающие за инициализацию обмена.

По флагу инициализации выставляем номер шага 1. Следующие строчки очень важны для работы

#instModbusCommLoad.MODE := 4; //для линии RS-485 должна быть 4!

#instModbusCommLoad.STOPBITS := #STOP_BITS;

Тут мы задаем значения статических переменных экземпляра ФБ Modbus_Comm_Load, которые отвечают за физику передачи. Не понимаю, почему немцы поместили эти важные конфигурационные параметры в статическую область, а не в область входов. Дело в том, что они (переменные) все описаны во встроенной справке. Беда лишь в том, что большинстволенивых жопновичков до этого пункта справку не читает, а потом тратят несколько часов, а то и дней, пока не найдут ответ. А справка-то, вот она:

Переменная MODE отвечает за режим, в котором будет работать коммуникационный процессор. Как видно из справки, для RS-485 надо явно выставить 4. Значение по умолчанию 0, от этого большинство ошибок у программистов.

STOP_BITS количество стоповых бит.

Далее следует вызов блока настройки коммуникационного интерфейса Modbus_Comm_Load. Про параметр PORT (аппаратный идентификатор) будет рассказано чуть ниже. Параметры BAUD и PARITY скорость и четность приходят на вход внешнего блока данных, куда мы и завернули весь обмен. А вот параметр MB_DB интересен. На этот вход надо подать структуру типа P2P_MB_BASE, которая находится в области статических переменных экземпляра функционального блока Modbus_Master. Этот экземпляр в нашем большом функциональном блоке уже объявлен, привожу скриншот:

Следующая часть: функциональный блок приступает к циклическому обмену.

Я сразу заворачиваю обмен в CASE, чтобы не переписывать код в дальнейшем, но пока мы ограничимся чтением слова состояния и скорости ПЧ, т.е. прочитаем два регистра хранения.

Давайте посмотрим на вызов блока Modbus Master повнимательнее:

#instModbusMaster(REQ := TRUE,MB_ADDR := 1,MODE := 0,DATA_ADDR := 40110,DATA_LEN := 2,DATA_PTR := #ZSWHIW);

Входной параметр REQ включить опрос. Пока на входе TRUE, он выполняется, если FALSE не выполняется. Нет необходимости подавать положительный фронт на этот вход самостоятельно (в отличии от работы Modbus RTU в системах S7-300/S7-400), поэтому я просто даю TRUE константой

MB_ADDR адрес подчиненного устройства Modbus RTU. В моем случае адрес частотника = 1.

MODE направление передачи данных, 0 чтение, 1 запись

DATA_ADDR адрес интересуемых нас данных. В моем случае необходимо прочитать два регистра хранения (поэтому первая цифра4), начиная со 110го. В протоколе Modbus (что RTU, что TCP) очень часто возникает путаница в понятиях адрес и номер. И очень часто производитель оборудования эту путаницу добавляет в свою систему. Вот смотрите. Мы должны прочитать 2 регистра, начиная с адреса 40110. Для чтения регистров хранения в протоколе Modbus используется функция с номером 3. Именно 3 будет передаваться в телеграмме Modbus. А в качестве адреса в телеграмме будет передаваться не 40110, а 109. Связано это с тем, что код функции уже содержит описание области данных. А в самой телеграмме мы передаем не адрес, а номер требуемого регистра или катушки. И эта нумерация идет не с единицы, а с нуля. Сейчас я работаю именно с адресами и режимом (чтении или запись), поэтому мне достаточно указать то, что я нашел в документации. Если же в вашем устройстве будет указано входной регистр номер 0 содержит текущий статус устройства, то вам на вход DATA_ADDR необходимо будет подать 30001. Так же имейте в виду, что из-за частой путаницы с номерами и адресами, иногда эта адресация съезжает на единицу, поэтому не бойтесь экспериментировать. Если вместо полезных данных по запросу 16ого регистра вам прилетает полная чехарда, не имеющая ничего общего с документацией, прочитайте 15ый регистр. Не помогло? Опрашивайте 17ый. Более подробно с материалом необходимо ознакомиться опять же во встроенной справке.

DATA_LEN количество читаемых регистров, их 2

DATA_PTR указатель на область памяти, куда необходимо положить результат чтения регистров. Собственно, это те данные, которые мы прочитали и необходимо подсказать функциональному блоку, куда эти данные надо записать. С моей точки зрения самый удобный способ в этом случае это объявить в области STAT неименованную структуру должного размера. Поля структуры мы объявляем, в зависимости от самих читаемых данных, ведь это могут быть и наборы бит, и вещественные числа (расположенные в двух соседних регистрах). И нам еще повезет, если порядок байт в слове и слов в двойных словах контроллера и подчиненного устройства совпадут, иначе нам еще потребуется осуществить сдвиги байт/слов.

В данном случае я счел уместным объявить структуру из двух слов и скормить ее на вход FB:

, где

ZSW слово состояния (так оно называется в документации на ПЧ)

HIW скорость вращения двигателя

После вызова блока мастера, необходимо проанализировать успех или неуспех его выполнения. В принципе, на этом скриншоте в комментариях уже все написано:

В случае успешного чтения необходимо полученные сырые данные как-то разобрать или переложить в другую область, и перейти к следующему опросу (у нас пока только один опрос, так что мы остаемся на шаге 1). При ошибке чтения данных минимальный разумный ход выставить где-нибудь флаг недостоверности и перейти к другому опросу.

Пока оставляем прием данных без обработки, компилируем и грузим программу, смотрим на результат. Кстати, обращаю еще внимание на один факт. Поскольку мы работаем, завернув системные вызовы в свой функциональный блок, то любое изменение своего ФБ с последующей загрузкой ПЛК, будет нарушать обмен в связи с переинициализацией экземпляра нашего ФБ. Например, будет уходить в ноль значение шага обмена. Да и внутренние статические переменные коммуникационных вызовов тоже пострадают. Самый простой способ стоп и старт контроллера. В боевом проекте это опасно, поэтому там на вход Init я бы подал еще одну переменную и поднимал ее самостоятельно после изменений в коммуникациях. Пока же боремся с остановом обмена простым стоп-стартом ПЛК.

Добавляем вызов нашего функционального блока в OB1 и грузим CPU

Переменная FirstScan имеет значение истина при первом цикле выполнения программы OB. Она назначается операционной системой ПЛК автоматически, ее применение настраивается в свойствах CPU.

Port. Это значение смотрим в проекте Step 7, аппаратная конфигурация:

Остальные параметры касаются скорости, четности и количества стоповых бит. Загружаем контроллер и смотрим, что нам приходит в ответ на единственный циклический запрос, открыв экземпляр нашего ФБ

В слове состояния что-то есть, скорость равна нулю. Открываем документацию и смотрим состав слова состояния ZSW:

Low enabled в примечаниях означает инверсию. К примеру, бит 15, перегрузка частотника, возникает, когда этот бит равен 0, а в нормальном состоянии приходит значение 1. Посмотрим на это слово состояния в watch table и посмотрим, какие его биты выставлены, а какие нет, оценим общее состояние ПЧ:

Тут нам везет, порядок байт в словах совпадают. Если вкратце, то видно, что ПЧ не готов, не включен, и сейчас активен сигнал аварии (fault, бит 3).

Далее я попытался разложить слово состояния в биты состояния, заменив WORD на структуру из бит, но что-то явно пошло не так.

Если посмотреть внимательно, то в таком представлении нулевой и первый байты явно не на своих местах. В общем, вопрос порядка следования информации в зависимости от того или иного представления он всегда важный и требует вдумчивости. Получил на этом этапе облом, я решаю вернуться к хранению внутри нашего ФБ только сырых данных, а удобочитаемый для человека формат представления информации перенести куда-нибудь во внешний глобальный блок. Добавляю в проект блок данных DataV20:

После чего задумываюсь, убираю из имен переменных окончание Inv и дописываю функциональный блок:

Теперь в глобалном блоке данных у нас находятся статусные биты преобразователя частоты без какой-либо инверсии:

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

Пока не будем пересчитывать коды в физические величины и перейдем к следующему шагу к записи слова управления и задания частоты. Вернемся к обработке текущей скорости чуть позже.

Обратимся к документации и посмотрим состав слова управления частотным преобразователем:

Знаете, мне, откровенно говоря, лень писать все эти переменные в глобальном интерфейсном блоке данных. В моей практике управление простыми технологическими процессами с применением преобразователей частоты ограничивалось командами включить, квитировать аварию и дать задание скорости. Поэтому, пойдем на поводу моей лени и в блоке данных V20Data пропишем всего лишь бит включить, бит квитировать и задание частоты в формате Real.

Изменю алгоритм на шаге 1, при успешном или неуспешном завершении опроса сделаю переход на шаг 2.

Добавим еще локальную структуру ФБ, которая содержит слово управления и слово задания скорости:

Дорабатываю программу обмена. Не забываем, что при изменении переменных функционального блока, после загрузки изменений в ПЛК происходит его переинициализация, посему надо выполнять стоп/старт CPU.

Параметры функционального блока модбас в данном случае отличаются от первого вызова. Разумеется, у нас тут другой адрес регистра. А так же отличается режим (MODE), он равен 1, так как в данном случае данные не читаются с частотника, а записываются в него. Разумеется, указатель на область данных так же другой.

Обратите внимание, что некоторые биты слова управления я принудительно выставляю в истину, другие в ложь. Всего два бита управления (включить и квитировать) доступны для внешней программы. Необходимое значение бит управления я вычитал в документации примера. Разумеется, это указано и в документации на сам преобразователь частоты. Изучая исходный пример, я обратил внимание, что если частотнику отдавать пустое (все биты выставлены в ноль) слово управления, то это подчиненное устройство модбас возвращает ошибку Invalid data. Однако, в этом примере я пробовал слать полностью пустое слово управления, и V20 принимал его. Однако, некоторые биты управления, все равно, должны быть установлены. К примеру, если снять бит Control by PLC, то запускаться ПЧ не будет. RTFM, как говорится!

Теперь пора перейти к регистру, который отвечает за задание скорости (ну и сразу же к регистру, который отображает текущую скорость). Из исходного примера я понял, что этот регистр меняет свое значение в пределах от 0 до 16384. Это же мельком нашел и в документации. Пока не будем делать никаких переводов величин, и зададим ПЧ максимальную скорость жестко прямо в программном коде.

Откроем наш блок данных DataV20 и выставим команду пуск:

V20 запустился и работает, судя по индикации своего экранчика, на максимальной скорости, т.е. на 50 Гц. Давайте посмотрим еще сырые данные его скорости, которые приходит по modbus.

Значит, пришло время доработать шаг 1 обмена (перевести коды скорости в герцы), ну и шаг 2 в части обратного преобразования, герцы в численное значение задания скорости. Математика самая простая, без проверок на достоверность и выход за диапазон, хотя все это не помешает.

После загрузки изменений откроем блок данных DataV20 и поуправляем частотником из него.

Даем задание 25 Гц, даем пуск и наблюдаем за появлением сигнала Running и текущей скоростью.

Все регистры, которые можно считать с V20, описаны в документе по ссылке

https://support.industry.siemens.com/cs/attachments/109768394/V20opinstr0419en-US.pdf?download=true

Судя по описанию регистров, есть и другие способы управления, но нас сейчас интересует не это. В моей практике с пребразователей частоты еще частенько просили считать ток(и), напряжение(я), мощность, детализацию ошибок и т.д. Давайте последуем этой старой-доброй традиции и считаем дополнительно вот эти параметры, а так же переведем их в понятное представление:

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

В принципе, мотор маленький, крутится без нагрузки, поэтому значения похожи на достоверные. Тем не менее, задача стоит в демонстрации считывания данных, поэтому будем считать наличие хоть каких-либо цифры за огромный технологический прорыв. Итак, вы уже заметили, что я добавил читаемые параметры в блок данных DataV20. Дополнительно был доработан функциональный блок коммуникаций:

Читаются (mode = 0) четыре регистра хранения по адресу 40025. Результат помещается во внутренний статический массив [0..4] of WORD. Далее эти слова переводятся в формат Real и помещаются во внешний блок данных в результате несложных преобразований.

Ну, и напоследок остается проанализировать качество связи. Ведь не зря же на каждом шаге после выполнения ФБ Modbus_Master смотрю его флаги DONE или Error (кстати, эти флаги имеют значение истина только на протяжении одного вызова после успешного или неуспешного выполнения запросы, в остальное время ложь). Для этого я объявил массив из булевых переменных

Массив размерностью три, по количеству запросов Modbus. Соответственно, если на шине будет 10 частотников, по три запроса к каждому, то размерность этого массива, как и количество шагов алгоритма, будет равно 30. Ну, и в конце каждого опроса, при анализе флагов, наконец, прописываем присвоение флагам значения.

Будем считать, что частотник стабильно обменивается информацией с ПЛК, когда все три запроса к нему выполнены успешно. Поэтому самая последняя строчка нашего функционального блока будет такой (предварительно добавим булевую переменную Connected в блоке данных DataV20):

Подробнее..

О несомненной пользе применения современного оборудования Simatic

20.01.2021 12:12:03 | Автор: admin

Году эдак в 2011 я на правах фрилансера написал и внедрил ПО для управления водонапорной станцией. По итогам система получилась распределенной и даже немного сложной, но начиналось все с локальной станции управления одной насосной установкой.

Проектная организация заложила CPU Simatic S7-313C. Аппаратный релиз был еще с 64 килобайтами рабочей памяти, тогда как актуальные сегодня версии оборудованы аж 128 килобайтами. Контроллер управлял двумя задвижками с приводами Auma Matic AM01.1 по профибасу и, по профибасу же, частотным преобразователем Robicon (модель не помню, здоровенная хреновина как минимум в мегаватт полезной мощности).

То есть, тут у нас технологически несложная насосная установка - задвижка на напоре, задвижка на всасе, датчики давления, насос, обвязанный датчиками вибрации и температуры, вакуумный выключатель для частотника, лампочки/кнопочки на шкафу, панель оператора.

Неожиданно мне стало интересно, как это будет выглядеть на новой линейке Simatic? Влезет ли прикладная программа, легко ли она портируется? Сколько стоит решение - внедренное ранее и выбранное мной сейчас?

С моей точки зрения такую несложную систему надо сегодня делать на S7-1200, поэтому она и была выбрана в качестве целевой системы.

Портировать прикладную программу оказалось несложно. Повозиться пришлось лишь в нескольких местах. Во-первых, в классическом Step 7 (версии 5.5 SP4) провел замену оборудования до актуальных заказных номеров. Это Step 7 знает всё своё железо с момента выхода в свет. TIA Portal ограничен более-менее актуальными релизами. А мигрировать прикладное ПО со старого Степа на новый решил полностью, включая аппаратную конфигурацию.

Второй источник боли - это прикладная программа в части вставок кода на языке STL. Дело в том, что S7-1200 не поддержкивает STL от слова вообще. А я его применял. Для копирования переменных, для несложных рассчетов и т.д. Ну, на не LADe же городить ветки с блоком MOVE. К слову, исходная программа написана на языке LAD с этими самыми вставками на STL.

В конечном итоге это превратилось в программу на языке LAD с нетворками на языке SCL.

Третье затруднение - это системные вызовы для обмена ЛСУ с вышестоящим мастер-контроллером, как профинет-подчиненнное устройство. В S7-300 через CP 343-1 LEAN для этого применялись отдельные функции. Тут я не стал заморачиваться и внедрил обмен через область процесса. Удобнее. А для контроля качества связи в обоих направлениях соорудил счетчик. В общем, никаких системных функций.

Работа с профибас-подчиненными устройствами осталась такой же. То есть, через функции DPRD_DAT и DPWR_DAT. В принципе, ничего не мешало использовать ту же область процесса. Только вот как контролировать качество связи - я при таком подходе не придумал. Поэтому оставил, как было.

Ну, а теперь немного картинок. И, конечно же, про деньги.

Так выглядит исходная (и внедренная) конфигурацияТак выглядит исходная (и внедренная) конфигурация

Большинство дискретных сигналов управления влазило на блок CPU, но, все равно, не хватало, поэтому проектировщики добавили модули DI16 и DO16. DI16 и DO16 оказалось слишком много. По хорошему эти два модуля можно спокойно заменить на комбинированный DIO8/8. На аналоговых модулях AI8 висят сигналы давления и обвязка насоса.

Новая сборка на базе S7-1214Новая сборка на базе S7-1214

Все сигналы управления влезли вот в такой вариант. S7-1214 это минимальной возможный подходящий CPU. И его хватает с запасом. С учетом того, что технологическое оборудование работает по шине Profibus, пришлось доставлять отдельно CM1243-5, а это значительно удорожает спецификацию. Увы, но без него никак, ибо я мигрирую систему управления, но не всю технологию.

Пришло время посмотреть, что получилось с прикладной программой.

Исходный вариант:

Итого, примерно 24 килобайта рабочей памяти и 35 килобайт загрузочной.

Портированный на S7-1200 вариант:

14 килобайт рабочей памяти. Почти в два раза меньше. Частично это достигается отказом от функций PNIOSEND, PNIOECV. Частично некоторой оптимизацией кода. Не смог я просто скопировать наработки семилетней давности, ряд вещей переработал. Напоминаю, что сейчас сравниваются программы с абсолютно идентичным функционалом. И в новой линейке для того же функционала требуется меньше памяти. Удивительно, я ожидал обратного.

А теперь, конечно же, про деньги.

Стоимость исходной конфигурацииСтоимость исходной конфигурации

Обратите внимание, что тут я для оптимизации заменил два дискретных модуля DI16 и DO16 на один комбинированный DI/DO 8/8. А так же выбрал карту памяти MMC на 64 кБ в целях удешевления системы (разумный подход к делу требует, чтобы объем загрузочной памяти, т.н. флешки, был больше рабочей памяти). Округляя, получаем стоимость 3400 ойро без НДС.

Интересно, а что же получилось на S7-1200?

Стомость новой конфигурацииСтомость новой конфигурации

Даже с учетом применения дорогого модуля Profibus DP Master, даже с учетом применения дин-рейки за 30 евро, сборка получилась почти в два раза дешевле, 1630 евро. При том же функционале.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru