Modbus tcp своими руками

Arduino & Modbus

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

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

Что нам необходимо знать об этом стандарте?
Протокол Modbus использует последовательные линии связи (например, RS232, RS485), а протокол Modbus TCP рассчитан на передачу данных по сетям TCP/IP.
Протокол Modbus имеет два режима передачи RTU и ASCII, в режиме ASCII каждый байт передается как два ASCII символа его шестнадцатеричного представления.
В сети Modbus есть только один ведущий, который с заданным интервалом опрашивает несколько ведомых устройств, каждое из которых имеет свой уникальный адрес от 1 до 254, адрес 0 широковещательный и на него отвечают все устройства, так как ведущий в сети один у него нет своего адреса.
В спецификации Modbus определено два типа данных, один бит и 16 битное слово. Данные организованны в четыре таблицы с 16 битной адресацией ячеек, адресация в таблицах начинается с 0. Для доступа к данным из разных таблиц предназначены отдельные команды.

Discrete Inputs 1 бит только чтение
Coils 1 бит чтение и запись
Input Registers 16 бит только чтение
Holding Registers 16 бит чтение и запись

Как нам подключить Modbus устройство к OpenHAB? За это отвечает модуль Modbus Tcp Binding, этот модуль работает в режиме ведущего и обеспечивает подключение нескольких ведомых устройств через последовательный порт или TCP/IP сеть.
Для того чтобы связать с ним Arduino нам необходимо реализовать в контроллере ведомое Modbus устройство, воспользуемся для этого библиотекой Modbus-Master-Slave-for-Arduino.

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

Рассмотрим на примере нашего скетча основные шаги необходимые для работы с этой библиотекой.

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

Затем определить массив регистров Modbus

После этого, при старте программы настроить последовательный порт ведомого

В основном цикле программы необходимо вызывать функцию обработки Modbus сообщений

И после этого можно обработать полученные данные и сохранить необходимые переменные в регистрах Modbus.

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

Для демонстрации работы с разными регистрами, в процессе работы программы данные из регистра с типом coil будут скопированы в регистр с типом discrete, а из регистров с типом holding в регистры с типом input. Кроме этого состояние кнопки будет сохранено в третий бит регистра au16data[0] (discrete), а значение третьего бита регистра au16data[1] (coil) выведено на светодиод.

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

Пора приступать к испытаниям. Значительно облегчает работу на этом этапе эмулятор Modbus мастер-устройства, в сети есть несколько хороших, при этом бесплатных программ, вот некоторые из них:
www.focus-sw.com/fieldtalk/modpoll.html
qmodbus.sourceforge.net
www.mikont.com/products/EAT-Console.html

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

Для установки эмулятора нужно скачать архив и распаковать его в папку C:\arduino\EATConsole, затем открыть страницу загрузки Eclipse, скачать Eclipse IDE for Java Developers и распаковать его в папку C:\arduino\eclipse, после этого скопировать файлы из папки C:\arduino\EATConsole\eclipse\plugins в папку C:\arduino\eclipse\plugins.

Для создания конфигурации необходимо запустить C:\arduino\eclipse\eclipse.exe, создать пустой проект, скопировать в него пустой файл C:\arduino\EATConsole\menu.ptmenu и добавить в редакторе пункты в соответствии со следующей таблицей. Если же вы скачали проект из репозитория, то в нём, в папке EATConsole уже есть подготовленный файл menu.ptmenu.

Читайте также:  Как сделать железного гаража своими руками
Type Address Bit Name Point Slave
Display Boolean 0 0 DT0 1
Display Boolean 0 1 DT1 1
Display Boolean 0 2 DT2 1
Display Boolean 0 3 BTN 1
Input Boolean 1 0 CL16 1
Input Boolean 1 1 CL17 1
Input Boolean 1 2 CL18 1
Input Boolean 1 3 LED 1
Display Integer 2 INPT3 0 1
Display Integer 3 INPT4 0 1
Display Integer 4 INPT5 0 1
Display Integer 5 HOLD6 0 1
Display Integer 6 HOLD7 0 1
Display Integer 7 HOLD8 0 1

Type — тип элемента меню EATConsole.
Address — адрес регистра данных.
Bit – номер бита в регистре.
Name – название элемента меню.
Point – количество десятичных знаков после точки.
Slave – Modbus адрес контроллера.

Теперь сохраним и скопируем файл menu.ptmenu в каталог C:\arduino\EATConsole, для этого можно щёлкнуть правой кнопкой мыши на файле прямо в Eclipse, выбрать в контекстном меню пункт “Copy”, а затем вставить в проводнике в папку C:\arduino\EATConsole.

После этого запустим C:\arduino\EATConsole\EATConsole.exe, настроим последовательное соединение, выбрав пункт меню Файл\Настройки, в диалоговом окне укажем номер порта, скорость 9600, 8 бит данных, 1 стоповый бит.

*Программа работает с портами с 1 по 8 и если USB переходник Arduino встал на порт с большим номером, придётся открыть диспетчер устройств Windows и изменить номер порта для него.

Когда все настройки будут введены, нажмите кнопку “Установить”, сразу после этого программа начнёт опрос устройства и если что-то пошло не так появится сообщение – НЕТ СВЯЗИ. Если же всё было сделано правильно и связь есть в чём можно убедиться по миганию индикатора статуса (светодиод на выводе 13), то пора приступить к испытаниям нашего контроллера.

Попробуем поменять значение в регистрах HLD0…HLD2 и СL0…СL2, при этом должно поменяться значение в соответствующем регистре IN0..IN2 и DT0..DT2, затем нажмём на кнопку макета, при этом должно поменяться значение в поле BTN, щёлкнем по полю LED, при этом должен загореться или потухнуть светодиод.

Что мы получили в результате нашей работы:

1 познакомились с азами протокола Modbus;
2 создали скетч, который превращает Arduino в Modbus slave устройство и позволяет читать и записывать несколько Modbus регистров с разными типами данных;
3 протестировали обмен с контроллером при помощи эмулятора функций Modbus master устройства, для которого создали конфигурацию соответствующую структуре регистров контроллера.

Выводы
Библиотека Modbus-Master-Slave-for-Arduino проста в использовании, позволяет создать ведомое Modbus устройство, которое корректно работает с программным эмулятором. Скомпилированный пример занимает немногим более 5кб памяти программ, так что в контроллере остаётся достаточно места для добавления необходимого функционала.

Стандарт Modbus открыт и популярен, но в нём есть ряд недостатков — в стандарте определено только два типа данных,
протокол требует постоянного обмена между ведущим и ведомыми устройствами, конфигурировать систему приходится вручную.

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

В следующий раз займёмся подключением контроллера к платформе OpenHAB.

Источник

Последовательная связь по протоколу Modbus RS-485 с Arduino (ведомой)

Протокол Modbus – самый распространенный промышленный протокол для межмашинного (M2M) взаимодействия. Является стандартом де-факто и поддерживается почти всеми производителями промышленного оборудования. В этой статье мы рассмотрим последовательную связь по протоколу Modbus RS-485 используя плату Arduino Uno в качестве ведомого устройства (Slave).

Что такое Modbus

Modbus — протокол, работающий по принципу «клиент-сервер». Широко применяется в промышленности для межмашинного взаимодействия и не только. Протокол Modbus был разработан в 1979 году. Modbus может использоваться для передачи данных через последовательные линии связи RS-485, RS-422, RS-232, а также через сети TCP/IP. В данной статье мы рассмотрим его использование на примере линии RS-485. Достаточно подробно протокол Modbus описан в соответствующей статье Википедии. Также неплохое описание протокола Modbus есть в этом документе (уже не помню откуда его скачал но его автору отдельное спасибо).

Modbus RS-485 использует линию последовательной связи RS-485 для передачи данных. Modbus является программным (не аппаратным) протоколом и состоит из двух частей: Modbus Master (ведущий) и Modbus Slave (ведомый). В сети Modbus RS-485 может быть один ведущий и 127 ведомых устройств, каждое из которых имеет уникальный адрес от 1 до 127. Master адреса не имеет — он в сети может быть только один.

Modbus чаще всего используется в программируемых логических контроллерах (PLCs — Programmable Logic Controllers). Но также он широко применяется в медицине, транспорте, проектах автоматизации дома и т.п. Modbus имеет 255 функциональных кодов. Наиболее распространены 3 версии данного протокола:

Какая разница между протоколами Modbus ASCII и Modbus RTU? По сути, это практически одинаковые протоколы. Только в протоколе Modbus RTU данные передаются последовательно в двоичном коде, а в Modbus ASCII – в ASCII кодах. В этом проекте мы будем использовать Modbus RTU. Структура пакета в проколе Modbus RTU выглядит следующим образом:

Назначение элементов данного пакета рассмотрено далее в статье.

В данной статье мы будем использовать последовательную связь по протоколу Modbus RS-485 используя плату Arduino Uno в качестве ведомого устройства (Slave). Мы установим программное обеспечение Simply Modbus Master Software на компьютер и будем управлять двумя светодиодами и сервомотором, подключенными к ведомой плате Arduino. Управлять ими мы будем при помощи передачи специальных значений от Master Modbus Software.

Читайте также:  Жидкое мыло для бритья своими руками

Принципы работы интерфейса последовательной связи RS-485

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

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

В нашем случае дифференциальный сигнал образуется при помощи использования положительного и отрицательного напряжения 5V. Интерфейс RS-485 обеспечивает полудуплексную связь (Half-Duplex) при использовании 2-х линий (проводов) и полноценную дуплексную связь (Full-Duplex) при использовании 4-х линий (проводов).

Основные особенности данного интерфейса:

  1. Максимальная скорость передачи данных в интерфейсе RS-485 – 30 Мбит/с.
  2. Максимальная дистанция связи – 1200 метров, что значительно больше чем в интерфейсе RS-232.
  3. Основным достоинством интерфейса RS-485 по сравнению с RS-232 является использование нескольких ведомых (multiple slave) при одном ведущем (single master) в то время как RS-232 поддерживает только одного ведомого.
  4. Максимальное число устройств, которое можно подключить по интерфейсу RS-485 – 32.
  5. Также к достоинствам интерфейса RS-485 относится хорошая помехоустойчивость вследствие использования дифференциального сигнала.
  6. RS-485 обеспечивает более высокую скорость передачи по сравнению с интерфейсом I2C.

Использование интерфейса RS-485 в Arduino

Для использования интерфейса RS-485 в плате Arduino мы будем использовать модуль 5V MAX485 TTL to RS485, в основе которого лежит микросхема Maxim MAX485. Модуль является двунаправленным и обеспечивает последовательную связь на расстояние до 1200 метров. В полудуплексном режиме он обеспечивает скорость передачи данных 2,5 Мбит/с.

Модуль 5V MAX485 TTL to RS485 использует питающее напряжение 5V и логический уровень напряжения также 5V, что позволяет без проблем подключать его к платам Arduino.

Данный модуль имеет следующие особенности:

  • работает с напряжениями 5V;
  • имеет в своем составе чип MAX485;
  • отличается низким энергопотреблением;
  • всеми его контактами можно управлять с помощью микроконтроллера;
  • размеры платы модуля: 44 x 14mm.

Внешний вид модуля RS-485 показан на следующем рисунке.

Назначение контактов (распиновка) модуля RS-485 приведена в следующей таблице.

Название контакта Назначение контакта
VCC 5V
A вход/выход линии RS-485
B вход/выход линии RS-485
GND GND (0V)
R0 выход приемника (RX pin)
RE разрешение работы приемника
DE разрешение работы передатчика
DI вход передатчика (TX pin)

Как видите, контакты на модуле RS-485 расположены очень логично — с одной стороны к модулю подключается устройство, а с другой — линия.

Модуль преобразования USB в RS-485

На представленном рисунке показан внешний вид адаптера (модуля преобразования) USB в RS-485. Он способен работать в различных операционных системах и обеспечивает интерфейс RS-485 при помощи использования одного из COM портов компьютера. Этот модуль является устройством plug-and-play. Все, что передается через виртуальный COM порт, автоматически преобразуется данным модулем в RS-485, и наоборот. Модуль питается от порта USB – никакого дополнительного питания не требуется.

В компьютере он виден как последовательный/ COM порт и доступен для использования различными приложениями. Модуль обеспечивает полудуплексную связь с помощью интерфейса RS-485. Скорость передачи – от 75 до 115200 бод/с, максимальная – до 6 Мбит/с.

В сети интернет можно найти достаточно много программного обеспечения, способного работать с данным адаптером. Мы в этом проекте будем использовать программу Simply Modbus Master.

Программное обеспечение Modbus Master

Программу Modbus Master Software мы будем использовать для передачи данных ведомой плате Arduino с помощью интерфейса RS-485.

Вы можете скачать программу Simply Modbus Master по следующей ссылке. Документацию по этой программе (на английском языке) можно прочитать здесь.

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

Slave ID (идентификатор/адрес ведомого)

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

Регистры Modbus

Регистры флагов (Coils) хранят однобитные значения — то есть могут находится в состоянии 0 или 1. Такие регистры могут обозначать текущее состояние выхода (включено реле). Название «coil» буквально и означает обмотку-актюатор электромеханического реле. Регистры флагов допускают как чтение, так и запись. Имеют номера от 1 до 9999.

Дискретные входы (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например, подано напряжение — 1). Эти регистры поддерживают только чтение. Имеют номера от 10001 до 19999.

Регистры ввода (Input Registers) – 16-битные регистры, используемые для ввода информации. Эти регистры поддерживают только чтение. Имеют номера от 30001 до 39999.

Читайте также:  Барельеф с деревьями своими руками

Регистры хранения (Holding Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 — 0xFFFF). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). Имеют номера от 40001 до 49999.

Function code (код функции/функциональный код)

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

Таблица Тип элемента Тип доступа
Дискретные входы (Discrete Inputs) один бит только чтение
Регистры флагов (Coils) один бит чтение и запись
Регистры ввода (Input Registers) 16-битное слово только чтение
Регистры хранения (Holding Registers) 16-битное слово чтение и запись

В реальной практике чаще всего встречаются устройства, в которых есть только таблица Holding Registers, иногда объединённая с таблицей Input Registers.

Для доступа к этим таблицам существует ряд стандартный функций ModBus:

Чтение:

  • 1 (0x01) — чтение значений из нескольких регистров флагов (Read Coil Status).
  • 2 (0x02) — чтение значений из нескольких дискретных входов (Read Discrete Inputs).
  • 3 (0x03) — чтение значений из нескольких регистров хранения (Read Holding Registers).
  • 4 (0x04) — чтение значений из нескольких регистров ввода (Read Input Registers).

Запись одного значения:

  • 5 (0x05) — запись значения одного флага (Force Single Coil).
  • 6 (0x06) — запись значения в один регистр хранения (Preset Single Register).

Запись нескольких значений:

15 (0x0F) — запись значений в несколько регистров флагов (Force Multiple Coils)
16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)

Наиболее часто используемые на практике функции (функциональные коды) ModBus это 3, 6 и 16 («Read Holding Registers», «Preset Single Register» и «Preset Multiple Registers» — соответственно).

В этой статье описана реализация команды 0x10 — запись значений в несколько регистров хранения, работа с командами 0x03 и 0x04 , наиболее часто используемыми для считывания информации с датчиков по протоколу ModBus, описана в данной статье (написать такую статью очень просили посетители нашего сайта).

CRC расшифровывается как Cyclic Redundancy check и переводится как “циклический избыточный код”. Это два байта, которые добавляются к каждому передаваемому сообщению протокола Modbus для обнаружения ошибок.

Необходимые компоненты

Аппаратное обеспечение

  1. Плата Arduino Uno (купить на AliExpress).
  2. MAX485 TTL to RS485 Converter Module (модуль преобразования логики TTL в RS485) ( купить на AliExpress).
  3. USB to RS-485 Converter Module (преобразователь USB в RS-485) ( купить на AliExpress).
  4. Светодиод – 2 шт. (купить на AliExpress).
  5. Резистор 1 кОм – 2 шт. (купить на AliExpress).
  6. ЖК дисплей 16х2 (купить на AliExpress).
  7. Потенциометр 10 кОм (купить на AliExpress).
  8. Сервомотор SG-90 (купить на AliExpress).

Программное обеспечение

Схема проекта

Схема для последовательной связи по протоколу Modbus RS-485 с платой Arduino представлена на следующем рисунке.

В следующей таблице представлены необходимые соединения между платой Arduino Uno (ведомой) и модулем MAX485 TTL to RS485.

Arduino Uno Модуль MAX485 TTL to RS485
0(RX) RO
1(TX) DI
4 DE & RE
+5V VCC
GND GND

В следующей таблице представлены необходимые соединения между модулями MAX485 TTL to RS485 и USB to RS-485.

MAX485 TTL to RS485 USB to RS-485
A A
B B

В следующей таблице представлены необходимые соединения между платой Arduino Uno и ЖК дисплеем 16х2.

ЖК дисплей 16х2 Плата Arduino Uno
VSS GND
VDD +5V
V0 к потенциометру для управления яркостью/контрастностью дисплея
RS 8
RW GND
E 9
D4 10
D5 11
D6 12
D7 13
A +5V
K GND

В следующей таблице представлены необходимые соединения между платой Arduino Uno, светодиодами и сервомотором.

Arduino Uno 1-й светодиод 2-й светодиод сервомотор
2 Anode через 1k resistor
5 Anode через 1k resistor
6 PWM pin (Orange)
+5V +5V (RED)
GND Cathode GND Cathode GND GND (Brown)

Со схемой разобрались, можно переходить к написанию программы.

Объяснение программы Arduino для связи по протоколу Modbus RS-485

В нашем проекте плата Arduino Uno используется в качестве ведомого устройства (Slave) протокола Modbus. К плате Arduino Uno подключены два светодиода и сервомотор. Ведомая плата Arduino Uno управляется программным обеспечением Master Modbus. Связь между Master Modbus и платой Arduino Uno осуществляется с помощью модулей RS-485. Для подключения к компьютеру используется модуль преобразования USB в RS-485, а для подключения к плате Arduino Uno используется модуль преобразования MAX-485 TTL to RS-485. Собранная конструкция проекта выглядит следующим образом:

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

Для использования протокола Modbus в плате Arduino Uno мы подключим в программе библиотеку . Эта библиотека применяется для связи с ведущим или ведомым устройством Modbus RS-485 при помощи протокола RTU. Скачайте эту библиотеку по следующей ссылке — Modbus RTU. Добавьте ее в Arduino IDE при помощи команды Sketch->include library->Add .zip Library.

Первым делом в программе мы подключим необходимые библиотеки: для работы с Modbus RS-485, а также библиотеки для работы с ЖК дисплеем и сервомотором.

Источник

Оцените статью