Как стать автором
Обновить

Arduino & Modbus

Время на прочтение6 мин
Количество просмотров212K
В предыдущей статье мы соединили открытую платформу домашней автоматизации 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 slave(ID, 0, 0);

Затем определить массив регистров Modbus
uint16_t au16data[11];

После этого, при старте программы настроить последовательный порт ведомого
slave.begin(9600);

В основном цикле программы необходимо вызывать функцию обработки Modbus сообщений
state = slave.poll(au16data, 11);

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

#include "ModbusRtu.h"

#define ID   1      // адрес ведомого
#define btnPin  2   // номер входа, подключенный к кнопке
#define stlPin  13  // номер выхода индикатора работы
                    // расположен на плате Arduino
#define ledPin  12  // номер выхода светодиода

//Задаём ведомому адрес, последовательный порт, выход управления TX
Modbus slave(ID, 0, 0); 
boolean led;
int8_t state = 0;
unsigned long tempus;

// массив данных modbus
uint16_t au16data[11];

void setup() {
  // настраиваем входы и выходы
  io_setup();
  // настраиваем последовательный порт ведомого
  slave.begin( 9600 ); 
  // зажигаем светодиод на 100 мс
  tempus = millis() + 100; 
  digitalWrite(stlPin, HIGH );
}

void io_setup() {
  digitalWrite(stlPin, HIGH ); 
  digitalWrite(ledPin, LOW ); 
  pinMode(stlPin, OUTPUT); 
  pinMode(ledPin, OUTPUT);   
  pinMode(btnPin, INPUT);  
}

void loop() {
  // обработка сообщений
  state = slave.poll( au16data, 11);  
  // если получили пакет без ошибок - зажигаем светодиод на 50 мс 
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(stlPin, HIGH);
  }
  if (millis() > tempus) digitalWrite(stlPin, LOW );
  //обновляем данные в регистрах Modbus и в пользовательской программе
  io_poll();
} 

void io_poll() {
  //Копируем Coil[1] в Discrete[0]
  au16data[0] = au16data[1];
  //Выводим значение регистра 1.3 на светодиод 
  digitalWrite( ledPin, bitRead( au16data[1], 3 ));
  //Сохраняем состояние кнопки в регистр 0.3
  bitWrite( au16data[0], 3, digitalRead( btnPin ));
  //Копируем Holding[5,6,7] в Input[2,3,4]
  au16data[2] = au16data[5];
  au16data[3] = au16data[6];
  au16data[4] = au16data[7];
  //Сохраняем в регистры отладочную информацию
  au16data[8] = slave.getInCnt();
  au16data[9] = slave.getOutCnt();
  au16data[10] = slave.getErrCnt();
}

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



Для демонстрации работы с разными регистрами, в процессе работы программы данные из регистра с типом 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.
Теги:
Хабы:
Всего голосов 19: ↑19 и ↓0+19
Комментарии49

Публикации

Истории

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань