Сети‎ > ‎

Modbus/TCP(рус)

6.4. MODBUS TCP / IP

6.4.1. Коммуникационная архитектура MODBUS TCP/IP

    Сеть MODBUS TCP/IP базируется на стеке протоколов TCP/IP и прежде всего предназначена для работы на базе сетей Ethernet. MODBUS TCP/IP описан в спецификациях MODBUS-IDA, в которых коммуникационная система MODBUS TCP/IP может включать различные типы устройств (рис.6.26):
- MODBUS TCP/IP Клиенты и Серверы, подключенные к TCP/IP сети;
- межсетевые устройства типа мостов, маршрутизаторов или шлюзов для соединения TCP/IP сети с последовательными линиями подсетей, что позволяет обмениваться данными з MODBUS Serial серверными устройствами.
Таким образом коммуникационная система MODBUS TCP/IP позволяет обмениваться устройствам не только на сетях со стеком TCP/IP, а также с устройствами на последовательных линиях связи (MODBUS RTU/ASCII или MODBUS+). Как пример можно привести рис.6.27, взятый из спецификации протокола прикладного уровня.

6.4.2. Особенности реализации протокола

Аналогично другим сетям MODBUS, данная сеть использует MODBUS Application Protocol. Напомним, что в MODBUS Serial на канальном уровне к PDU добавляется адрес Ведомого и контрольная сумма, сам PDU не модифицируется. Однако в MODBUS TCP/IP перед попаданием на транспортный уровень, к PDU (который состоит из кода функции и данных) добавляется дополнительный MBAP-заголовок. (Рис.6.28). Заголовок состоит из полей, которые описаны в табл.6.6. Полученный модуль передается уровню TCP.

Обратите внимание, что с помощью поля UnitID можно указать адрес узла в MODBUS Serial, например адрес ведомого в MODBUS RTU. Если нужно адресовать узел, непосредственно подключенный по TCP/IP то UnitID = 0.

    Поле ProtocolID используется для межсистемного мультиплексирования. Так TCP порт для MODBUS Сервера имеет номер 502, однако этот же порт, например, использует Schneider Electric для UNITE-Сервера. Таким образом, заменив поле ProtocolID, Ethernet модули ПЛК Schneider Electric одновременно поддерживают два протокола: MODBUS и UNI-TE.

Таблица 6.6

Поля MBAP заголовка

Поле

Длина (байт)

Пояснение

Клиент

Сервер

TransactionID

2

идентификация транзакций запросов/ответов

инициализирует Клиент в запросе

копирует из запроса в сообщение-ответ

ProtocolID

2

тип протокола, 0=MODBUS протокол

инициализирует Клиент в запросе

копирует из запроса в сообщение-ответ

Length

2

количество следующих байт

инициализирует Клиент в запросе

инициализирует Сервер в ответе

UnitID

1

адрес Ведомого, который подключен к узлу

инициализирует Клиент в запросе

копирует из запроса в сообщение-ответ

Для идентификации устройства, которому передается запрос, указывается его IP адрес. Для идентификации TPDU, направляемых MODBUS-Серверу, как прикладному объекту, выделен 502-й TCP-порт. С деталями функционирования стека TCP/IP а также Ethernet можно ознакомиться в литературе по компьютерным сетям а также в главе 10. Кроме того там приведены некоторые пояснения по поводу ограничений использования решений подобных MODBUS TCP/IP, в частности в системах с жесткими требованиями к реальному времени.
  

Пример 6.7 MODBUS. Реализация MODBUS TCP/IP Клиентской программы для связи VIPA Speed7 с удаленными модулями ввода/вывода VIPA IM 253NET.

Задание. Написать прикладную программу в среде Step7 для реализации периодического (1 раз в 500 мс) считывания значений 4-х аналоговых входов в ПЛК Vipa Speed7NET с удаленных модулей ввода/вывода на базе VIPA IM 253NET (рис 6.29).

Решение. Данный пример будет рассмотрен с максимальными упрощениями и без детализации вещей, не касающихся данной темы. Учитывая, что для программирования Vipa можно использовать другой  программный продукт (WinPLC7), детали создания конфигурации для Step7 будут опущены. Стоит также отметить, что Siemens предлагает свой коммуникационный функциональный блок, как для реализации Клиента так и Сервера  MODBUS TCP/IP, но в данном примере используются стандартные функции AG_SEND и AG_RECV.

По рис.6.29 видно, что 4-ре 12-битных входа будут считываться как 4 слова. Но так как они находятся на первом посадочном месте, AI0 – будет адресоваться как 0-вой входной регистр, а AI3 – как 3-тий.

Таким образом, задачу можно сформировать так: написать прикладную программу в ПЛК Vipa Speed7NET (IP=192.168.0.1) для реализации считывания 4-х входных регистров из MODBUS TCP/IP Сервера с адресом IP=192.168.0.2. При такой постановке уже не важна конкретика реализации удаленного устройства.

Для полноты картины построим схему сетевых соединений (рис. 6.30). Стоит отметить, что у Vipa S7NET среди 2-х портов Ethernet X8 и X5 только один порт, а конкретно Х8 (ТР), может использоваться для разных типов соединений, аналогичных СР343 от Сименс. Другой порт (Х5) может использоваться только для PG/OP соединений. Таким образом, для соединения данного ПЛК по MODBUS TCP/IP необходимо использовать разъем Х8 (ТР).

Для реализации обмена по протоколу ТСР в S7-подобных контроллерах конфигурируют соединительные каналы (Connections). Для каждого канала указывают:

- локальный процессор, для которого конфигурируется канал;

- точку выхода в сеть, то есть коммуникационный модуль;

- идентификатор соединения;

- активность соединения, то есть, инициирует ли данный узел соединение;

- коммуникационного партнера, с которым настраивается соединение (IP и TCP port);

- локальный ТСР port для соединения.

В принципе, используя соединительные каналы, можно обмениваться поверх ТСР по любому открытому протоколу.  Поэтому MODBUS TCP/IP  - один из множества вариантов использования данного типа коммуникаций Siemens. Так, например, в Step5 совместная связь также конфигурируется подобным образом, но порты ТСР будут другими и протокол прикладного уровня также другой.

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

- канал создается на стороне процессора Vipa S7NET;

- точка выхода в сеть (маршрутизатор) – выбираем порт ТР (виртуальный модуль СР343), после чего в конфигураторе получаем адрес данного модуля соответственно его размещению в корзине (=14016);

- тип канала =ТСР;

- идентификатор соединительного канала выбирается произвольно, например 3;

- соединение активное с этой стороны, чем указываем, что данный узел в соединении представляет сторону клиента ТСР;

- указываем IP- адрес коммуникационного партнера, то есть IP=192.168.0.2;

- указываем ТСР port для партнера, ТСР=502 (MODBUS сервер);

- указываем локальный, то есть клиентский ТСР port, выбираем произвольно в возможном диапазоне, например  ТСР=2001;

После такой конфигурации, даже без написания дополнительной программы, между ПЛК и модулем удаленного ввода/вывода создается ТСР соединение. Но никакими данными пользователя узлы обмениваться не будут.

Для передачи данных от ПЛК Vipa S7NET необходимо использовать коммуникационную функцию AG_SEND, которая поставляется с библиотеками для Vipa. Эта функция отправляет блок данных по созданному соединительному каналу. Одним из аргументов этой функции является указатель на блок данных, которые необходимо отправить. В нашем случае это по сути MODBUS TCP/IP ADU. Наиболее удобный способ описать в Step7 подобную структуру и выделить под нее память  - это использование блоков данных типа DB. Таким образом, формируем DB10 для создания MODBUS TCP/IP ADU, согласно таблице 6.7 и синтаксиса функции чтения входных регистров (см.п.6.2.2). Результат формирования блока DB10 в Step7 показан на рисунке 6.31.

 
 

Первые два поля при инициализации блока приравниваются к нулю. Поле TransactionID можно использовать для отслеживания последовательности ответов на запросы (какой TransactionID в запросе, такой и в ответе), но это не обязательно. ProtocolID=0, так как используется сервер MODBUS.

Количество следующих байт зависит от функции, в нашем случае их 6. Адрес Ведомого=0, так как адресат находится непосредственно на Ethernet. Функция=4, поскольку необходимо считать входные регистры, начальный адрес=0, а количество=4(см.рис.6.29).

Указатель на сформированный блок данных указывается в аргументах функции AG_SEND. Часть программы, которая отвечает за отправку запросов, будет иметь вид как на рисунке 6.32. Программа написана в организационном блоке OB1 (циклический вызов).

В Network1 каждые 500 мс перезапускается таймер и генерируется одиночный импульс М100.0 длительностью в один цикл. Этот импульс используется для отправки данных в сеть (параметр АСТ) раз в 500 мс. С этой же периодичностью в Network2 увеличивается значение 0-го слова в блоке данных DB10 (DB10.DBW0),  которое указывает на идентификатор транзакции. Кроме непосредственно указателя на блок с данными для отправки длиной 12 байт (параметр SEND), в функции указывается идентификатор соединительного канала (параметр ID=3), адрес коммуникационного модуля (LADDR=14016), и количество байт для отправки. Контроль отправки и вызова функции проводится при помощи параметров DONE (бит выполнения операции), ERROR (бит наличия ошибки) и STATUS (слово статуса операции), о использовании которых можно прочитать в справочной литературе.

После начала выполнения программы процессор ПЛК будет записывать указанные в DB10 данные во входной буфер коммуникационного модуля с адресом LADDR=14016, которые отправятся этим модулем по соединительному каналу ТСР с идентификатором 3. Интерфейсный модуль распределенной системы ввода/вывода VIPA IM 253NET, получив по соединительному каналу данные MODBUS TCP/IP ADU, сформирует сообщение-ответ и отправит его по этому же каналу. Это сообщение попадает во входной буфер коммуникационного модуля. Для того, чтобы прочитать эти данные из входного буфера, используется функция AG_RECV.

    В свойствах одного из параметров функции AG_RECV существует указатель на данные, в которые необходимо поместить результат функции, то есть данные входного буфера. Аналогично предшествующей части программы, лучше всего использовать блок данных, например DB11.Значение инициализации полей данного блока не играет никакой роли, поскольку он заполняется значениями буфера. Однако желательно задать структуру блока, которая и показана на рисунке 6.33.
 
 
 
 Другая часть программы, в которой реализовано получение необходимых значений аналоговых входов, показана на рисунке 6.34.
 
 

В случае положительного результата выполнения функции и получения новых данных (NDR=0 и ERROR=0) записываем значения в переменные MW200-MW206, соответственно заданию.

Следует отметить, что данный пример значительно упрощенный,  кроме того, в нем не учитываются случаи возникновения коммуникационных ошибок. Однако он показывает каким образом используется клиентская сторона MODBUS TCP/IP в Siemens-совместимых ПЛК. Аналогично можно прописать и серверную сторону MODBUS TCP/IP, но это более сложная задача.

Пример 6.8. MODBUS. Реализация MODBUS TCP / IP Клиентской программы для связи приложений с интегрированным VBA и ПЛК.

Задание. Написать приложение в среде VBA (Excel) для реализации считывания значения 5-ти внутренних регистров с ПЛК по MODBUS TCP/IP. Считывание проводить при нажатия кнопки.

Решение. В VBA прописываем следующий код, показанный на рис. 6.35.
Для реализации данной задачи использован ActiveX-элемент Winsock (
имя экземпляра Winsock1), который обычно уже присутствует на компьютерах с операционной системой Windows. Этот компонент является интерфейсом к одноименному сервису в Windows и функционирует примерно так же как и модель сокетов (см. раздел 10). Он может работать как в режиме TCP так и UDP. Для последнего - соединение проводить не нужно. Достаточно разместить Winsock элемент на контейнере (например форме) и можно пользоваться его методами, свойствами и событиями.

------------------------------------------------------------------------

Dim Reg(1 To 10) As Integer ' тут сохраняем значение переменных

Private Sub CloseSocket()

    Winsock1.Close           'закончить соединение

End Sub

 

Private Sub ConnectSocket()              'соединяемся с MODBUS Сервером

    Winsock1.Protocol = sckTCPProtocol   'выбираем протокол ТСР

    Winsock1.Connect "192.168.9.17", 502 'вказываем ІР и 502 порт

End Sub

 

Private Sub CommandButton3_Click()

    ReadRegisters 0, 5                    'читаем 5 регистров начиная с 0

End Sub

 

Sub ReadRegisters(StartAddr As Integer, CountAddr As Integer)

    Dim a(1 To 12) As Byte                 'посылка в байтах

    If Winsock1.State = sckConnected Then 'если соединены

        a(6) = 6                          'количество байт

        a(8) = 3                         'функция

        a(9) = StartAddr \ 256            ’начальный № - старший байт

        a(10) = StartAddr Mod 256         'начальный № - младший байт

        a(11) = CountAddr \ 256           оличество – старший байт

        a(12) = CountAddr Mod 256         оличество – младший байт

        Winsock1.SendData a               'отправить масив байт

    End If

End Sub

 

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) 'получили данные

 Dim a As Variant, LoInd As Integer, i As Integer, j As Integer

 Winsock1.GetData a, , bytesTotal          'извлечь данные с буфера

 LoInd = LBound(a)                         'определить начальн. индекс массива

 If a(7 + LoInd) = 3 Then 'если это функция чтения и она обработана без ошибок

    For i = 1 To a(8 + LoInd) \ 2         'перебираем каждый регистр

        j = 9 + (i - 1) * 2               'номер байта в массиве для регістра і

        If (a(j) And &H80) > 0 Then      'если число отрицательн(старший бит=1)

            a(j) = a(j) And &H7F          'обнулить старший бит

            Reg(i) = a(j) * 256 + a(j + 1) - 32768

'считать с учетом згнака

        Else

            Reg(i) = a(j) * 256 + a(j + 1) 'считать без знака

        End If

    Next

 End If

End Sub

  

Private Sub UserForm_Initialize()
    ConnectSocket
End Sub

----------------------------------------------------------------------
 
 
Оставить комментарии Вы можете здесь http://pupena-san.blogspot.com
Comments