Modbus ASCII
- Войдите на сайт для отправки комментариев
Вс, 27/03/2022 - 00:32
Приветствую всех читающих. Хотел организовать связь Arduino UNO (Master) по rs-485. Отправка пакета осуществляется ASCII символами в 16-м виде.
Пример пакета :010600000057A2CRLF. Если правильно понял, то по таблице ASCII символов нужно переделать каждый символ в 16-й вид, получится 3A 3031 3036 3030 3030 3030 3537 4132 0D 0A. Это все разбить в массив и отправить в устройство.
На GitHub нашел библиотеку, с помощью которой вроде можно осуществить отправку (https://github.com/4-20ma/ModbusMaster/blob/master/examples/RS485_HalfDu...), но не понимаю, где в коде вставлять массив с элементами пакета и как его объявлять.
Бессмыслицу какую-то написал. Прочитай документацию modbus.
Отправка пакета осуществляется ASCII символами в 16-м виде.
Высказывание, изобличающее вас как самого зеленого новичка, причем даже не в программировании, а в элементраной компьютерной грамотности.
Запомните, компьютеру абсолютно все равно, в каком виде вы запишите в своем скетче ASCII символы - как символы или как коды - в десятичном, двоичном или шестнадцатиричном виде... Ничего специально преобразовывать не нужно, записи '0', 0x30 и 48 - абсолютно эквивалентны.
нигде
Если вы работаете через библиотеку - вам не нужно формировать пакеты Модбас самому, вы задаете только данные. Разберитесь, как работает тот пример, который вы цитируете
Эта библиотека под Modbus RTU.
"This is an Arduino library for communicating with Modbus slaves over RS232/485 (via RTU protocol)."
Причем она с блокировкой с момента начала передачи, до получения ответа или окончания таймаута ожидания приема. Таймаут по умолчанию 2 сек!!!
Если вам нужен Modbus ASCII нужно искать другую библиотеку.
Отправка пакета осуществляется ASCII символами в 16-м виде.
Высказывание, изобличающее вас как самого зеленого новичка, причем даже не в программировании, а в элементраной компьютерной грамотности.
Запомните, компьютеру абсолютно все равно, в каком виде вы запишите в своем скетче ASCII символы - как символы или как коды - в десятичном, двоичном или шестнадцатиричном виде... Ничего специально преобразовывать не нужно, записи '0', 0x30 и 48 - абсолютно эквивалентны.
Может я неправильно выразился, но вот полный текст из спецификации:
"Пример отправки пакета с требованием установить мощность 87% на устройстве с 01 адресом. Выбор адреса осуществляется перемычками на корпусе устройства в соответствии с таблицей.
:010600000057A2CRLF
(значение необходимо передавать в шестнадцатеричном виде стандартными ASCII символами, т. е. значению 0x57 (один байт информации) придется два символа 5 и 7 (4 байта информации) и будет соответствовать мощность 87%. Для мощности 100% необходимо отправить значение 0x64"
Значит ли это, что мне нужно отправлять данные в таком виде? 0x01 0x06 0x00 0x00 0x00 0x57 0xA2?
Или после подсчета контрольной суммы преобразовать сформированный запрос в Char?
этого не знаю, я ориентировался на процитированную библиотеку, там никакие строчки в HEX не требуются
Нужна библиотека, которая не в MODBUS RTU шлёт пакет, а в MODBUS ASCII. Например: https://github.com/pepsilla/Arduino/tree/master/MODBUS/ASCII/ASCII_RTU
Или после подсчета контрольной суммы преобразовать сформированный запрос в Char?
Нужно сначала посчитать LCR а потом формировать пакет для отправки.
LCR считается по данным до перевода в ASCII и без начального ":".
0x01 0x06 0x00 0x00 0x00 0x57 - это данные для расчета LCR, LCR = 0xA2.
Потом пакет переводится в ASCII, включая контрольную сумму.
Первым идет признак начала пакета символ ":" (0x3A), заканчивается пакет двумя байтами 0x0D,0x0A.
Но пакет и контрольную сумму, по идее, должна сформировать библиотека. Подсказать какую использовать - не смогу, не использовал Modbus ASCII на мастере. Я сейчас дорабатываю библиотеку Modbus RTU master под себя.
Пример пакета :010600000057A2CRLF. Если правильно понял, то по таблице ASCII символов нужно переделать каждый символ в 16-й вид, получится 3A 3031 3036 3030 3030 3030 3537 4132 0D 0A. Это все разбить в массив и отправить в устройство...
Не надо ничего переделывать. Достаточно строку :010600000057A2CRLF отправить через Serial.print(":010600000057A2CRLF"); если конечно ответа не надо.
Пример пакета :010600000057A2CRLF. Если правильно понял, то по таблице ASCII символов нужно переделать каждый символ в 16-й вид, получится 3A 3031 3036 3030 3030 3030 3537 4132 0D 0A. Это все разбить в массив и отправить в устройство...
Не надо ничего переделывать. Достаточно строку :010600000057A2CRLF отправить через Serial.print(":010600000057A2CRLF"); если конечно ответа не надо.
Признак конца пакета "CRLF" должен быть байтами 0x0D, 0x0A (2 байта) а не символами 'C','R','L','F' (4 байта)
Serial.println(":010600000057A2"); Так лучше?
Serial.println(":010600000057A2"); Так лучше?
Да, так пакет будет корректным.
Но если передавать готовый пакет, с заранее посчитанной контрольной суммой, наверное будет правильней:
Serial.print(":010600000057A2\r\n");
А для произвольных значений все равно придется считать контрольную сумму, поэтому придется пакет собирать.
Может я неправильно выразился, но вот полный текст из спецификации:
А теперь покажи, где в спецификации присутствутет слово "MODBUS"
В спецификации нет слов MODBUS, но есть схема, на которой указана связь по RS-485
Нужна библиотека, которая не в MODBUS RTU шлёт пакет, а в MODBUS ASCII. Например: https://github.com/pepsilla/Arduino/tree/master/MODBUS/ASCII/ASCII_RTU
Спасибо за пример. Но автор удалил библиотеку, на которую ссылается в примерах программы, а именно SerialCommand. В общем, скетч не запускается.
Ну так модбас и 485 вещи лежащие совершенно в разных плоскостях. Они конечно могут пересекаться, но совершенно не обязательно.
Ну так модбас и 485 вещи лежащие совершенно в разных плоскостях. Они конечно могут пересекаться, но совершенно не обязательно.
Также тут заданы параметры передачи.
Управление передано блоку RS485. Изменение параметров производится отправкой команд с ПК или ПЛК в виде ASCII символов. Модуль после получения команды модуль отправляет ответ.
Параметры передачи:
Скорость передачи — 9600
Data bits 8
Stop bits 1
Parity — none
Какие по-вашему мнению могут быть другие способы отправки пакета?
"Пример отправки пакета с требованием установить мощность 87% на устройстве с 01 адресом. Выбор адреса осуществляется перемычками на корпусе устройства в соответствии с таблицей.
:010600000057A2CRLF
(значение необходимо передавать в шестнадцатеричном виде стандартными ASCII символами, т. е. значению 0x57 (один байт информации) придется два символа 5 и 7 (4 байта информации) и будет соответствовать мощность 87%. Для мощности 100% необходимо отправить значение 0x64"
Ну а это то откуда вы взяли?
Если из документации к устройству, протокол - Modbus ASCII over RS485.
Нужна библиотека, которая не в MODBUS RTU шлёт пакет, а в MODBUS ASCII. Например: https://github.com/pepsilla/Arduino/tree/master/MODBUS/ASCII/ASCII_RTU
Посмотрел библиотеку, основа та же, что и в https://github.com/jecrespo/simple-modbus
Но от jecrespo чуть постарше, и в ней только RTU. Видимо pepsilla дописывал ASCII к ней.
Я сейчас под себя правлю эту библиотеку (SimpleModbusMaster от jecrespo).
В принципе она норм, без блокировок, написана с использованием конечного автомата.
Какие по-вашему мнению могут быть другие способы отправки пакета?
Передача данного кода 010600000057A2CRLF выглядит так :
Serial.write(0x30);Serial.write(0x31);Serial.write(0x30);Serial.write(0x36);Serial.write(0x30);Serial.write(0x30);Serial.write(0x30);Serial.write(0x30);Serial.write(0x30);Serial.write(0x30);Serial.write(0x35);Serial.write(0x37);Serial.write(0x41);Serial.write(0x32);Serial.write(0x43);Serial.write(0x52);Serial.write(0x4С);Serial.write(0x46);
Копируй, вставляй в свой код, и получай в обратку результат.
Ну так модбас и 485 вещи лежащие совершенно в разных плоскостях. Они конечно могут пересекаться, но совершенно не обязательно.
Также тут заданы параметры передачи.
Управление передано блоку RS485. Изменение параметров производится отправкой команд с ПК или ПЛК в виде ASCII символов. Модуль после получения команды модуль отправляет ответ.
Параметры передачи:
Скорость передачи — 9600
Data bits 8
Stop bits 1
Parity — none
Какие по-вашему мнению могут быть другие способы отправки пакета?
Вот не надо путать тёплое с мягком. Протоколов общения много и они могут работать over 485. При этом есть похожие по содержанию на MODBUS. Если есть в документации точная ссылка на MODBUS, то это одно. А ещё бывает просто частный протокол общения, описанный в документации на устройство. А вот параметры сериальной передачи ни как не могут характеризовать протокол.
SAB, Serial.print("\x30\x31 .... \x0D\x0A");
Согласен, можно и так, но я для топикстартера чтобы понятнее было написал :)