40

Open source Modbus TCP — RTU конвертор

Серия Контроллер интернет вещей AntexGate

Добрый день коллеги, поговорим о прозрачном конверторе Modbus TCP в Modbus RTU.

Казалось бы, что выбор ограничен несколькими проприетарными продуктами которые не всегда удовлетворяют нашим потребностям.

Мы предложим свободно программируемый контроллер AntexGate с помощью которого можно получить конвертер Modbus tcp – Modbus rtu – can – profitnet – bacnet – mqtt – http – opc UA – другой протокол.

Итак, рассмотрим первую связку Modbus TCP – Modbus RTU, нам понадобится сам контроллер AntexGate либо другой компьютер с linux/windows на борту и периферией RS485.

Первое, что необходимо – это установить программный продукт Node-Red, это делается одним скриптом в командной строке:

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/...)

Далее после установки делаем Node-red сервисом:

sudo systemctl enable nodered.service

Перезагружаем железяку:

sudo reboot

Теперь попадаем в среду нашего программного конвертора Node-red через web браузер по ссылке ip шлюза:1880

Далее настроим скрипт, который конвертирует посылку Modbus TCP в RTU, посылает в RS485/232 порт, ждет ответ и тут же преобразует ответ обратно в Modbus TCP.

Заходим в "меню" > "импорт"

Проект конвертора Modbus TCP <> RTU (прошу прощения в пикабу нет спойлера)

[ { "id": "22ff3060.54da6", "type": "function", "z": "de082ac2.4b8bf8", "name": "Convert TCP to RTU", "func": "var MBAPHeader = [5];\nvar crc = 0xFFFF;\n\nMBAPHeader[0]= msg.payload[0];\nMBAPHeader[1]= msg.payload[1];\nMBAPHeader[2]= msg.payload[2];\nMBAPHeader[3]= msg.payload[3];\nMBAPHeader[4]= msg.payload[4];\nflow.set('MBAP_HEADER', MBAPHeader);\n\nvar ReqLen = msg.payload[5];\nvar MBLen = (msg.payload.length)-ReqLen;\nvar MBReq = [MBLen];\n\nfor (let x=0; x < MBLen;x++){\n MBReq[x] = msg.payload[x+ReqLen];\n}\n\nfor (var req = 0; req < ReqLen; req++) {\n crc ^= MBReq[req]; // XOR byte into least sig. byte of crc\n \n for (var i = 8; i !== 0; i--) { // Loop over each bit\n if ((crc & 0x0001) !== 0) { // If the LSB is set\n crc >>= 1; // Shift right and XOR 0xA001\n crc ^= 0xA001;\n } else { // Else LSB is not set\n crc >>= 1; // Just shift right\n }\n }\n}\n\nvar MyCRC = crc.toString(16);\nMBReq[MBLen+1] = parseInt(MyCRC.substring(0,2),16);\nMBReq[MBLen] = parseInt(MyCRC.substring(2,4),16);\n\nvar buf = new Buffer(MBReq);\nmsg.payload = buf;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 300, "y": 100, "wires": [ [ "7e62bbbc.bd8ea4" ] ], "outputLabels": [ "XO" ] }, { "id": "7e62bbbc.bd8ea4", "type": "serial request", "z": "de082ac2.4b8bf8", "name": "", "serial": "27dabad398437b7e", "x": 490, "y": 100, "wires": [ [ "db79ee80.1d792", "9e53f02d0a4e04fb" ] ] }, { "id": "db79ee80.1d792", "type": "function", "z": "de082ac2.4b8bf8", "name": "Convert RTU to TCP", "func": "if (msg.payload.length > 0) {\n var resLen = msg.payload.length - 2;\n var respond = [];\n respond[0] = flow.get('MBAP_HEADER')[0];\n respond[1] = flow.get('MBAP_HEADER')[1];\n respond[2] = flow.get('MBAP_HEADER')[2];\n respond[3] = flow.get('MBAP_HEADER')[3];\n respond[4] = flow.get('MBAP_HEADER')[4];\n respond[5] = resLen;\n\n for (let req = 6; req < resLen+6; req++) {\n respond[req]= msg.payload[req-6];\n }\n msg.payload = new Buffer(respond);\n return msg;\n} else {\n return null;\n}\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 640, "y": 60, "wires": [ [ "2622a1e893f52bed", "140a62f5366490d9" ] ] }, { "id": "55423964225fa869", "type": "comment", "z": "de082ac2.4b8bf8", "name": "Convert Modbus TCP to Modbus RTU", "info": "", "x": 170, "y": 40, "wires": [] }, { "id": "cbd6e86861af643d", "type": "tcp in", "z": "de082ac2.4b8bf8", "name": "Modbus TCP - IN", "server": "server", "host": "", "port": "5002", "datamode": "stream", "datatype": "buffer", "newline": "", "topic": "", "trim": false, "base64": false, "tls": "", "x": 100, "y": 100, "wires": [ [ "22ff3060.54da6", "48471bdeae3a1d30" ] ] }, { "id": "2622a1e893f52bed", "type": "tcp out", "z": "de082ac2.4b8bf8", "name": "Modbus TCP - OUT", "host": "127.0.0.1", "port": "502", "beserver": "reply", "base64": false, "end": false, "x": 850, "y": 100, "wires": [] }, { "id": "9e53f02d0a4e04fb", "type": "debug", "z": "de082ac2.4b8bf8", "name": "debug 17", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 640, "y": 220, "wires": [] }, { "id": "140a62f5366490d9", "type": "debug", "z": "de082ac2.4b8bf8", "name": "debug 18", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 820, "y": 200, "wires": [] }, { "id": "48471bdeae3a1d30", "type": "debug", "z": "de082ac2.4b8bf8", "name": "debug 19", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 260, "y": 200, "wires": [] }, { "id": "27dabad398437b7e", "type": "serial-port", "serialport": "/dev/ttyUSB0", "serialbaud": "115200", "databits": "8", "parity": "none", "stopbits": "1", "waitfor": "", "dtr": "none", "rts": "none", "cts": "none", "dsr": "none", "newline": "5", "bin": "bin", "out": "time", "addchar": "", "responsetimeout": "1000" } ]

Копируем скрипт, нажимаем "Импорт"

Копируем скрипт, нажимаем "Импорт"

Настраиваем порт для просушки в узле Modbus TCP IN, рекомендуем не использовать стандартный 502, а использовать нестандартный порт более 1024, для них не нужны дополнительные разрешения в Linux.

Настраиваем последовательный порт RS485/232 на скорость конечного железа, поддерживающего протокол Modbus RTU.

Жмем "Развернуть" и наш конвертер готов!

Настраиваем Ваш инструмент верхнего уровня, например Modbus TCP OPC сервер стандартно: ip_адре_ шлюза:5002:id_RTU_устройства.

Все работает стабильно, чтение и запись! Посылки как видим между запросом и ответом 100-200мс, что равно пингу. Удаленный шлюз AntexGate работает на встроенном LTE модеме.

Бонусом, для тех, у кого софт верхнего уровня поддерживает функцию Modbus RTU поверх TCP включаем это правило.

В Node-Red упрощаем поток и исключаем функции RTU TCP обработки, и наш проект в Node-Red становится без единой строчки кода.

Контроллер AntexGate в связке с Node-red является отличным универсальным решением для обработки, пересылки и хранения данных. Прошу прощения за рекламу, однако выше представленный проект Вы можете реализовать на любом железе и любой ОС.

Присоединяйтесь к нашему сообществу в Telegram

Железо можно получить на тесты, пишите на почту: info@antexcloud.ru (на три месяца для ЮР лиц и ИП)

Arduino & Pi

1.5K постов20.9K подписчиков

Правила сообщества

В нашем сообществе запрещается:

• Добавлять посты не относящиеся к тематике сообщества, либо не несущие какой-либо полезной нагрузки (флуд)

• Задавать очевидные вопросы в виде постов, не воспользовавшись перед этим поиском

• Выкладывать код прямо в посте - используйте для этого сервисы ideone.com, gist.github.com или схожие ресурсы (pastebin запрещен)

• Рассуждать на темы политики

• Нарушать установленные правила Пикабу

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества