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 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:\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 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:\arduino\EATConsole для цього можна клацнути правою кнопкою миші на файлі прямо в Eclipse, вибрати в контекстному меню пункт «Копіювати», а потім вставити в провіднику в папку C:\arduino\EATConsole.

Після цього запустимо C:\arduino\EATConsole\EATConsole.exe, налаштуємо послідовне з'єднання, вибравши пункт меню Файл\Настройки в діалоговому вікні вкажемо номер порту, швидкість 19200, 8 біт даних, 1 стоповий біт.



*Програма працює з портами з 1 по 8 і якщо USB перехідник Arduino встав на порт з більшим номером, доведеться відкрити диспетчер пристроїв Windows і змінити номер порту для нього.

Коли всі налаштування будуть введені, натисніть кнопку «Встановити», відразу після цього програма почне опитування пристрою і якщо щось пішло не так з'явиться повідомлення — НЕМАЄ ЗВ'ЯЗКУ. Якщо ж все було зроблено правильно і зв'язок є в чому можна пересвідчитись по миганню індикатора статусу (світлодіод на виводі 13), то пора приступити до випробувань нашого контролера.

Спробуємо поміняти значення в регістрах HLD0...HLD2 і СL0… СL 2, при цьому повинно змінитися значення у відповідному регістрі 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.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.