Структура записи адреса Modbus. Присваивание глобальным переменным Modbus-адреса ================================================================================ Для обмена контроллера данными с подчиненными modbus-устройствами, необходимо создать запрос определенного типа к нужным регистрам памяти modbus-устройств и объявить в проекте глобальные переменные, связанные с соответствующими адресами этих регистров. В данном уроке разберем все нюансы присваивания для разных подмодулей Modbus. Адрес глобальной переменной присваивается внесением записи в поле "Location". Структура записи выглядит следующим образом: **%[Форма] [Размер] [Идентификатор] . [Номер]** .. csv-table:: **Форма регистра** :header: "Тип формы", "Описание" :widths: 3, 10 "Q", "Глобальная переменная используется для записи Reg/Coil slave–устройства (WriteSingleСoil, WriteSingleRegister, WriteMultipleCoils, WriteMultipleRegisters)" "I", "Глобальная переменная используется для чтения Reg/Coil slave–устройства (ReadCoils, ReadInputDiscretes, ReadHoldingRegisters, ReadInputRegisters)" "M", "Глобальная переменная используется для записи и чтения" .. csv-table:: **Размер переменной** :header: "Размер", "Количество байтов", "Тип данных" :widths: 3, 3, 10 "D", "4", "DINT, REAL, UDINT, DWORD" "L", "8", "LINT, ULINT, LREAL, LWORD" "B", "1", "BYTE, USINT, SINT" "X", "1", "BOOL" "W", "2", "WORD, INT, UINT" .. csv-table:: **Идентификатор элемента** :header: "Структура", "Предназначение" :widths: 3, 40 "X.X.X", "Для ModbusRequest" "X.X", "Для MemoryArea" "X", "Для остальных, не входящих в модуль расширения" **Номер регистра** выставляется согласно номеру в выборке ModbusRequest, при этом номер первого регистра равен 0. Если пока ничего не понятно, то не стоит переживать, сейчас мы на примерах узнаем подробнее. Допустим, есть slave–устройство, подключенное к порту RS-485_1 и нам необходимо прочитать состояние регистра с типом данных UINT по адресу 6032 и 6015. Modbus-адрес устройства - 5. Скорость передачи данных - 9600, 8-n-1. Добавим подмодуль ModbusRTUMaster. .. note:: Более подробно о подмодуле ModbusRTUMaster можно узнать в :ref:`Подмодуль ModbusRTUMaster. Добавление и конфигурирование ModbusRequest.` .. figure:: img/13.png :width: 600 :align: center Выбираем нужный нам порт - RS_485_1, скорость передачи данных и тип 8-n-1. Далее добавляем ModbusRequest для настройки конкретного slave–устройства. Создадим запрос типа «Read Holding Registers» к нашему modbus-устройству, имеющему modbus-адрес 5 (Slave_Modbus_Adress:5). Начальный адрес пула регистров Start_Address сделаем равным: 6000. Так как регистр с адресом 6032 имеет размер W (используется 2 байта для хранения данных типа UINT, т.е. одна ячейка), то Regs_number запишем как 33. Таким образом, задействуются регистры с 6000 по 6032 включительно. .. figure:: img/14.png :width: 600 :align: center Далее напишем программу на языке FBD. Добавим глобальные переменные *read_mdb1* и *read_mdb2* с типом данных UINT. .. figure:: img/15.png :width: 600 :align: center Далее переходим во вкладку с глобальными переменными проекта. Пропишем Modbus-адреса для наших переменных. .. figure:: img/gif9.gif :align: center :width: 600 Как видно, мы задали адрес по структуре, указанной выше: * Прописываем "%" * Прописываем форму регистра для чтения ReadHoldingRegisters - "I" * Прописываем размер переменной - "W" в соответствии с типом данных UINT * Для ModbusRequest структура имеет вид "X.X.X" - "1.0.0.X" * Прописываем номера необходимых регистров 32 и 15. .. tip:: Если в проекте несколько ModbusRequest, необходимо прописать нужный субмодуль, проверяя в дереве проекта Имеется еще один вариант прописывания адреса. Для этого нажимаем на три точки в "Location" и далее выбираем наши нужные регистры. .. figure:: img/gif10.gif :align: center :width: 600 В данном случае мы сами выбираем адрес из нужного подмодуля. Также не забываем указать правильный номер регистра. .. attention:: После ввода Modbus-адреса через три точки в "Location" обычно ИСР Beremiz по умолчанию меняет тип данных на WORD Рассмотрим другой пример. Допустим, у нас есть несколько переменных, которые необходимо прочитать другому устройству. В данном случае наш контроллер будет выполнять функции slave–устройства. Итак, пусть переменными у нас будут *LocalVar0 - LocalVar3* с типами данных *WORD*, *REAL*, *LWORD* и *BOOL*. Напишем простую программу, которая будет фиктивной. .. figure:: img/16.png :width: 600 :align: center Остальные переменные добавим в *Config variables*. .. figure:: img/17.png :width: 600 :align: center Следующим шагом мы добавим подмодуль MemoryArea. Зададим область адресов с 6000 с количеством регистров - 10. Тип MemoryArea выберем 03 - HoldingRegisters. .. note:: Более подробно о подмодуле ModbusRTUMaster можно узнать в :ref:`Добавление и конфигурирование подмодуля MemoryArea` .. figure:: img/18.png :width: 600 :align: center Остался последний шаг - корректно прописать адреса. С помощью таблицы структуры мы запишем сначала для *LocalVar0*: * Прописываем "%" * Прописываем форму регистра - "M" * Прописываем размер переменной - "W" в соответствии с типом данных WORD * Для MemoryArea структура имеет вид X.X - "1.0" * Прописываем номер, пусть *LocalVar0* будет первым - "1.0.0" .. figure:: img/19.png :width: 600 :align: center Итоговый вариант глобальных пременных выглядит так: .. figure:: img/20.png :width: 600 :align: center Возникает вопрос: почему *LocalVar2* прописан с адресом %ML1.0.3, а не %ML1.0.2? Потому что тип данных REAL имеет количество битов 4, значит занимает 2 ячейки. Аналогично с этим и прописан адрес для *LocalVar3* - количество битов для типа данных LWORD - 8. Готово, компиллируем и загружем программу, и теперь мастер-устройство может опросить, менять данные переменные обратишись к конроллеру по Modbus-адресу - 3(по умолчанию) со скоростью - 115200 к регистрам с адресами от 6000.