Шина RS485 на кілька пристроїв: шлейф, термінатори, адреси
Написано для прошивки 0.2.159 (коміт 59f5b35) · порталу 0.0.190Можливо, застаріло: поточна прошивка 0.2.205, поточний портал 0.0.236
З одним частотником шина RS485 прощає майже все: вона коротка, пристрій на ній один, і працює навіть те, що зібрано неправильно. Другий пристрій цю поблажливість забирає. Зʼявляються поломки, яких раніше не було: у логах сиплються помилки CRC, один модуль «зникає», коли вмикається інший, а тест показує відповідь від чужої адреси.
Причин рівно чотири, і жодна з них не в програмі: зайвий термінатор, різна швидкість, однакові адреси й другий майстер на лінії. Ця стаття — про те, як завести на один провід кілька контролерів oCBot і модулів Modbus так, щоб шина не потребувала подальших пояснень.
Три дроти на всіх і один UART на контролер#
Фізично шина — це два сигнальні дроти, A (дані «плюс») і B (дані
«мінус»), плюс третій дріт спільної землі. Скільки б пристроїв не висіло на
лінії, дротів лишається три: усі клеми A зводяться разом, усі B — разом,
усі GND — разом.
На KC868-A6 і KC868-A16 у шину дивиться драйвер MAX13487EESA з
автоматичним перемиканням напряму: окремого піна DE/RE немає, тому в
розкладці плат rts = -1 і в налаштуваннях його задавати не треба
(A6, A16).
Друге, що задає всю подальшу архітектуру: UART під RS485 у контролера
один (UART2). Прошивка піднімає на ньому або майстер-опитування, або
відповідач-вузол — залежно від поля «Роль контролера» в Налаштування →
Обладнання (rb_environment.cpp: ROLE_SLAVE → init_slave(), інакше
init()). Одночасно і те, і те неможливо, і це не налаштування, а кількість
портів у чипі.
Схема: шлейф від першого пристрою до останнього#
Правила розкладки, які не залежать від кількості пристроїв:
- Тільки лінія. Шина йде від першого пристрою до останнього одним шлейфом. Зірка, «павучок» у клемнику й довгі відгалуження від основної лінії дають відбиття й помилки передачі.
- Відгалуження — короткі. Пристрій сідає на лінію в тому місці, де лінія повз нього проходить, а не на метровому «хвості» збоку.
- Земля — третім дротом. Особливо коли частотник і контролер живляться від різних джерел: без вирівнювання потенціалів зʼявляються «випадкові» помилки CRC, які неможливо повторити.
- Силові кабелі — окремо. Захист на платах (TVS-діоди SMBJ6.8CA і
самовідновні запобіжники на лініях
AіB) розрахований на статику й короткі викиди, а не на сусідство з кабелем двигуна.
Порядок пристроїв у шлейфі довільний — крім країв. На кінцях краще ставити контролери oCBot, і причина в наступному розділі.
Термінатори: на A6 і A16 вони вже впаяні#
На двох фізичних кінцях шини між A і B має стояти узгоджувальний
резистор 120 Ом. Два на всю шину — не більше й не менше, посередині
жодного.
На платах Kincony цей резистор уже стоїть, і не перемичкою, а впаяний (звірено зі схемами з каталогу):
| Плата | Драйвер шини | Термінатор | Запобіжники на лініях |
|---|---|---|---|
| KC868-A6 | U24, MAX13487EESA | R54, 120 Ом | R51, R55 — PPTC 10 Ом |
| KC868-A16 | U29, MAX13487EESA | R79, 120 Ом | R78, R80 — PPTC 10 Ом |
Звідси проста розкладка:
- Два oCBot на шині — ставте їх на кінці шлейфа, і термінатори вже правильні: по одному на кожному кінці, обидва заводські. Робити нічого не треба.
- Сторонні пристрої між ними — частотники й модулі Modbus зазвичай мають свій термінатор на перемичці або DIP-перемикачі. Він вмикається лише якщо пристрій стоїть на кінці шини. Усе, що в середині, іде без термінатора.
- Три і більше oCBot — у середніх контролерів резистор доведеться підняти паяльником (R54 на A6, R79 на A16). Перемички для цього не передбачено.
Три впаяних термінатори дають 40 Ом замість 120 — це вже не узгодження, а навантаження на драйвер: розмах сигналу падає, і шина починає «губити» пристрої тим частіше, чим вона довша. Саме тому третій контролер у середині шлейфа — єдиний випадок, коли в цій системі треба брати паяльник.
Звідси ж практичне: там, де потрібні просто зайві реле чи аналогові входи, дешевше й спокійніше повісити на шину модуль розширення, ніж третій контролер. Модуль на шині — це адреса, контролер у середині шлейфа — це ще й паяльник.
Кабель і клеми: куди що прикручується#
На колодці RS485 обох плат Kincony лише дві клеми — A і B. Землі там
немає, і це перше, на чому зупиняються: третій дріт прикручувати нібито
нікуди.
Насправді є, і на обох платах — в одному й тому ж місці. Порядок клем на корпусі (за картами роз'ємів):
| Плата | Колодка RS485 | Що стоїть одразу за клемою B |
|---|---|---|
| KC868-A6 | A, B |
GND — перша клема колодки цифрових входів DI-6…DI-1 |
| KC868-A16 | A, B |
GND — перша клема колодки аналогових входів 1–4 |
Усі клеми GND на платі — одна й та сама точка, мінус блока живлення
(входи A6, входи A16). Тож
«найближча GND» — це не компроміс, а буквально та сама земля, що й на
будь-якій іншій колодці; на A16 її видно ще й ліворуч від RS485, на колодці
входів 9–16.
Схема намальована ролями, а не моделями: пара може бути хоч A6 і A16, хоч два A16 — порядок клем на обох платах однаковий, різниться лише те, яка саме колодка стоїть за RS485. І вузол на ній не останній: три дроти йдуть від нього далі, тож термінатор на його платі — уже зайвий.
Кабель — екранована вита пара, годиться звичайний FTP категорії 5e, тим самим, яким ведуть датчики:
AіB— обов'язково дві жили однієї пари. Це і є весь сенс витої пари: завада наводиться на обидві жили однаково, а приймач бачить різницю й тому її не помічає. РознеслиAіBпо різних парах — і диференційна лінія перестала бути диференційною.GND— жила з іншої пари (можна кілька жил разом, вони все одно вільні).- Довжину міряти по трасі, а не по прямій: зайві метри «для запасу», згорнуті бухтою в шафі, — це і є та довжина, на якій шина починає помилятися.
Екран: приєднується один раз, з боку майстра#
Екран кабелю притягується до GND лише в одній точці на всю шину — біля
майстра, на ту саму клему, куди приходить третій дріт (дві жили під одним
гвинтом — нормально). З усіх інших боків екран обрізається й ізолюється.
Правило те саме, що для кабелю датчиків (колодка DA/IO на A6), і причина та сама: земля двох шаф ніколи не має однакового потенціалу. Приєднаний із двох боків екран замикає цю різницю через себе, по ньому починає текти зрівнювальний струм — і замість того, щоб захищати пару, екран сам стає джерелом завади просто поруч із нею.
Екран не замінює третій дріт. Спільна земля — це опорний потенціал, відносно якого приймач міряє різницю між A і B; екран — це заземлена оболонка, яка нічого не опорює. Шина, зібрана «дві жили плюс екран замість GND», працює рівно доти, доки всі пристрої живляться від одного блока.
У проміжних пристроях екран не розривається: вхідний і вихідний з'єднуються між собою й ізолюються від клем. Інакше замість одного суцільного екрана виходить набір коротких відрізків, кожен із яких уже нічого не екранує.
Адреси: різні в усіх, і заводські збігаються#
Кожен пристрій на шині має свій номер — Modbus Slave ID від 1 до 247. Два пристрої з однаковим номером відповідають одночасно, кадри накладаються, і на екрані це виглядає як «постійні помилки CRC» або як відповідь від чужої адреси.
Пастка в тому, що заводські адреси в різних виробників однакові: два нові частотники з коробки — це два пристрої з адресою 1.
| Пристрій | Де задається адреса | Заводська адреса | Заводська швидкість |
|---|---|---|---|
| oCBot у ролі вузла | Налаштування → Обладнання: «Роль контролера» = Slave, далі «Modbus Slave ID» | — | — |
| Ennera FCE | група C08 з пульта |
1 | 9600 |
| Yingshida AE200 | P.142 |
1 | 9600 (P.143 = 3) |
| CFM310 | 6-13 |
81 | 19200 (6-12 = 3) |
| Модуль реле N4D8B08 | перемичками на платі | — | 9600 (типово) |
| Модуль PT100 (PTA8C04) | налаштуванням модуля | — | 9600, 8N1 |
| Лічильник PZEM-016 | запис у регістр 0x0002 кодом 06 |
1 (за прикладами керівництва) | 9600 |
Два зауваження до таблиці:
- Швидкість у контролера одна на всю шину. Вона задається в Плати та
шини → «Параметри RS485» (9600, 19200, 38400, 57600 або 115200), і всі
пристрої мають бути переведені на неї. Формат кадру в прошивці зашитий —
8N1, без контролю парності (
rb_modbus.cpp,_configure_uart_rs485()), тож пристрій із парністю треба перемкнути на 8N1, а не навпаки. - Адреси модулів часто задаються до монтажу. У N4D8B08 це перемички на платі, тобто після встановлення в шафу їх уже не видно. Розпишіть номери на папері перед збиранням і підпишіть модулі.
У PZEM-016 є зручна деталь для першого налаштування: загальна адреса 0xF8
працює тільки тоді, коли на шині один пристрій (керівництво PZEM-014/016).
Тобто адресу новому лічильнику зручно призначати окремо, а не в готовій
шафі.
Майстер на шині один#
Modbus RTU — протокол «питання-відповідь». Ініціативу має лише майстер; решта пристроїв мовчить, поки їх не спитали. Два майстри на одній лінії означають два кадри одночасно — шина не працює в жодного.
Тому в системі з кількох oCBot майстер один, решта — вузли (Slave). І
звідси наслідок, про який легко забути: частотник вішається на майстра.
Вузол свій UART уже витратив на те, щоб відповідати, і власним майстром для
частотника бути не може.
Другий контролер додається в Плати та шини → «Додати нову плату» → тип «Контролер ESP32 (Універсальний розширювач)», і далі є два способи ним скористатися:
| Плата розширення | Повноцінний вузол | |
|---|---|---|
| Поле «IP / host вузла» | порожнє | заповнене |
| Де живе периферія | створюється на майстрі, адресами регістрів | створюється на самому вузлі |
| Де виконуються скрипти | на майстрі | на вузлі, автономно |
| Що йде по шині | читання й керування регістрами вузла: реле 0x0100+, входи 0x0200+, аналог 0x0300+, ЦАП 0x0400+ |
оркестрація скриптів: 0x1000+uid (стан, старт і стоп) і 0x1040+uid (режим) |
| Що йде мережею | — | директорія скриптів і периферії, живість і стан вузла — GET /api/node_directory |
Рядок про шину для вузла варто прочитати уважно, бо очікування тут зазвичай
інші. heartbeat (0x000B) і node_state (0x000C) у карті регістрів
вузла є. Але прошивка їх по шині не опитує:
ті самі два числа вузол кладе ще й у JSON директорії
(rb_server_handler.cpp), і «онлайн» у майстра береться саме звідти
(rb_js.js, rb_node_online). Між двома oCBot по шині ходять рівно дві
адреси — 0x1000+uid і 0x1040+uid (rb_scripts_internal.cpp). Те саме з
блоком значень периферії 0x1100: вузол його віддає, а майстер-oCBot не
читає — значення приходять директорією.
Поділ навмисний: шина — це реальний час і безпека, мережа — виявлення, назви й конфігурація. Один 16-бітний регістр за транзакцію на 9600 незручний для рядків і списків, а вузли й так стоять у тій самій локальній мережі; натомість команда «стоп» не може залежати від того, чи піднявся Wi-Fi.
Прошивка 0.2.159 віддає по шині стан реле вузла (0x0100+) і їхню бітову маску
(0x0110), цифрові входи (0x0200+) і їхню маску (0x0210), аналогові входи
(0x0300+), значення периферії (0x1100+), стан скриптів (0x1000+), heartbeat
і node_state.
На прошивках 0.2.158 і старіших регістри цифрових і аналогових входів
відповідали винятком 0x02 — через помилку в діапазонах, виправлену в 0.2.159.
Якщо вузол лишається на старій прошивці, ті самі входи читаються як його периферія
блоком 0x1100.
Який із двох режимів брати#
Плату розширення — коли другий контролер потрібен лише як зайві входи й
виходи: свого розуму йому не треба, майстер сам опитує його регістри, як
опитував би релейний модуль. І окремо — коли майстром узагалі не oCBot:
SCADA, ПЛК, панель оператора чи будь-який сторонній Modbus-майстер. Саме
заради цього випадку блоки 0x01–0x04 і існують: сторонній майстер не
знає нашої HTTP-директорії, і карта регістрів — його єдиний шлях до вузла.
Повноцінний вузол — коли контролер має виконувати власні скрипти й власний аварійний захист і переживати втрату зв'язку з майстром. Це те, заради чого вузли й робились: обрив шини для такого контролера — не зупинка процесу, а лише втрата координації.
Периферія і скрипти створюються на тому контролері, до якого вони фізично підключені; майстер їх виявляє й оркеструє, а не володіє їхньою конфігурацією. Наскрізного створення сутностей з майстра немає свідомо: інакше в однієї конфігурації з'явилося б два господарі й вічне питання, чия копія правильна після обриву зв'язку.
Щоб не лише бачити вузол, а й керувати ним, у поле «Ключ доступу вузла» треба внести ключ із самого вузла (Налаштування → Обладнання). Кнопка «Сканувати» поруч із полем IP знаходить oCBot у підмережі сама.
Логіка ролей описана в Мультиконтролерності — там про те, який контролер що робить; тут — про дріт, яким вони зʼєднані.
Скільки пристроїв витримає одна шина#
Адрес у протоколі 247, але практична межа нижча, і задають її три різні речі.
Електрика лінії. Виробник модуля PT100 прямо пише: на одній шині допускається до 247 модулів, але вже понад 16 потрібен повторювач RS485. Виробник релейного N4D8B08 обіцяє до 64 пристроїв. Це верхні межі для ідеальної лінії, а не план на шафу.
Майстер у прошивці. Він робить рівно три речі (rb_modbus.h): читає
holding- і вхідні регістри кодами 0x03 і 0x04 та пише один регістр
кодом 0x06. Котушкових функцій (0x01, 0x05, 0x15) і пакетного запису
0x10 немає. Тому модуль, у якого реле сидять на котушках, контролер не
перемкне, а вісім реле — це вісім окремих транзакцій.
Час. Кожне читання периферії — окрема транзакція на шині. Між кадрами
прошивка витримує паузу t3.5 (38 500 000 / швидкість мікросекунд — це 4 мс
на 9600 і 0.33 мс на 115200), а на відповідь чекає 150 мс. Тобто один
мовчазний пристрій коштує 150 мс у кожному колі опитування — і чим більше
пристроїв, тим помітніше «підгальмовує» вся шина. Якщо на шині більше
десятка пристроїв, швидкість 9600 вже варто піднімати.
Мовчазний пристрій до того ж не заливає лог: перші три невдачі поспіль пишуться як є, далі — раз на 30 секунд із накопиченим лічильником, і пауза подвоюється до пʼяти хвилин. Успішна операція лічбу скидає, тож повернення пристрою в лозі теж видно.
Перевірка: кнопка «Тестувати підключення»#
У модалі плати є кнопка «Тестувати підключення». Вона шле пристрою
мінімальний запит (0x03, регістр 0x0000, один регістр) і за відповіддю
розрізняє п'ять ситуацій. На спільній шині вони читаються так:
| Що показала кнопка | Що це означає, коли пристроїв багато |
|---|---|
| Підключення успішне | Пристрій відповів своєю адресою. Шина, швидкість і адреса правильні. |
| Пристрій не відповідає (0 байт) | Його на лінії немає: переплутані A і B, обрив у шлейфі після попереднього пристрою, не та адреса або пристрій знеструмлено. |
| Спотворені дані (помилка CRC) | Фізично звʼязок є, а домовитись не виходить: інша швидкість або формат кадру, зайвий чи відсутній термінатор, наводка від силового кабелю. |
| Виняток Modbus | Це добра новина. Адреса й швидкість правильні, кадр складено вірно — просто регістра 0x0000 у карті цього пристрою немає. |
| Відповів пристрій з іншим ID | На шині є пристрій з тим номером, який ви шукаєте деінде, — типовий симптом двох однакових заводських адрес. |
Порядок, у якому це швидше сходиться: додавайте пристрої на шину по одному, і кожен перевіряйте кнопкою одразу після підключення. Шина, яку зібрали цілком і ввімкнули, дає одну загальну помилку на всіх, і шукати в ній доводиться перебором.
Суміжні статті#
- Промисловий протокол RS485 (Modbus RTU) — основи шини й покрокове налаштування першого пристрою: піни, швидкість, додавання плати.
- Мультиконтролерність — навіщо взагалі другий контролер, які бувають ролі й що робить майстер.
- Шини й роз'єми KC868-A6 і
Шини й мережа KC868-A16 — де на платах клеми
AіB, які GPIO зайняті під RS485 і що ще висить на тих самих шинах. - Плати та шини — той самий екран інтерфейсу, з якого додаються плати й відкриваються «Параметри RS485».