Modbus на практике
- Войдите на сайт для отправки комментариев
Добрый день!
Решил я тут на практике изучить протокол Modbus. Ну то есть взять какое нибудь устройство, отправлять на него ардуиной запросы и получать ответы. План такой: найти где нибудь на Авито б/у прибор, например электросчетчик или теплосчетчик, подключить его и поиграться. Их сейчас просто меняют, вместо поверки. Но после поиска возникла куча вопросов:
1. M-bus и Modbus - это одно и то же? С точки зрения общения ардуино с устройством? Подойдут ли библиотеки Modbus для этого?
2. Если устройство имеет интерфейс rs485 - то не обязательно оно поддерживает Modbus?
3. Может посоветуете дешманский прибор, поддерживающий Modbus? Или его эмулятор. Может скетч есть для ардуино, эмулирующий какое то устройство?
Скетч наверняка есть в той же библиотеке.
Выскажу субъективное мнение.
Российские производители оборудования - хлеще китайцев. Те, хотя бы, воруют индустриальные стандарты, а не придумывают свои протоколы там, где этого вообще не требуется. И не обзывают эти протоколы так, что не разберёшься где чей.
Поэтому есть шанс прикупить какой-нить Меркурий с модифицированным модбасом, обозванным мбасом и работающим на UART с настройкой 7N2 вместо стандарта де-факто 8N1, а потом покупать к нему за тонны нефти переходник с мбаса на модбас.
RS485 напрямую с модбасом не связан. Наличие одного не гарантирует присутствие другого.
Дешманский прибор. Слово FLProg здесь ругательное, но я знавал одного товарища, который на нем лепил оконечные устройства, которыми потом по модбасу рулил. Причем через гейт Modbus-RTU/Modbus-TCP, далее в линупс, через perl в SQL, затем через php в браузер. Вобщем трехэтажный дом из говна и палок. Но! Эти херовины на FLProge вполне себе устойчиво щелкали релюхами и даже, вроде, отдавали температуры.
Чего тут советовать. Копеечный модбас свисток и программный эмулятор на компе, коих туева хуча в интернете. Вы вроде старожил, в гугл вас отправлять как то стыдно....
Про M-bus, опять же интернет на пол шишечки копните, там и программный интерфейс для нокиа, счетчика всякие, музыкальный интерфейс от мерседеса.... Но никак не мод бас.
несколько лет назад я разбирался с Modbus,
основной протокол довольно простой, но он содержит пакеты "произвольного" характера, именно на этих пакетах и построены все расширения Modbus-а, то есть никто не ломает его а просто на него делают некую надстройку (по аналогией с TC/IP)
Самый главный недостаток этого протокола - в нем обязательно должно быть устройство мастер, а остальные слейвы. Причина кроется в физической реализации.
Я тогда начал изобретать свой велосипед на технологии кольцевых выборов, в принципе даже у меня работало 4 устройства одновременно. То есть каждое устройство умело находить промежуток не занятый другими устройствами и отсылало или широковещательный или персональный пакет.
Отлаживал на компе, для этого я игрался эхом UART и USB микросхем, то есть у меня комп через USB был таким-же участником как и остальные.
Тот проект пока немного задвинут из-за нехватки времени...
про rs485 - это физический (точнее электрический) протокол, к Modbus он не имеет никакого отношения
там протоколов масса...
а Modbus может быть реализован например поверх того же tc/ip в обычных компьютерных сетях
Спасибо всем ответившим! Потихоньку начинаю разбираться.
Действительно проблематично найти дешевые устройства с реализацией Modbus. Есть куча электросчетчиков и теплосчетчиков с rs485, но Modbus там и не пахнет. В основном это M-bus или еще какой-нибудь протокол. Многие счетчики могут быть доукомплектованы переходником на Modbus, но они тоже недешевые. В основном Modbus имеют трехфазные счетчики. Работать с ними в домашних условиях проблематично, да и стоят они дороже однофазных.
Самое дешевое что я нашел, это реле, работающее по modbus вот такое но судя по отзывам - там китайская реализация протокола.
Буду пробовать эмулировать устройство. Посмотрел - кто как только не извращается для этого. Даже вроде как эмулятор Nextion-дисплея может по Modbus общаться.
PZEM-004 v2 с модбасом, вроде как. v1 со своим, китайским.
Подключение - простой UART
Ну, и совет брукли не забывать - взять RS-485 модуль для ардуины + RS-485/USB свисток для PC (это если очень хочется с 485-м завестись) + программный Modbus слейв для PC.
Занимался модбасом много. Бегает у меня под ним куча устройств. Вот только программ на РС почти совсем нет. Есть мастер Qmodbus. Работает отлично. Слейвы есть но все платные. С ограничением функций для пробных версий. Может кто подскажет чего я не нашёл?
nik182, писни мне на wrk.sadman@gmail.com в пнд. Я на работе гляну - там где-то отличный слейв у меня валялся.
Ага, ты рутрекер не нашел :)
Ага, ты рутрекер не нашел :)
Только вот я не понимаю. Уж если взял модбас, то и пользуй его через какой нить PLC или Панельку с функцией мастера. Ну или если есть слейв модбасовский какой то очень нужный , можно свой сервер на ардуине написать. А вот компьютер для рулежки слейвами... Это тогда скада какая нибудь монструозная и куча слейвов, а иначе оно зачем ?
Ага, ты рутрекер не нашел :)
Только вот я не понимаю. Уж если взял модбас, то и пользуй его через какой нить PLC или Панельку с функцией мастера. Ну или если есть слейв модбасовский какой то очень нужный , можно свой сервер на ардуине написать. А вот компьютер для рулежки слейвами... Это тогда скада какая нибудь монструозная и куча слейвов, а иначе оно зачем ?
У меня как то на рутрекере не нашлось слейва для модбаса. Но это уже дела давно минувших дней, когда с модбасом разбирался. Сейчас на дельфях написан мастер и под stm слейв на основе freemodbus. Полностью покрывает все мои хотелки. По крайней мере производительности хватает в реальном времени рисовать осцилограммы токов и напряжений шестифазного тиристорного регулятора. Ну и управлять им одновременно.
А частота оцифровки графиков какая ? Я могу на модбасе мону лизу нарисовать в реал тайме :)
Речь не о скорости модбаса, а о назначении. Это промышленный, достаточно длинный интерфейс. Кстати настолько простой, что всякие чудеса типа монструозных библиотек и целых систем программирования в этом вопросе излишни.
Абсолютно согласен. Когда разберёшся - ни проблем ни библиотек. Работает у меня в условиях наводок. Когда диагностику смотришь иногда до пяти повторных отправок протокол делает. Но справляется.
Китайцы только народ в заблуждение вводят продавая 485 модули на МАХ495, которые до похабности упрощены, да еще и терминаторы воткнуты везде. В результате человек пытается использовать эти модули и ломает себе голову нахрен.
да еще и терминаторы воткнуты везде. В результате человек пытается использовать эти модули и ломает себе голову нахрен.
Ибо нехрен хвататься не изучив основы, а выпаять всегда проще, чем впаять. Другое дело, что они зажали 2 штырька под джампер - это да... сволочи...
Да. Только вот отсутствие стабилитронов очень часто приводит к выгоранию этого самого макса.
https://media2.24aul.ru/imgs/5320f704e1bf2714b47e5453/nabor-dlya-sborki-preobrazovatelya-interfeysov-v-rs485-1-3830949.jpg
Кстати и пары резисторов в линии китайцы тоже не ставят. Так что да "Ибо нехрен хвататься не изучив основы" :)
Дали мне поиграться вот такой модуль

Подскажите пожалуйста какую библиотеку лучше использовать для чтения значений регистров этой штуки?
Я думал, что самая правильная библиотека - это ардуиновская но там в примерах тема RS485 не раскрыта. Ну то есть там написано, что библиотека зависит от библиотеки ArduinoRS485 (это понятно, ее я без проблем поставлю), но при этом они предлагают использовать шилд "MKR 485 shield" и на нем джампер "FULL" поставить в положение "OFF", и джампер "Z \/\/ Y" тоже в положение OFF. У меня же в наличии есть только тот самый пресловутый модуль на МАХ495, который нужно переключать в режим прием-передача (как я понял), а какой пин это будет делать в этой библиотеке - непонятно.
Нашел шикарные лекции, на всякий случай оставлю здесь ссылки:
Лекция про rs485
Лекция про modbus
Нашел шикарные лекции, на всякий случай оставлю здесь ссылки:
Лекция про rs485
Лекция про modbus
ИМХО. по мне так проще и быстрее прочитать ну хоть в вики, или в ДШ на микросхему 485
что касается modBus RTU и других - стандарт открытый и хорошо описан.
Все равно, пока не начнешь самостоятельно собирать устройство - всегда все понятно, пока до дела не дойдет.
Разве что для старта обучения, в полглаза посмотреть... лучше и проще брать конкретный пример и конкретное устройство, параллельно с изучением стандарта.
Стандарт действительно описан, но есть куча нюансов. И в них вся соль.
Как пример. Стандарт никак не регулирует расположение портов в адресном пространстве. По умолчанию допускается сделать устройство с портами не следующими один за другим. То есть в адресном пространстве портов могут быть "пустые" адреса. При этом стандарт обязывает при чтении таких портов отвечать ошибкой. Но в стандарте же существуют операции и группового чтения-записи. То есть стандарт разрешает писать сразу много портов, последовательно. Если в такую операцию попадает кусок адресного пространства с несуществующими портами, то возникает коллизия, стандарт сам себе противоречит. Наличие хотя бы одной дырки в адресном диапазоне такой операции должен приводить к ошибке и вся операция должна быть ничтожна. Однако на деле у 50% производителей это не так. Вот поэтому часто оборудование разных производителей может быть несовместимо.
Подскажите, есть ли какой-нибудь простой способ, чтобы узнать адрес устройства в сети и скорость передачи данных? Не хочет мне почему-то мое устройство отвечать, пробую по разным адресам на разных скоростях - все без толку.
Может есть какая-нибудь стандартная команда, на которую любое Modbus-устройство отвечает?
Только перебором, имхо.
Подскажите, есть ли какой-нибудь простой способ,
возможно есть, найти ДШ в интранете , на пример открыть этот сайт, вкладка файлы (таблица адресов Modbus: (0.6 Мб))
прикольно получается, ссылка на это устройство, а адреса этого устройства в документе нет, как и таблицы ...
Как это нет? а это что?
Как это нет? а это что?
вариант, что адрес 1 ко всей линейке 7000? все одно, есть чего там почитать...
kost82, на приборе есть кнопка ресет?
В мануале на серию есть инструкция как поменять адрес.
В мануале на серию есть инструкция как поменять адрес.
а есть инструкция как сбросить на дефолт? на скорость и адрес. Чтобы потом свой записать без ненужных телодвижений.
вариант, что адрес 1 ко всей линейке 7000? все одно, есть чего там почитать...
kost82, на приборе есть кнопка ресет?
Есть переключатель Init/Normal, Но как я понял в положении Init он переводит прибор на протокол DCON с определенными начальными параметрами
Да именно по DCON. И программа есть для установки параметров под винду и подробно описано с картинками какие кнопки нажимать для установки своих параметров.
Видимо не обойтись мне без винды, пойду достану старый комп из кладовки. Из под wine не хочет она работать.
Вроде разобрался я с отправкой команд с компьютера: устройство отвечает по адресу 0x01 на команду получения версии прошивки (46 20). Скорость передачи при этом 115200.
Стал пытаться отправлять команды через ардуину. Долго искал библиотеки, но подходящей найти не смог. Какие-то работают с адаптером, на котором нужно выставить непонятные джамперы, и непонятно к какому пину цеплять контакты DE и RE от моего свистка. Другие библиотеки не дают отправлять сырую строку, а сразу считают и добавляют к ней контрольную сумму, которая в моем устройстве (M-7045-NPN) вроде как и не нужна. Некоторые библиотеки просто плохо документированы и пример только один. Короче бросил я это занятие и решил отправлять напрямую. Поскреб по форумам как люди отправляют и наваял себе вот такой скетч
#include <SoftwareSerial.h> byte SendData[12]; #define DE_RE_PIN 7 // The pin controlling Recieve Enable and Driver Enable on the RS485 adapter #define RX_PIN 10 // to R0 on RS485 adapter #define TX_PIN 11 // to DI on RS485 adapter SoftwareSerial modbusSerial(RX_PIN, TX_PIN); void setup() { pinMode(DE_RE_PIN, OUTPUT); Serial.begin(115200); modbusSerial.begin(115200); //3.7.5 Sub-function 32 (0x20) Read firmware version SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x20; //Sub-function code //3.7.4 Sub-function 06 (0x06) Set communication settings /*SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x06; //Sub-function code SendData[3] = 0x00; //Reserved SendData[4] = 0x06; //Baud Rate SendData[5] = 0x00; //Reserved SendData[6] = 0x00; //Reserved SendData[7] = 0x00; //Reserved SendData[8] = 0x01; //Mode SendData[9] = 0x00; //Reserved SendData[10] = 0x00; //Reserved*/ } void loop() { digitalWrite(DE_RE_PIN, HIGH); for (byte i = 0; i < 3; i++) { modbusSerial.print(SendData[i]); delay(1); } /*modbusSerial.flush();*/ Serial.println("-------"); modbusSerial.listen(); delay(10); digitalWrite(DE_RE_PIN, LOW); delay(500); while (modbusSerial.available()) { Serial.print(modbusSerial.read()); } Serial.println(); delay(5000); }В итоге устройство отвечает, но в мониторе порта я вижу только нули. Иногда один, чаще два.
Пробовал всевозможные скорости, которые поддерживает устройство - отвечает на всех скоростях. Пробовал перевести на 9600 (в коде закомментировал эту команду) - ничего не изменилось. Эксперементировал с задержками - все без толку. Если верить документации - то в ответ должно прийти 5 байт, при ошибке - три байта.
Подскажите, плиз, что я делаю не так?
Возьмите МК с двумя UART для начала, а то SoftSerial-ом долго будете ловить байты.
Или реализуйте правильный алгоритм - с простеньким конечным автоматом, без delay(). Ибо пока вы в них висите, Softserial ушами хлопает.
Работа по уарт без delay. Там свой простой протокол. Но может чем и поможет, по аналогии сделать. Ниже тоже читать.
Мегу мне пока достать неоткуда, поэтому решил убрать почти все delay() из цикла. И на всякий случай поменял пины для софтового Serial. Вот что получилось в итоге:
#include <SoftwareSerial.h> byte SendData[12]; unsigned long lastMillis; #define DE_RE_PIN 7 // The pin controlling Recieve Enable and Driver Enable on the RS485 adapter #define RX_PIN 5 // to R0 on RS485 adapter #define TX_PIN 4 // to DI on RS485 adapter SoftwareSerial modbusSerial(RX_PIN, TX_PIN); void setup() { pinMode(DE_RE_PIN, OUTPUT); Serial.begin(115200); modbusSerial.begin(115200); lastMillis = millis(); //3.7.5 Sub-function 32 (0x20) Read firmware version SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x20; //Sub-function code //3.7.4 Sub-function 06 (0x06) Set communication settings /*SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x06; //Sub-function code SendData[3] = 0x00; //Reserved SendData[4] = 0x06; //Baud Rate SendData[5] = 0x00; //Reserved SendData[6] = 0x00; //Reserved SendData[7] = 0x00; //Reserved SendData[8] = 0x01; //Mode SendData[9] = 0x00; //Reserved SendData[10] = 0x00; //Reserved*/ } void loop() { if (millis() - lastMillis >= 5000) { digitalWrite(DE_RE_PIN, HIGH); for (byte i = 0; i < 3; i++) { modbusSerial.print(SendData[i], HEX); delay(10); } modbusSerial.flush(); digitalWrite(DE_RE_PIN, LOW); Serial.println("-------"); lastMillis = millis(); } //modbusSerial.listen(); while (modbusSerial.available()) { Serial.print(modbusSerial.read()); } }Все равно в ответ приходят ноли, но похоже это не ответ устройства, а какое-то "эхо" чтоли. Заметил что при выключенном питании устройства ноли в монитор все равно приходят. Также заметил такую особенность: при выключении устройства в порт приходит куча цифр, всегда разных. А вот при включении стабильно приходит строка 02550. Значит проблема кроется в неправильных запросах. Попробовал разные варианты и контрольную сумму добавлял к запросу. Результат тот же - в ответ нули.
Скажите пожалуйста какой именно модбас вы пытаетесь реализовать ? ModBus RTU ?
Что вы делаете строкой 44 ? В каком виде данные должны уходить на устройство ?
Брукли, похоже, что это ModBus \N
Это как это ?
Прошу прощения, это плоды моих вчерашних полуночных извращений над кодом. Забрыл вернуть как было.
Намек про Serial.print() тоже понял, исправил.
Поигрался еще с передачей команды с компьютера, заметил что терминал все-таки добавляет контрольную сумму к пакету. Я тоже добавил.
#include <SoftwareSerial.h> byte SendData[12]; unsigned long lastMillis; #define DE_RE_PIN 7 // The pin controlling Recieve Enable and Driver Enable on the RS485 adapter #define RX_PIN 5 // to R0 on RS485 adapter #define TX_PIN 4 // to DI on RS485 adapter SoftwareSerial modbusSerial(RX_PIN, TX_PIN); void setup() { pinMode(DE_RE_PIN, OUTPUT); Serial.begin(115200); modbusSerial.begin(115200); lastMillis = millis(); //3.7.5 Sub-function 32 (0x20) Read firmware version SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x20; //Sub-function code SendData[3] = 0x13; //checksum SendData[4] = 0xB8; //checksum //3.7.4 Sub-function 06 (0x06) Set communication settings /*SendData[0] = 0x01; //Address SendData[1] = 0x46; //Function code SendData[2] = 0x06; //Sub-function code SendData[3] = 0x00; //Reserved SendData[4] = 0x06; //Baud Rate SendData[5] = 0x00; //Reserved SendData[6] = 0x00; //Reserved SendData[7] = 0x00; //Reserved SendData[8] = 0x01; //Mode SendData[9] = 0x00; //Reserved SendData[10] = 0x00; //Reserved*/ } void loop() { if (millis() - lastMillis >= 5000) { digitalWrite(DE_RE_PIN, HIGH); for (byte i = 0; i < 5; i++) { modbusSerial.write(SendData[i]); delay(10); } modbusSerial.flush(); digitalWrite(DE_RE_PIN, LOW); Serial.println("-------"); lastMillis = millis(); } //modbusSerial.listen(); while (modbusSerial.available()) { Serial.print(modbusSerial.read()); } }Результат не изменился
Это как это ?
Ну, когда дело до println() дойдет - поймёшь ))
Вы бы описание своего протокола показали бы.
Это как это ?
Это ты про двоеточее ?
kost82, я бы на вашем месте давно прицепился к концам осциллографов или лог.анализатором. С такой ардуиной тыкаться наугад можно только при избытке свободного времени.
Это как это ?
Это ты про двоеточее ?
Я про \n, который передает println(). Дело явно в ту сторону двигалось.
Устройство отдает данные при подключении и отключении, причем при подключении стабильно одно и то же приходит. Я думаю, что с ловлей ответов проблем нет. Проблема с отправкой запроса ИМХО.
Ну ты блин изъясняешься.... Переводом строки оканчивается пакет ModBus ASCII, но тогда пакет должен начинаться с двоеточия. Но имхо тут не в том причина. Однозначно нужен осциллограф. Скорее всего у ТС китайский модуль max485 уже сгорел.
Устройство отдает данные при подключении и отключении, причем при подключении стабильно одно и то же приходит. Я думаю, что с ловлей ответов проблем нет. Проблема с отправкой запроса ИМХО.
Что значит "отдает" ?
Так вот лог.анализатор, прицепленный к UART девайса и покажет - приходит ли ему правильный пакет, отвечает ли он в принципе на запрос. Недокументированные мусор при старте ещё ни о чем не говорит на данном этапе.
Устройство отдает данные при подключении и отключении, причем при подключении стабильно одно и то же приходит. Я думаю, что с ловлей ответов проблем нет. Проблема с отправкой запроса ИМХО.
Что значит "отдает" ?
В мониторе порта при подаче питания на устройство я вижу цифры 02550 каждый раз
Не очень то оно поможет, потому что нужно вовремя переключать направление передачи, а анализатор сам этого не сделает.