Программирование Modbus RTU Master на примере Simatic S7-1200 и ПЧ Sinamics V20

  • Tutorial

Давно хотел рассказать про тонкости программирования обмена по протоколу 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

Смотрите этот пример, он сделан очень толково, с визуализацией, диалогами и квестами и возможностью расширить прикладную программу до опроса множества ПЧ 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, описаны в документе по ссылке.

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

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

В принципе, мотор маленький, крутится без нагрузки, поэтому значения похожи на достоверные. Тем не менее, задача стоит в демонстрации считывания данных, поэтому будем считать наличие хоть каких-либо «цифры» за огромный технологический прорыв. Итак, вы уже заметили, что я добавил читаемые параметры в блок данных DataV20. Дополнительно был доработан функциональный блок коммуникаций:

Читаются (mode = 0) четыре регистра хранения по адресу 40025. Результат помещается во внутренний статический массив [0..4] of WORD. Далее эти слова переводятся в формат Real и помещаются во внешний блок данных в результате несложных преобразований.

Ну, и напоследок остается проанализировать качество связи. Ведь не зря же на каждом шаге после выполнения ФБ Modbus_Master смотрю его флаги DONE или Error (кстати, эти флаги имеют значение «истина» только на протяжении одного вызова после успешного или неуспешного выполнения запросы, в остальное время — ложь). Для этого я объявил массив из булевых переменных

Массив размерностью три, по количеству запросов Modbus. Соответственно, если на шине будет 10 частотников, по три запроса к каждому, то размерность этого массива, как и количество «шагов» алгоритма, будет равно 30. Ну, и в конце каждого опроса, при анализе флагов, наконец, прописываем присвоение флагам значения.

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

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 40

    0
    Спасибо что поделились. Существует ли к этим контроллерам какая-либо бесплатная среда для их программирования? Валяется один такой без дела, 21-дневный триал давно кончился, платная версия стоит судя по всему недешево.
      0
      Версия Step 7 Basic для программирования контроллеров серии S7-1200 распространяется в РФ безвозмездно, т.е. даром. Свяжитесь с представительством компании Сименс в Вашем регионе.
        0
        От представителя физ.лицо не получит должного ответа.
        Все, кто работает с Siemens, прекрасно знают о существовании ключей для разработчиков. Они не ограничивают функционал и без ограничения по времени, единственное — их нельзя оставить заказчику. А для личного использования самое то.
        P.S. Sim_EKB_Install_2018_11_14
          0

          На самом деле достаточно счёта на покупку ПЛК, по нему лицензию высылают.

            0
            О, если не секрет? От какой компании получали ключ? Миг, форум, симекс, ЭТМ?

            Каталог указывает на цену в 336 евро
            STEP 7 Basic V16 6ES7 822-0AA06-0YA5
              0

              Если мне вопрос, то ключ я прошу в самом Сименс, раньше у них Разгоева этим занималась, теперь вроде кто-то другой.


              Недавно с итальянцами проект запускали, так они спокойно ekb ставят.

                0
                Нет ничего криминального в ekb.
                Сам Сименс ставит их на ПК заказчику, а по окончанию ПНР передают запечатанную коробку с ключом.
                Все понимают что заказчик лицензию оплатил, и не обязательно использовать на АРМ именно купленный ключ. И автоматически уходят проблемы с восстановлением лицензии при выходе из строя АРМ.
                  0
                  Анна Разгоева теперь стала Анной Чистяковой, а в целом ситуация не изменилась )
                  0
                  Пишите/звоните в ближайшее местном бюро Сименс
          +2

          Из моего опыта отслеживать Done и Error недостаточно, они могут и не появиться. Использую ещё таймер по таймауту.

            0
            Кажется, в документации что-то было про то, что по таймауту error взводится или я путаю?
              0
              Не всегда…
              Самое надежное анализировать количество принятых байт или анализ «Живого слова». Например секунд системного времени устройства.
            0
            Я, конечно, извиняюсь, но программирование микроконтроллеров и программирование ПЛК — это немного разные вещи.
              0
              Прошу простить, исправлюсь.
                +1
                Просто и Вы поймите — я слежу за хабом «Программирование микроконтроллеров» потому что мне интересны именно микроконтроллеры, а не ПЛК :)
                  +1
                  Я прекрасно понял Ваше недоумение и осознаю свою ошибку.
                  Никаких обид не испытываю, Ваше замечание более чем справедливое )
                    0
                    Спасибо за понимание :)
              0
              Спасибо, интересно читать ваши статьи, понятно, доходчиво и развернёто.
              Я в своё время делал этот обмен на LAD, было больновато)) У вас конечно, на SCL поизящней будет.

              Как я вижу — у вас идёт циклическое чтение\запись независимо от условий.
              И я вроде, тоже так делал. Однако, в случае, если выходами слейвов может управлять кто-то ещё (например, модуль реле у WirenBoard может переключать выходы от своих входов, а может «рулиться» по модбас — задача управления светом).
              Соответственно, нужно делать некий кроссчек на проверку, была ли переменная изменена, чтобы не было такого, что слейв пишет на выход «0», а мы туда статически пишем «1». В ПЧ и т.д. обычно используют режим local\remote либо как здесь некий ControlFromPLC бит, как подтверждение «легитимности» записи.
              В-общем, за счёт того, что Modbus в Siemens прописывается «руками» о циклической записи нужно помнить, я так понимю.
              Или в дебрях руководства к драйверу что-нибудь написано про то, что если с последней записи данных значения не изменились то в интерфейс новые значения подаваться не будут? В любом случае, это не отменяет необходимость чтения выходов слейва и только потом записи (если пришел реквест на запись).

              Пока оставляем прием данных без обработки, компилируем и грузим программу, смотрим на результат. Кстати, обращаю еще внимание на один факт. Поскольку мы работаем, завернув системные вызовы в свой функциональный блок, то любое изменение «своего» ФБ с последующей загрузкой ПЛК, будет нарушать обмен в связи с переинициализацией экземпляра нашего ФБ. Например, будет уходить в ноль значение «шага обмена». Да и внутренние статические переменные коммуникационных вызовов тоже пострадают. Самый простой способ — стоп и старт контроллера. В боевом проекте это опасно, поэтому там на вход Init я бы подал еще одну переменную и поднимал ее самостоятельно после изменений в коммуникациях. Пока же боремся с остановом обмена простым стоп-стартом ПЛК.


              Можно ещё раз другими словами?.. Я немного не понял… ПЛК грузится в RUN «онлайн» без стопа? соответственно, модбас драйвер уже инициализирован и новые значения при их прогрузке не подхватывает, так? Напомните, S7-1200 может грузиться онлайн или через стоп?
              А блок инициализации можно вызывать принудительно? Не хотелось бы, условно говоря останавливать процесс ради переинициализации обмена данными.

              ЗЫ. Планирую поставить какой-нибудь 1200й в качестве главного ПЛК для умного дома.
                0
                Соответственно, нужно делать некий кроссчек на проверку, была ли переменная изменена, чтобы не было такого, что слейв пишет на выход «0», а мы туда статически пишем «1». В ПЧ и т.д. обычно используют режим local\remote либо как здесь некий ControlFromPLC бит, как подтверждение «легитимности» записи.
                В-общем, за счёт того, что Modbus в Siemens прописывается «руками» о циклической записи нужно помнить, я так понимю.


                Речь не о Модбас в Сименс, речь про Модбас вообще. И даже не только про Модбас. Любое устройство, если оно спроектировано с умом, будет выбирать источник получения команд, «место управления». В случае частотно-регулируемых приводов, как правило, это реализуется выбором управления с локальной панели, с дискретных/аналоговых входов или по интерфейсу, неважно какому. Опять же, как правило, если ПЧ управляется от ПЛК по интерфейсу, то это его штатный режим работы, выбрано место управления, выставлены соответствующие разрешения.

                Можно ещё раз другими словами?.. Я немного не понял… ПЛК грузится в RUN «онлайн» без стопа? соответственно, модбас драйвер уже инициализирован и новые значения при их прогрузке не подхватывает, так? Напомните, S7-1200 может грузиться онлайн или через стоп?


                ПО ПЛК серии Simatic возможно загружать без останова CPU, это его нормальная работа.
                Речь в данном случае идет про то, что в моем примере применяется т.н. мультиэкземпляр функционального блока, где внутри одного ФБ завернуты другие экземпляры ФБ, в частости — отвечающие за коммуникацию. Если на лету изменить интерфейс «внешнего» ФБ, то загрузка по умолчанию будет выполнена с переинициализацией всех его переменных, включая коммуникационные ФБ. Если в это время идет обмен, то такое финт является грубым вмешательством в коммуникации, и обмен попросту останавливается от такого пинка. Это неправильно.

                Рестарт контроллера — это самый простой, но самый тупой способ устранить последствия такого наглого вмешательства.

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

                Приведенный мной пример не является боевым проектом, но может послужить базой для его разработки.
                  0
                  Если на лету изменить интерфейс «внешнего» ФБ,

                  Что значит «интерфейс» внешнего ФБ?.. Изменение его структуры, добавление новых данных и т.д.?
                  Можно ли как-то автоматически отслеживать, что произошла загрузка\изменение ФБ и запуск инициализации коммуникации «с начала»?.. Либо даже не с начала а с последнего шага…
                  Может ли в таком случае быть потерян какой-то управляющий сигнал на запись?.. (если мы использовали что-то в стиле one shot в шаге 3, а пере-инициализация началась на шаге 1 и мы «потеряли» команду управления?) В-общем, похоже нужно быть внимательным… Может быть, можно и автоматически останавливать коммуникацию?..
                    0
                    Что значит «интерфейс» внешнего ФБ?.. Изменение его структуры, добавление новых данных и т.д.?


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

                    Можно ли как-то автоматически отслеживать, что произошла загрузка\изменение ФБ и запуск инициализации коммуникации «с начала»?.. Либо даже не с начала а с последнего шага…


                    Возможно. Тут можно завести отдельную статическую переменную, вроде аналога «FirstScan», которая при инициализации будет держать значение «истина». Внутри блока при поднятии этой переменной надо будет проводить инит. Тут надо вдумчвиво смотреть и пробовать, описанное выше является предположением.

                    Может ли в таком случае быть потерян какой-то управляющий сигнал на запись?.. (если мы использовали что-то в стиле one shot в шаге 3, а пере-инициализация началась на шаге 1 и мы «потеряли» команду управления?) В-общем, похоже нужно быть внимательным… Может быть, можно и автоматически останавливать коммуникацию?..


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

                    В общем, как я уже сказал, это не боевой проект.
                    Самое простое, что тут можно сделать — это не заворачивать коммуникационные ФБ модбаса в мультиэкземпляр, а объявить их в виде глобальных экземплярных блоков данных. Тогда ситуация на площадке сильно упростится.
                      0
                      Хотелось бы понять а зачем… «заворачивать» ФБ модбаса в мультиэкземпляр как таковой… Это хорошая практика? В примерах Сименс похожий подход?.. Не должна как по мне, падать программа при изменении формата хранения данных…
                      Там скорее всего… я не знаю как сказать — драйвер модбаса обращается к «жестко» прописанным адресам в ДБ, и если ДБ «сместить» (добавить новую переменную выше по течению) драйвер модбаса наверное, «сходит с ума»?.. хотелось бы поподробнее понять механизм, что там происходит и почему… По всей видимости, нужен какой-то online memory rebuild или типа того, чтобы после изменения олнайн программа продолжала «жить»…
                      Возможно, в справке по online change про это что-нибудь рассказано, но я с сименсом давно уже не работал…
              0
              «— Они тоже из тиа программируются? — Нет, ещё из степа».
              Непривычно видеть название STEP7 для среды программирования S7-1200/1500. Обычно её называют TIA Portal, а STEP7 остаётся для старого доброго SIMATIC Manager S7-300/400.
                +1
                А сам продукт там и называется — Step 7'
                Уточняется либо номером версии (v16, например) или примеяанием, что он портальный
                Например:
                mall.industry.siemens.com/mall/en/ru/Catalog/Products/10317037?tree=CatalogTree
                  0
                  Надо бросать что-то писать с планшета, буквы мелкие, я вначале по ним не попадаю, а потому не вижу кучу опечатак… (

                  Вот что должно было быть написано:
                  А сам продукт так и называется — Step 7.
                  Уточняется либо номером версии (v16, например) или примечанием, что он портальный: Step 7 (TIA Portal).
                  Например:
                  mall.industry.siemens.com/mall/en/ru/Catalog/Products/10317037?tree=CatalogTree
                0
                1. Также хотелось бы понять механизм появления данных, считанных по Модбас — в какой момент и как они появляются?.. Скажем, классический сценарий работы ЦПУ — считываем входы, делаем программу — записываем выходы.
                Где в этом цикле будет находиться перемещине данных из буфера коммуникационного модуля в область ДБ?.. Нужно ли это учитывать при написании программы? Могут ли данные появиться в середине цикла программы и может ли это повлиять на работоспособность?
                Насколько я могу судить, считываемые данные могут появиться в любой момент времени (мы не знаем, через сколько ответит слейв или если есть на линии отваленные устройства то к циклу опроса добавится задержка). Не знаю, важно ли это или нет.

                2. Я всё со своей записью в регистры «по изменению» в релеынй модуль WirenBoard.
                Как писал выше — кейс: управлять лампочками через релейный модуль «в параллель» с входными сигналами. Релейный модуль меняет состояние выходных каналов по фронту входных сигналов, а также может менять состояние (R/W) выходных каналов через modbus.

                Остаётся продумать механизм записи. Похоже, он просто выглядит из, как минимум, 2х циклов: чтение выходов (скажем, слово из 8 бит, по биту на выход), проверки слова на запись, если слово на запись != считанному слову -> посылка слова на запись, непосредственно запись в слейв.

                Также для повышения быстродействия, по всей видимости (если опрашиваем ХХ устройств) на отклик — можно предусмотреть «прерывания» — если слова на запись != считанным словам, то изменить шаг с условного 1(считывание первого устройства) на 10 — (запись в 1 устройство).
                Но опять же, придётся учитывать, что остальная запись пройдет скорее всего, «в холостую», т… е в остальные слейвы будут записаны те же данные, что там и были(для простоты программы).

                3. Эмулятор под S7-1200/1500 позволит протестировать Modbus TCP?.. Лет 9 назад вроде не умел, согласно документации…

                4.0 Если использовать Modbus TCP, сколько коннектов можно поднять на S7-1200?.. У него вроде было до 8 коннектов, вот я не знаю — туда входят коннекты Модбаса? Вопрос в том ключе, что как работает драйвер ModbusTСP с несколькими слейвами — если делать опрос «по шагам» — то понятно, что как «поллинг».
                А что если использовать несколько экземпляров ModbusTСP драйвера, каждый со своим коннекшеном, могу ли я тем самым повысить быстродействие?
                4.1 Такой финт ушами для MB_MASTER (несколько экземпляров) в режиме ModbusRTU Over TCP всё равно не пройдет, ведь я понимаю, один экземлпяр на один коммуникационный модуль?
                4.2 Что если я поставлю на каждый конвертер TCP-RTU и буду поднимать отдельный MB_MASTER RTU over TCP на каждый конвертер — в теории это же должно повысить быстродействие (см 4.0)?.. Мало того, можно использовать топологию «звезда».
                Скажем, в условиях домашнего применения можно было бы HVAC повесить на один шлейф, а управление светом — на другой и вместо RS485 модуля купить 2 преобразователя TCP-RTU.
                Вопрос целесообразности пока не сильно затрагиваю, хотелось бы понять больше принцип работы.
                  0
                  Коллега, у Вас очень много вопросов на общие темы.
                  Так я все пальцы сотру )
                  Напишите мне в приват, я могу позвонить Вам и дать ответы в общем.
                    0
                    На вопрос 4.0 отвечает вот эта полезная схемка:
                    support.industry.siemens.com/cs/us/en/view/38051505
                    0
                    Далее я попытался разложить слово состояния в биты состояния, заменив WORD на структуру из бит, но что-то явно пошло не так.

                    В PLC Siemens для типов больших одного байта используется формат big-endian(от старшего к младшему, см. Endianness).
                    Поэтому и "перепутались" байты.

                      0
                      Каждый раз, видя статьи на Хабре о том, как следовать F1 в TIA Portal меня сжигает испанский стыд… От комментариев и вовсе опускаются руки… Может тоже свои дрова как статьи выложить? Хотя бы за рамки хелпа выберусь… И самое грустное — такие статьи не спасут от имён блоков/переменных на русском языке в пять-семь слов или любителей весь код впихнуть в OB1…
                        0
                        Коллега, Вы не поверите, но
                        1. Являясь технической поддержкой Сименс на Урале, я постоянно сталкиваюсь с вопросами про модбас и s7-связь. Несмотря на то, что мануала вполне достаточно. Все мои публикации написаны, в том числе, с корыстной целью упростить себе жизнь.
                        2. Выкладывайте, конечно. Будет полезно и познавательно, особенно новичкам, которые вряд ли даже понимают, что значит «количество байт далее» в пакете modbus tcp
                          0
                          Конечно, выкладывайте, интересно ж!
                          0
                          Скажу честно, заглянул найти для себя что-то интересное. С siemens не работаю.
                          Из прочитанного сделал следующий вывод — реализовать даже кастомного (есть встроенный) мастера на ПЛК Овен (среда Codesys 2.3) значительно проще. Про ПЛК фирмы Koyo вообще и говорить нечего.

                          Зачем они так усложняют? Я не говорю, что это сложно. Но требует явно больше времени на реализацию.
                            0
                            Коллега, я не стремлюсь вдаваться в дискуссию и поэтому позволю себе только один вопрос.
                            Реализовать на овене проще или привычнее? Это разные вещи.
                              0
                              И в Овне и в Koyo есть конструктор — просто и быстро можно подключить кучу девайсов, проставить признаки обновления (по времени, по изменению тд).
                              Если же стандартный конструктор не устраивает, на помощь приходит Modbus_lib. Здесь уже реализация напоминает ваш случай. Просто в реализации на Codesys на мой взгляд библиотека очевиднее. Открыть порт все так же. Вот последующие запросы немного иначе. Вы используете DATA_ADDR с указанием области. В моем же случае у меня полный набор ФБ в виде read_holding, write_coil, write_multiple и так далее. Понятно, что можно таковые создать и у вас в проекте.
                              Лично я ждал от топ ПЛК какого-то богатого набора инструментов из коробки. Изумившись отсутствием и был написан первый коммент.

                              А в заключение, оговорюсь по поводу проще — кому-то и на жигулях с механикой «проще», чем на автомате мерса. Это вкусовщина. Я не совсем корректно выразил мысль в первом сообщении.

                              И еще одна ремарка, я не люблю Овен. Я просто вынужден с ним работать.
                                0
                                Я вспомнил, о чем Вы говорили, коллега

                                Справедливости ради замечу, что безусловное удобство работы с модбасом является заслугой компании 3S software, являющейся автором среды codesys третьей версии, где и программируется ряд ПЛК фирмы Овен. Некоторые же модели ПЛК, например, плк63 и плк73 программируются в кодесис версии 2, и опрос по модбас превращается в тьму и ужас )

                                Но в третьей версии — красота.
                                  +1

                                  Вынужден вас поправить. Третью версию codesys поддерживает 1 или 2 ПЛК овен узкой специализации ( совершенно не подходят для стандартных проектов). Вся основная линейка (включая новый 110м2 на котором мы сидим ) дружит только с версией 2.3. Удивительно, ПЛК новый, а среда старая. Имея опыт знакомства с TIA 15 версии, скажу так — codesys 2.3 это как Delphi 6 версии. При этом имеется удобнейший конструктор для modbus. Хотя, не глядя на modbus, я всегда завидовал тем кто работает на TIA. Довелось поработать неделю в свежей версии. Это как иномарка после Жигулей.

                                    0
                                    Странно, очень странно.

                                    Поработав как-то с ПЛК110 (вроде бы) в кодесис 3, был абсолютно уверен, что таргеты под новые ПЛК будут исключительно для 3ей версии.

                                    За исключением мутности с версией таргета и версией библиотек, и с учетом стоимости, решение, в принципе, удовлетворительное. Не знаю, правда, то ли эта тенденция у них, то ли мне так «везло», но цепи в 24 Вольта у них дохнут, как мухи в полдень.
                            0
                            Хочется проконсультироваться) Автору спасибо, ибо появилось хоть общее представление как работать с модбасом в сименсе. Сейчас ситуация такова: плк S7-1200 (6ES7215-1HG40-0XB0), панель TP700 (6AV2124-0GC01-0AX0) и 4 тензомодуля (7MH4960-2AA01). Предполагалось подключить все модули к контроллеру на шину, но в итоге узнаю что модули должны быть установлены удаленно от контроллера ближе к датчикам тензометрии (метров 30). Знаю что можно панель непосредственно подключить через Модбас (у моей Profinet (( ). Теперь задумка поставить на контроллер модуль RS-485 (6ES7 241-1CH32-0XB0) и организовать чтение/запись в тензомодули. Я понимаю что это получится много запросов, плюс как то необходимо калибровать сами модули с панели ( вообщем жопа(( ). Посоветуйте как проще выбраться из этой ситуации и вообще получится сделать так, как я хочу?

                            Only users with full accounts can post comments. Log in, please.