![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#1
|
|
![]() Администратор ![]() ![]() ![]() ![]() ![]() Группа: Главные администраторы Сообщений: 14349 Регистрация: 12.10.2007 Из: Twilight Zone Пользователь №: 1 ![]() |
Разработка для интернета вещей*, SCADA*, Arduino* В предыдущей статье мы соединили открытую платформу домашней автоматизации 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(19200); В основном цикле программы необходимо вызывать функцию обработки 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( 19200 ); // зажигаем светодиод на 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(); } Стандарт предусматривает отдельную таблицу для каждого типа данных, но особенностью применённой библиотеки является то, что все регистры хранятся в одном массиве, поэтому структура регистров контроллера будет выглядеть следующим образом: Регистр Тип Название Доступ au16data[0] discrete 0:DT0; 1:DI1; 2:DT2; 3:BTN только чтение au16data[1] coil 0:CL0; 1:CL1; 2:CL2; 3:LED чтение и запись au16data[2] input IN0 только чтение au16data[3] input IN1 только чтение au16data[4] input IN2 только чтение au16data[5] holding HLD0 чтение и запись au16data[6] holding HLD1 чтение и запись au16data[7] holding HLD2 чтение и запись Для демонстрации работы с разными регистрами, в процессе работы программы данные из регистра с типом 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:arduinoEATConsole, затем открыть страницу загрузки Eclipse, скачать Eclipse IDE for Java Developers и распаковать его в папку C:arduinoeclipse, после этого скопировать файлы из папки C:arduinoEATConsoleeclipseplugins в папку C:arduinoeclipseplugins. Для создания конфигурации необходимо запустить C:arduinoeclipseeclipse.exe, создать пустой проект, скопировать в него пустой файл C:arduinoEATConsolemenu.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 CL0 1 Input Boolean 1 1 CL1 1 Input Boolean 1 2 CL2 1 Input Boolean 1 3 LED 1 Display Integer 2 IN0 0 1 Display Integer 3 IN1 0 1 Display Integer 4 IN2 0 1 Display Integer 5 HLD0 0 1 Display Integer 6 HLD1 0 1 Display Integer 7 HLD2 0 1 Type — тип элемента меню EATConsole. Address — адрес регистра данных. Bit – номер бита в регистре. Name – название элемента меню. Point – количество десятичных знаков после точки. Slave – Modbus адрес контроллера. Теперь сохраним и скопируем файл menu.ptmenu в каталог C:arduinoEATConsole, для этого можно щёлкнуть правой кнопкой мыши на файле прямо в Eclipse, выбрать в контекстном меню пункт “Copy”, а затем вставить в проводнике в папку C:arduinoEATConsole. После этого запустим C:arduinoEATConsoleEATConsole.exe, настроим последовательное соединение, выбрав пункт меню ФайлНастройки, в диалоговом окне укажем номер порта, скорость 19200, 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. Original source: habrahabr.ru (comments, light). Читать дальше -------------------- |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 31.7.2025, 10:19 | |
|