14 июля 2015 в 11:15

Arduino -> FLProg -> RS-485 -> Modbus


Вышла новая версия программы FLProg c номером 1.9.1. Я подумал что нововведения в программе заслуживают освещения на хабре.Так же расскажу немного теории о протоколе Modbus и особенностях его реализации на борту Arduino.

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

Именно этой разностью потенциалов и передается сигнал. Такой способ передачи обеспечивает высокую устойчивость к синфазной помехе. Синфазной называют помеху, действующую на оба провода линии одинаково. К примеру, электромагнитная волна, проходя через участок линии связи, наводит в обоих проводах потенциал. Если сигнал передается потенциалом в одном проводе относительно общего, как в RS-232, то наводка на этот провод может исказить сигнал относительно хорошо поглощающего наводки общего («земли»). Кроме того, на сопротивлении длинного общего провода будет падать разность потенциалов земель — дополнительный источник искажений. А при дифференциальной передаче искажения не происходит. В самом деле, если два провода пролегают близко друг к другу, да еще перевиты, то наводка на оба провода одинакова. Потенциал в обоих одинаково нагруженных проводах изменяется одинаково, при этом информативная разность потенциалов остается без изменений.
Так выглядит типичная посылка, от Ведущего — Ведомому.

Так выглядит ответ Ведомого — Ведущему

ID — Адрес ведомого устройства. Он может иметь значения от 1 до 247. Адрес 0 используется для широковещательной передачи, его распознаёт каждое устройство, адреса в диапазоне 248…255 — зарезервированы.
В программе FLProg для ведущего (Master) реализована поддержка 32 ведомых (Slave) устройств что обусловлено применяемыми конвертерами UART -> RS-485.

Команда(код функции):
в данном примере одна, на чтение 0x03.
Но в действительности их намного больше.
Все коды функций делятся на:
— Публичные коды, описанные в стандарте MODBUS-IDA. Их список включает уже назначенные и используемые коды, а также коды для будущего использования;
Список
0x02) — чтение значений из нескольких дискретных входов (Read Discrete Inputs).
(0x03) — чтение значений из нескольких регистров хранения (Read Holding Registers).
(0x04) — чтение значений из нескольких регистров ввода (Read Input Registers).
(0x05) — запись значения одного флага (Force Single Coil).
(0x06) — запись значения в один регистр хранения (Preset Single Register).
(0x07) — Чтение сигналов состояния (Read Exception Status)
(0x0F) — запись значений в несколько регистров флагов (Force Multiple Coils)
(0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)
(0x16) — запись в один регистр хранения с использованием маски «И» и маски «ИЛИ» (Mask Write Register).
(0x18) — Чтение данных из очереди (Read FIFO Queue)
(0x14) — Чтение из файла (Read File Record)
(0x15) — Запись в файл (Write File Record)
(0x08) — Диагностика (Diagnostic)
(0x0B) — Чтение счетчика событий (Get Com Event Counter)
(0x0C) — Чтение журнала событий (Get Com Event Log)
(0x11) — Чтение информации об устройстве (Report Slave ID)
(0x2B) — Encapsulated Interface Transport

— User-Defined Function Codes (65-72, 100-110) — коды, которые могут использоваться компаниями для собственных функций, и не описаны в спецификации;
— Reserved Function Codes (9, 10, 13, 14, 41, 42, 43, 90, 91, 125, 126 и 127) — зарезервированы коды, которые не доступны для общего использования.
Обработка ошибок
Ведущий отправляет запрос к Ведомому, в котором в поле «код функции» указывает ему на необходимое действие.
Байты данных содержат информацию, необходимую для выполнения данной функции.
Ведомый, в случае удачного выполнения этой функции, повторяет код функции в ответе.
При возникновении ошибки, код функции в ответе модифицируется — старший бит выставляется в 1.
В байтах данных передается причина ошибки. Например при исполнении Ведомым функции 0x0F возникла ошибка, тогда он ответит Ведущему полем функции равным 0x8F.
В дополнении к изменению кода функции, Ведомый размещает в поле данных уникальный код, который указывает на тип и причину ошибки.
В спецификации Modbus определено два типа данных, один бит и 16 битное слово. Данные организованны в четыре таблицы с 16 битной адресацией ячеек, адресация в таблицах начинается с 0. Для доступа к данным из разных таблиц предназначены отдельные команды.
Discrete Inputs 1 бит только чтение
Coils 1 бит чтение и запись
Input Registers 16 бит только чтение
Holding Registers 16 бит чтение и запись

Стандарт предусматривает отдельную таблицу для каждого типа данных, но особенностью реализации в программе FLProg является то, что все регистры ведомого хранятся в одном массиве в виде перекрывающихся таблиц, соответственно все команды от ведущего будут обращаться к одно и той же области памяти. В реализации ведущего предусмотрена работа только с таблицей «Holding Registers».

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

Они стоят недорого но достаточно надежны. Собраны на микросхеме MAX485.

Соеденение с Arduino проводятся по схеме

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

QModBus — Симулятор ведущего


PeakHmiMBSerialSlave — Симулятор ведомого


Ну и напоследок видео урок по созданию ведущего и ведомого устройства в программе FLProg.


PS. Благодарю авторов представленных ниже статей, которые помогли мне разобраться с протоколом Modbus, и реализовать данный функционал.
Источники:
Modbus RTU для Чайников
Arduino & Modbus
Автор: @totuin
FLProg
рейтинг 33,46
Графическая среда программирования Arduino

Комментарии (2)

  • 0
    Пока в программе FLProg реализована передача данных только по через RS-485.
    А собственно какие трудности с 232? Тот и тот через конвертеры видятся COM-портами, а как там железно всё устроено — забота драйвера, нет?
    • 0
      Это можно реализовать без проблем, библиотека поддерживает. Но я не вижу смысла. Основная идея Modbus — большое количество слейвов на шине. С 232 такого не получится. А для обмена данными по UART (COM-порт) в программе реализован другой, более быстрый дуплексный механизм

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

Самое читаемое Разработка