• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ModBus RTU (RS-485)

pvvx

Активный участник сообщества
PS cам занимаюсь АСУ ТП (DeltaV от Emerson) и пока не встречал применений, где нужен высокоскоростной modbus. обмена раз в секунду обычно хватает.
Это не отменяет переполнения TCP при отправке/приеме пакетов в режиме сниффера на линии RS-485.
Что вас всех тянет делать всё кое-как, в несоответствии хоть с какими стандартами?
Надо стремиться чтобы работало в любых условиях и обрабатывало любую ситуацию, а не вылетало на перезагруз и не пенять на другую сторону, перенося все проблемы на неё:
боюсь сказать глупость, но первый вопрос (если речь о макрософтовской реализации стека) - https://support.microsoft.com/en-us/kb/328890 не поможет?
Не полезет пользователь в реестр, тем более это дело с задержкой прижилось и распространилось по всем системам и в микрософте есть и системная функция переключения, доступная ПО (программы лезущие к ней тоже патчить? :) )
Беда в LwIP - у него нет функции передачи блоков из одного стека. Т.е. это надо лезть в его потроха... почти реализуя собственный TCP стек. Но тогда может "возрадоваться" половина ПО, которая писана кое-как.
Короче - обложили со всех сторон, особенно писаки стандарта Modbus TCP - это вообще шедевр :) Там постоянно какой-то "Вася" должен заботиться и следить чтобы дело не пошло в сторону сотни условий не входящих в стандарт и пущенных на самотек...
 
Последнее редактирование:

Dmitry P

New member
Это не отменяет переполнения TCP при отправке/приеме пакетов в режиме сниффера на линии RS-485.
Что вас всех тянет делать всё кое-как, в несоответствии хоть с какими стандартами?
Надо стремиться чтобы работало в любых условиях и обрабатывало любую ситуацию, а не вылетало на перезагруз и не пенять на другую сторону, перенося все проблемы на неё:
Тут скорее вопрос компромисса между коммерцией и инжинирингом. Чтобы сделать "работало в любых условиях и обрабатывало любую ситуацию" нужно времени вагон на разработку и самое главное, тестирование. И если несколько лет тестировать (к примеру, у крупных производителей АСУ ТП каждый релиз системы тестируется десятки тысяч человеко-часов) без выпуска в production - то такая контора быстро вылетит в трубу. Поэтому и выпускают, а потом патчи, фиксы, workarounds и т.д.
Но, в оправдание :) , могу сказать, что наш modbus rtu работает с десятками других контроллеров ГОДАМИ без сбоев. Это только то, что я лично пускал и знаю :)
Конечно, я работаю на другом уровне - прикладном и TCP пакеты, переполнение буферов в обычной работе не вижу.
Не полезет пользователь в реестр, тем более это дело с задержкой прижилось и распространилось по всем системам и в микрософте есть и системная функция переключения, доступная ПО (программы лезущие к ней тоже патчить? :) )
Беда в LwIP - у него нет функции передачи блоков из одного стека. Т.е. это надо лезть в его потроха... почти реализуя собственный TCP стек. Но тогда может возрадоваться половина ПО, которая писана кое-как.
Ну тогда нормально решения первого вопроса нет. Как можно без вмешательства в настройки стека изменить его параметры?
С другой стороны, если делать высокоскоростной modbus - то это спец.применение и квалификация того, кто будет использовать такое решение должна предполагать способность импортировать .reg файл.
 

pvvx

Активный участник сообщества
Конечно, я работаю на другом уровне - прикладном и TCP пакеты, переполнение буферов в обычной работе не вижу.
Возьмите простейший пример. 115200 Baud по спецификации один пакет это 0.00175 сек пауза + 8*11/115200 сек запрос/ответ одной ячейки. Итого 1/0.002514 = 397.772474 пакетов в секунду. Проверьте на своем устройстве :)
Предположим, это мастер на шине передает всем изменение N-ной переменной. А так, как ответа быть от устройств в данном случае (адрес = 0) не должно, то ваше устройство обязано принять и обработать все эти 397 изменений.
Так-же попробуйте задать такую программу передачи с таким трафиком в ПЛК. Когда найдете тот, который это отработает, то составьте список этих устройств :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
А что будет прецедентом? :)
Вот ещё мелкий вопрос:
Данные флаги выставляются на весь фрейм в rx fifo UART ESP8266 или возникают каждый раз и сбрасываются приемом следующего байта?
UART_BRK_DET, UART_RXFIFO_OVF, UART_FRM_ERR, UART_PARITY_ERR
Т.е. конкретнее - эти сигналы (какой и как) маскируются маской в регистре UARTx_INT_ENA и/или всё равно выставляются в UARTx_INT_RAW до сброса их через UARTx_INT_CLR?
А то уже замучался тестить UART ESP8266 на все варианты, но эти тесты следующие и не охота время тратить, если уже кем проверено. И так уже много выужено, чтобы реализовать rs-485...
 

sharikov

Active member
115200 Baud по спецификации один пакет это 0.00175 сек пауза + 8*11/115200 сек запрос/ответ одной ячейки. Итого 1/0.002514 = 397.772474 пакетов в секунду. Проверьте на своем устройстве :)
Предположим, это мастер на шине передает всем изменение N-ной переменной. А так, как ответа быть от устройств в данном случае (адрес = 0) не должно, то ваше устройство обязано принять и обработать все эти 397 изменений.
Таких скоростей и темпов передачи пакетов в практических реализациях нет. Уверен что 90% промышленных модбас устройств от подобных издевательств заглючит. Хотя оно формально стандарту соответствует такой темп передачи пакетов следует рассматривать как dos атаку.
На практике используют обмен на скоростях 9600-19200-38400 с темпом единицы пакетов в секунду.
 

Dmitry P

New member
Кстати, поправил сейчас реестр и modbus master
Таких скоростей и темпов передачи пакетов в практических реализациях нет. Уверен что 90% промышленных модбас устройств от подобных издевательств заглючит. Хотя оно формально стандарту соответствует такой темп передачи пакетов следует рассматривать как dos атаку.
На практике используют обмен на скоростях 9600-19200-38400 с темпом единицы пакетов в секунду.
Именно так. В промышленных условиях скорости выше 19200 не используем. Связано со многими факторами - длина линий (десятки и сотни метров), помехи от мощного силового оборудования, проблемы с контурами заземления.
Да и просто не надо столько :)
Кстати, и беспроводные автономные решения начинают приходить в промышленность - Wireless HART на основе стека Zigbee. Например, датчик давления работает от батарейки от года до трех лет.
 

Dmitry P

New member
Вот ещё мелкий вопрос:
Данные флаги выставляются на весь фрейм в rx fifo UART ESP8266 или возникают каждый раз и сбрасываются приемом следующего байта?
UART_BRK_DET, UART_RXFIFO_OVF, UART_FRM_ERR, UART_PARITY_ERR
Т.е. конкретнее - эти сигналы (какой и как) маскируются маской в регистре UARTx_INT_ENA и/или всё равно выставляются в UARTx_INT_RAW до сброса их через UARTx_INT_CLR?
А то уже замучался тестить UART ESP8266 на все варианты, но эти тесты следующие и не охота время тратить, если уже кем проверено. И так уже много выужено, чтобы реализовать rs-485...
Вряд-ли кто-то еще настолько глубоко закопался в эту тему, особенно с тестированием...
По поводу маски - вот этот документ не поможет?
 

pvvx

Активный участник сообщества
Вряд-ли кто-то еще настолько глубоко закопался в эту тему, особенно с тестированием...
Уже вчера протестил все эти флаги на большинство комбинаций и последовательностей выставления/снятия при разных условиях... Вопрос полностью снят.
По поводу маски - вот этот документ не поможет?
Нет - я его в начале года и распространял, да и он вложен в пару моих проектов и всё перенесено в uart_register.h
 

pvvx

Активный участник сообщества
Вы сможете однозначно сказать, что такое “пауза в 1.5 символа” в Modbus RTU?
Берем символ 0xff и при 2 стоп битах без четности. На линии rs-485 это выглядит как стартовый бит и далее “тишина” (она-же пауза) в 10 бит. Пауза в 1.5 символа – это 1.5*11 = 16.5 бит тишины.
Значит, если фрейм заканчивается значением 0xFF, то “истечением паузы 1.5 символа” будет считаться место 17-того бита после вывода сигнала старта последнего символа при случае его значения 0xFF? :)
Но это для принимающего устройства анализирующего шину означает, что после вывода последнего символа (или помехи) прошло всего 6 бит тишины, т.е. всего 0.5 символа, а не 1.5 ? Ну и куда эти 10/11-ых символа девать к 1.5 и 3.5 ?
 

pvvx

Активный участник сообщества
Именно так. В промышленных условиях скорости выше 19200 не используем. Связано со многими факторами - длина линий (десятки и сотни метров), помехи от мощного силового оборудования, проблемы с контурами заземления.
Да и просто не надо столько :)
Ну вот - пошли отговорки. А это значит, что ни одно ваше устройство не соответствует стандарту Modbus.
Кстати, и беспроводные автономные решения начинают приходить в промышленность - Wireless HART на основе стека Zigbee. Например, датчик давления работает от батарейки от года до трех лет.
Zigbee - ужасный протокол, хуже чем Modbus из-за глюков и временных параметров (вроде "выпадов" за 20 сек).
Пром. и прогресс не стоит - скорости и кол-во информации для сопровождения процессов постоянно увеличиваются (ещё с начала того веку). Одно значение на один контроллер в секунду не годится даже для работы выключателя лампочки в коридоре. Скорость опроса-анализа-ответа у среднестатистического человека быстрее 0.2 сек. При реакции устройства более этого времени кнопка будет разбита или устройство обзовут тормозом и требуется вещать плакат - "нажал пипу - жди". :p
Это всё так у вас - используете только древнее и устаревшее морально оборудование?
Вы писали, что 4..20mA это “скоростной” интерфейс. :) А 50Гц у нас является основной помехой ... , но любой твердотельный датчик давления в состоянии выдавать полосу изменения давления к 200 Гц. Аналогично и другие датчики. Анализ переходных процессов всегда дает дополнительную пусть даже статистическую информацию о состоянии работающих устройств. Но т.к. у вас оборудование устарело и ограничено анализом в один бит в секунду, то становится ясно, что никого комплексного анализа на нем не ведется и даже не предполагается, не говоря о других вещах... Таких как использование дорогого древнего списанного оборудования со складов из других стран, а не создание своего. Современное исполнение на новых микроконтроллерах/микромодулях и дешевле, и в тысячи раз производительнее. А уж на чем, кем и как сделано определяет его надежность... а не заморской лейбой.
С Modbus мучаюсь только из-за того, что существует непреодолимая внешняя сила - безграмотность и невозможность освоения каких либо современных протоколов в АСУ имеющихся заводов на территории России (на вопрос "какой вам нужен интерфейс?" - тупой маркетолог неделями звонит в отдел АСУ и в договоре появится: "Modbus и сухой контакт" :) ) Остальные промежуточные чисто "коммерческие" протоколы можно с успехом выкинуть и использовать сразу совершенно современные, т.к. если уж пошли на новое (послав учиться работников AСУ), то зачем вляпываться в это устаревшее промежуточное ...
 
Последнее редактирование:
  • Like
Реакции: Alex

Dmitry P

New member
Ну вот - пошли отговорки. А это значит, что ни одно ваше устройство не соответствует стандарту Modbus.
ну не то, что бы отговорки - это реальная жизнь.
Zigbee - ужасный протокол, хуже чем Modbus из-за глюков и временных параметров (вроде "выпадов" за 20 сек).
Ну он и стоит на тех применениях, где экономия на кабеле важнее детерменированности..
Пром. и прогресс не стоит - скорости и кол-во информации для сопровождения процессов постоянно увеличиваются (ещё с начала того веку). Одно значение на один контроллер в секунду не годится даже для работы выключателя лампочки в коридоре.
Ну так по одному значению и не передаем, а сразу два десятка регистров :)
Скорость опроса-анализа-ответа у среднестатистического человека быстрее 0.2 сек. При реакции устройства более этого времени кнопка будет разбита или устройство обзовут тормозом и требуется вещать плакат - "нажал пипу - жди". :p
Так мы modbus и не используем для таких целей. Сухой контакт, 4-20 обрабатываются напрямую контроллерами гораздо быстрее :). Для DeltaV (та система, которая для нас базовая) цикл обработки модулей управления в зависимости от области применения (ПАЗ или РСУ) находится в диапазоне от 50 ms до 10 секунд. И одновременно контроллер обрабатывает от 750 параметров и выше. Modbus мы используем для связи с локальными системами управления комплектным оборудованием и вывода данных для оператора. Никакие критичные вещи через модбас не передаем в силу уже озвученных причин.
Это всё так у вас - используете только древнее и устаревшее морально оборудование?
Правильнее написать "проверенное временем и имеющее оптимальное соотношение "цена-качество" :)
Вы писали, что 4..20mA это “скоростной” интерфейс. :) А 50Гц у нас является основной помехой ... , но любой твердотельный датчик давления в состоянии выдавать полосу изменения давления к 200 Гц. Аналогично и другие датчики. Анализ переходных процессов всегда дает дополнительную пусть даже статистическую информацию о состоянии работающих устройств.
Но т.к. у вас оборудование устарело и ограничено анализом в один бит в секунду, то становится ясно, что никого комплексного анализа на нем не ведется и даже не предполагается, не говоря о других вещах...
Не совсем так. Как скорость внешнего интерфейса будет влиять на анализ переходных процессов? Практически всё современное промышленное полевое оборудование (датчики давления, температуры, расхода, уровня, исполнительные механизмы) имеют внутри себя мощные микроконтроллеры и кучи алгоритмов. Как для анализа внутреннего состояния датчика, так и для анализа переходных процессов. А уже обработанная информация может передаваться цифрой (HART, Foundation Fieldbus, Profibus, Ethernet) на АСУ ТП. Например, датчик давления Rosemount 3051 умеет по шумам на сенсоре давления определять будущую закупорку линии с продуктом и заранее предупреждать об этом.

Таких как использование дорогого древнего списанного оборудования со складов из других стран, а не создание своего. Современное исполнение на новых микроконтроллерах/микромодулях и дешевле, и в тысячи раз производительнее.
могу сказать, что без современной элементной базы сейчас не обходится ни один датчик. Какая древняя списанная элементная база позволит сделать датчик давления с потреблением 3,6 мA максимум, из которых чувствительный тензоэлемент "кремний на сапфире" жрет 1 мА, ЖКИ индикатор - еще 1 мА, т.е. на все преобразования, расчеты, интерфейс с пользователем, обработку HART, термокомпенсацию - остаётся 1,6 мА? на MCS51 такое не сделать :)

А уж на чем, кем и как сделано определяет его надежность... а не заморской лейбой.
Надежность определяется количеством времени, затраченным на тестирование и работу над ошибками. Заморские лейблы на тестирование тратят на порядки больше времени, чем отечественные. Отсюда и закономерный итог - где наши приборы и системы и где заморские.
С Modbus мучаюсь только из-за того, что существует непреодолимая внешняя сила - безграмотность и невозможность освоения каких либо современных протоколов в АСУ имеющихся заводов на территории России (на вопрос "какой вам нужен интерфейс?" - тупой маркетолог неделями звонит в отдел АСУ и в договоре появится: "Modbus и сухой контакт" :) ) Остальные промежуточные чисто "коммерческие" протоколы можно с успехом выкинуть и использовать сразу совершенно современные, т.к. если уж пошли на новое (послав учиться работников AСУ), то зачем вляпываться в это устаревшее промежуточное ...
В промышленности так нельзя, слишком много тянет за собой всего. Зачем собственнику такие риски и что он получает взамен? Мало кто хочет становиться полигоном. Собственнику нужно, чтобы продукция выпускалась, а не чтобы киповцу или асушнику хорошо было :)
Мы пытаемся продвигать новые технологии на так называемых greenfield - новых объектах. Иногда получается, иногда - нет. Тот же HART очень хорош для модернизаций заводов - позволяет не ломать существующую инфраструктуру, а помаленьку приучать народ к цифре. Хотя бы к тому, что можно приборы настраивать не в поле, а в операторной. А там уж и до других плюшек доберутся. А собственнику поются песни о сокращении простоев и снижению издержек на приборный парк.
 

Dmitry P

New member
Согласно раздела 2.5.1 документа понятие character имеет размерность 4 бита. ...When devices communicate on a MODBUS serial line using the RTU (Remote Terminal Unit) mode, each 8–bit byte in a message contains two 4–bit hexadecimal characters... :)

Вы сможете однозначно сказать, что такое “пауза в 1.5 символа” в Modbus RTU?
Интервал t1.5 является межсимвольным и используется для детектирования ошибок внутри фрейма - If a silent interval of more than 1.5 character times occurs between two characters, the message frame is declared incomplete and should be discarded by the receiver. Кроме того, в документе прописано жесткое условие по детекту именно межсимвольного интервала - Partial messages must be detected and errors must be set as a result.
в этом же документе в разделе 2.5.1.1 In RTU mode, message frames are separated by a silent interval of at least 3.5 character times. In the following sections, this time interval is called t3,5
т.е. t3,5 служит для разделения фреймов. Далее он так и называется - inter-frame delay (t3.5)

Берем символ 0xff и при 2 стоп битах без четности. На линии rs-485 это выглядит как стартовый бит и далее “тишина” (она-же пауза) в 10 бит.
а разве 0xFF будет тишиной? там же вроде в двоичной 1111 1111?

Пауза в 1.5 символа – это 1.5*11 = 16.5 бит тишины.
Значит, если фрейм заканчивается значением 0xFF, то “истечением паузы 1.5 символа” будет считаться место 17-того бита после вывода сигнала старта последнего символа при случае его значения 0xFF? :)
А сигнал старта вроде один для всего фрейма? Или Вы рассматриваете ситуацию с одним байтом во фрейме?
Но это для принимающего устройства анализирующего шину означает, что после вывода последнего символа (или помехи) прошло всего 6 бит тишины, т.е. всего 0.5 символа, а не 1.5 ? Ну и куда эти 10/11-ых символа девать к 1.5 и 3.5 ?
PS Еще глупый вопрос - понятие тишины (silence) для дифференциальной линии rs-485 - эквивалентно логическому нулю? т.е. 485 не различает логический ноль и тишину? Между двумя проводами витой пары всегда есть разность потенциалов при «1» она положительна, при «0» — отрицательна. А при тишине что на проводах?
 

pvvx

Активный участник сообщества
Согласно раздела 2.5.1 документа понятие character имеет размерность 4 бита. ...When devices communicate on a MODBUS serial line using the RTU (Remote Terminal Unit) mode, each 8–bit byte in a message contains two 4–bit hexadecimal characters... :)
Ну и ? Где же суть? От куда считается "1.5 символа тишины" или "3.5" ? (Пусть будет точка t0 в Figure 13 из вами указанного дока :) т.е. она содержит ошибку, т.к. невозможно при выходе на линию узнать точку отсчета паузы и нельзя при старте выдать сообщение через интервал 3.5 символа. Необходимо добавить те пресловутые 10/11 символа и описать как определяется помеха на линии. Если принята помеха в виде импульса - это считать целым символом? Т.е. вести отсчет от неё как 3.5+10/11 символа для следующей передачи? Или как вздумается? В modbus ещё много ляп, т.к. это пром.стандарт, как и все указанные вами. Пром.стандарт - это стихийно сформированный стандарт, часто ставший применимым по итогам сложившейся ситуации с выпуском устройств применяющих его. К примеру CAN - это специально разработанный стандарт и не имеет такого кол-ва ляп, как modbus и прочие... )
А сигнал старта вроде один для всего фрейма? Или Вы рассматриваете ситуацию с одним байтом во фрейме?
Для каждого символа.
понятие тишины (silence) для дифференциальной линии rs-485 - эквивалентно логическому нулю?
Для шины нет понятия "0" или "1". Есть понятие активного состояния.
Но у нас по шине (хоть 485, как токовой) передаются символы UART. У них стартовый бит у символа является "активным". Стоп - "не активным". Промежуточные, биты данных, могут кодироваться любым состоянием, и передаваться вперед младшим или старшим битом. Т.е. всё равно имеем 0x00 или 0xff которые будут передаваться неактивным состоянием шины. А далее уже конкретика как передается символ в стандарте... Для modbus rtu указано - обычно 11 бит. 1 старт + 8 данных + 2 стопа или 1 стоп с 1 четностью. (Figure 10 и Figure 11 из вами указанного дока).
PS: Странно это - гоните рекламу чужому оборудованию, даже не проверив его :)
Существуют алгоритмы, которые не приводят к ошибкам и не требуют долгих тестов. Так что не стоит рекламировать кривые системы управления.
Modbus не имеет подтверждения доставки сообщения и ни какой гарантии вообще о передаче данных. Это можно сделать только в протоколе уровнем выше, но временные параметры modbus не позволяют использовать и это в разумном временном интервале. По этому он и прижился - народ всегда выбирает наихудшие из имеющихся вариантов (закон природы).
А уже обработанная информация может передаваться цифрой (HART, Foundation Fieldbus, Profibus, Ethernet) на АСУ ТП.
Что вас тянет на особо платные протоколы и ещё самые тормозные?
HART - платная документация, 1200 бод, теор. максимум 120 байт в сек. Нагромождение на имеющийся интерфейс, как и modbus -> куча глюков и сотни переизданий стандарта (и будут ещё, как и у modbus, т.к. составляли кое как и не думали). Принцип передачи как запись на кассеты у первого народного ПК Синклера :)
Foundation Fieldbus - платная документация, в основном надстройка над проводным Ethernet и то, устаревшей скоростной группы.
Profibus - тут вообще можно много лет ржать :)
Про это и говорил, что их надо просто забыть и использовать нормальные, безглючные шины и протоколы. К ним, из проводных, относятся такие как CAN и Ethernet (уже отлаженный вдоль и поперек). Но только не CAN Open - это опять очередная попытка из одного сделать другое... :) (Modbus - есть попытка переложить телетайп c RS-232 с его десятком проводных сигнальных линий во временные интервалы, оставив RX-TX, но по пути безграмотного переложения забыв пару сигналов :))
На большие расстояния по проводу существуют модемные протоколы с автоопределением скорости, простой и сложной (квадратурной и т.д. модуляцией). Из них как всегда выбраны и распространены самые худшие реализации. Причина проста - продать только своё устройство, чтобы было несовместимо с другими.
Но даль-провод отживает последние годы... из-за цены провода :)
 
Последнее редактирование:

Dmitry P

New member
Ну и ? Где же суть? От куда считается "1.5 символа тишины" или "3.5" ?
Насколько понимаю, t1.5 должна отсчитываться после каждого старт-бита каждого символа. Если после приема старт-бита в течение 1.5 символов ничего нет - буфер приема сбрасывается.
(Пусть будет точка t0 в Figure 13 из вами указанного дока :) т.е. она содержит ошибку, т.к. невозможно при выходе на линию узнать точку отсчета паузы и нельзя при старте выдать сообщение через интервал 3.5 символа.
Почему нельзя использовать момент выхода на линию как точку t0 (отсчета паузы) ?
Необходимо добавить те пресловутые 10/11 символа и описать как определяется помеха на линии. Если принята помеха в виде импульса - это считать целым символом?
Если помеха будет соответствовать по параметрам старт-биту и попадет в разрешенный интервал - это будет воспринято как начало character и через 1.5 символа отброшено как неправильный символ и в итоге забракует фрейм.
Если попадет в t1.5 - забракует фрейм, в который попала.
Если попадет в t3.5 - фрейм закончится не начавшись.
Т.е. вести отсчет от неё как 3.5+10/11 символа для следующей передачи? Или как вздумается?
не смешивается ли в одну кучу интервалы t1.5 и t3.5? Разве интервал t3.5 не должен отсчитываться перед\после приема всего фрейма?
Прошло t3.5 -> ждем старт-бита. Дождались старт-бита, принимаем символ. Если во время приема символа возникла ошибка t1.5 - отбрасываем и символ и фрейм, ждем t3.5 снова.
Если всё нормально -> принимаем следующий символ. Приняли фрейм без t1.5 ошибок -> ждем t3.5 и следующего фрейма.

PS: Странно это - гоните рекламу чужому оборудованию, даже не проверив его :)
ну почему же чужому? :) :) :) Пишу про то, с чем работаю сам в Emerson, рекламы стараюсь избегать. Занимаюсь внедрением АСУ ТП с 2004 года.
Бывший инженер АСУ ТП, сейчас - руководитель проектов.
Существуют алгоритмы, которые не приводят к ошибкам и не требуют долгих тестов. Так что не стоит рекламировать кривые системы управления.
я имел в виду тестирование не столько самих алгоритмов, а их реализации и взаимодействия с другими компонентами.
По поводу кривости - вопрос больше философский. Система свои заявленные функции (например, гарантированное время отклика, наработка на отказ) выполняет? Выполняет. Почему она кривая?
Modbus не имеет подтверждения доставки сообщения и ни какой гарантии вообще о передаче данных. Это можно сделать только в протоколе уровнем выше, но временные параметры modbus не позволяют использовать и это в разумном временном интервале. По этому он и прижился - народ всегда выбирает наихудшие из имеющихся вариантов (закон природы).
Что вас тянет на особо платные протоколы и ещё самые тормозные?
Наверно потому, что как минимум два из них - HART и Foundation Fieldbus были инициированы Emerson :)
HART - платная документация, 1200 бод, теор. максимум 120 байт в сек. Нагромождение на имеющийся интерфейс, как и modbus -> куча глюков и сотни переизданий стандарта (и будут ещё, как и у modbus, т.к. составляли кое как и не думали). Принцип передачи как запись на кассеты у первого народного ПК Синклера :)
Зато позволяет использовать современные датчики (удаленная диагностика и конфигурирование) в старых РСУ и существующую кабельную инфраструктуру. А так, да - HART - тормоз.
Foundation Fieldbus - платная документация, в основном надстройка над проводным Ethernet и то, устаревшей скоростной группы.
для промышленной автоматизации FF - это был прорыв. Общая шина, легкость конфигурирования, перенос алгоритмов управления в сами приборы - на тот момент это было круто. Особенно когда можно было удаленно клапан диагностировать. Невысокая скорость - 31.25 кбайт\с, но зато расстояния до 2 км., искробезопасные применения. Понятно, что есть и недостатки, куда без них. Но с точки зрения пуско-наладки - просто конфетка.
Profibus - тут вообще можно много лет ржать :)
Мне сложно говорить, работал с ними мало - но на практике, в условиях 10 кВ распредщитов на оптике все работало идеально - был Profibus DP.
Про это и говорил, что их надо просто забыть и использовать нормальные, безглючные шины и протоколы.
А в большинстве применений это просто не нужно.
К ним, из проводных, относятся такие как CAN и Ethernet (уже отлаженный вдоль и поперек).
Да, да. Особенно хорош Ethernet своим гарантированным временем доставки пакета :)
Причина проста - продать только своё устройство, чтобы было несовместимо с другими.
В части цифры - частично соглашусь. Каждый из крупных вендоров старается "подсадить" заказчика на своё железо и сервис. На и у нас и у и других вендоров есть куча оборудования с протоколами конкурентов.
Но даль-провод отживает последние годы... из-за цены провода :)
только не у нас :)
 
Последнее редактирование:

Прапор

New member
pvvx, 99% оборудования не умеет работать на "сверхзвуковых" скоростях и на практике скоростей выше 19200/38400 обычно не нужно (частенько , высокие скорости только всё портят). И зачем Вам строгое соответствие спецификации MODBUS ? Покажите мне хоть один промышленный прибор, который 100% реализует все эти интервалы/задержки т.д.? Текущий вариант прошивки TCP2UART вполне работоспособен для частного использования (в коммерческих целях вряд ли кто-нибудь решиться менять витую пару на изначально ненадёжный ВайФай) . Если нужен "беспроводной Модбас", то обычно применяем модемы на 433 МГц и , изредка, GPRS-удлинители СОМ-портов (это больше от безвыходности, ибо тоже то ещё глюковище). 5 запрос/ответов в секунду в текущей реализации - это более чем хороший показатель ;).
 

pvvx

Активный участник сообщества
pvvx, 99% оборудования не умеет работать на "сверхзвуковых" скоростях и на практике скоростей выше 19200/38400 обычно не нужно (частенько , высокие скорости только всё портят). И зачем Вам строгое соответствие спецификации MODBUS ? Покажите мне хоть один промышленный прибор, который 100% реализует все эти интервалы/задержки т.д.?
Есть такие - со спец UART или дополнительными счетчиками (тут бывает разная реализация).
Текущий вариант прошивки TCP2UART вполне работоспособен для частного использования (в коммерческих целях вряд ли кто-нибудь решиться менять витую пару на изначально ненадёжный ВайФай) .
В TCP2UART нет ожидания паузы и разграничения сообщений на пакеты, что требует Modbus TCP. Я пробовал менять алгоритм имеющейся в TCP2UART на это, но возникают доп. проблемы, которые не обойти. Т.е. не сделать совмещения простого TCP2UART и нарезки сообщений по принципу modbus.
Если нужен "беспроводной Модбас", то обычно применяем модемы на 433 МГц и , изредка, GPRS-удлинители СОМ-портов (это больше от безвыходности, ибо тоже то ещё глюковище). 5 запрос/ответов в секунду в текущей реализации - это более чем хороший показатель ;).
Я не собираюсь делать 100% modbus rtu для всех случаев на ESP8266. Будет упрощено до анализа всего одной задержки и полудуплексным режимом приема/передачи - это достаточно для связи с стандартным оборудованием. Но скорость выше, вплоть до 1 Мегабита нужна для этого-же интерфейса, когда он используется для локальной связи чип ESP8266 - другой чип. Не делать же сотни разновидностей драйверов.
По данному вопросу отладка и проработка уже находится на уровне выше - разборке пакетов и создания очереди, по типу полноценного драйвера блочных передач, работающего по событиям. Остальное уже как-то проработал и упростил до подходящего предела (чтоб код был мал и т.д.). Но нет времени на всё - есть другие задачи, по тому и тормоз.
К примеру необходимо иметь возможность управления таким минимумом в низком уровне драйвера:
bool rs485_init(uint32 baud, uint32 parity, uint32 pin_ena, bool flg, bool swap)
Где - pin_ena - это номер GPIO доп. пина, переключающего направление шины аппаратного драйвера RS-485. При номере более 15 - не используется.
Swap - это переключение RX<->CTS, TX<->RTS используемых у ESP8266 пинов для работы
flg - использовать стандартные задержки modbus rtu на больших скоростях (1.75 ms) или тайм-аут в 4 символа.
Драйвер выдает события - пакет принят, вышел таймаут приема, пакет передан (для задания следующего, если гоним одни передачи всем устройствам).
Так-же имеет функции - отослать пакет с ожиданием вставки (анализом когда можно начать передачу для исключения коллизии).
Ну этот уровень драйвера уже отлажен и пашет (до 5 Мегабит - более не рассчитываю). Далее стыковка с остальным и частичная модификация его под нужды слияния.
Так-же учитывается, что шина RS-485 может быть не нужна, если соединение контроллеров локальное, по одному проводу. Тогда соединяем у чипа входы/выходы RX-TX и через резистор (защиту от коллизии) тянем на другой чип.
На политику Arduino - делать лишбы как-то работало, всё равно меня не сломите. Всё равно буду пытаться выудить максимум.
 
Последнее редактирование:

Dmitry P

New member
Есть такие - со спец UART или дополнительными счетчиками (тут бывает разная реализация).
В TCP2UART нет ожидания паузы и разграничения сообщений на пакеты, что требует Modbus TCP. Я пробовал менять алгоритм имеющейся в TCP2UART на это, но возникают доп. проблемы, которые не обойти. Т.е. не сделать совмещения простого TCP2UART и нарезки сообщений по принципу modbus.
Я не собираюсь делать 100% modbus rtu для всех случаев на ESP8266. Будет упрощено до анализа всего одной задержки и полудуплексным режимом приема/передачи - это достаточно для связи с стандартным оборудованием. Но скорость выше, вплоть до 1 Мегабита нужна для этого-же интерфейса, когда он используется для локальной связи чип ESP8266 - другой чип. Не делать же сотни разновидностей драйверов.
По данному вопросу отладка и проработка уже находится на уровне выше - разборке пакетов и создания очереди, по типу полноценного драйвера блочных передач, работающего по событиям. Остальное уже как-то проработал и упростил до подходящего предела (чтоб код был мал и т.д.). Но нет времени на всё - есть другие задачи, по тому и тормоз.
Не планируете разделить функциональность на две части - собственно "физика" RS-485 и Modbus RTU?
Возможно ли будет использовать устройство как" прозрачный мост\удлинитель" RS-485, возложив задачу контроля временных интервалов на мастера и слейва?

Ну этот уровень драйвера уже отлажен и пашет (до 5 Мегабит - более не рассчитываю). Далее стыковка с остальным и частичная модификация его под нужды слияния.
Так-же учитывается, что шина RS-485 может быть не нужна, если соединение контроллеров локальное, по одному проводу. Тогда соединяем у чипа входы/выходы RX-TX и через резистор (защиту от коллизии) тянем на другой чип.
На политику Arduino - делать лишбы как-то работало, всё равно меня не сломите. Всё равно буду пытаться выудить максимум.
Не в коем случае не пытаемся сломить! Именно за стойкость к политике Arduino мы Вас и ценим :)
 

Semicon

New member
Вы сможете однозначно сказать, что такое “пауза в 1.5 символа” в Modbus RTU?
Берем символ 0xff и при 2 стоп битах без четности. На линии rs-485 это выглядит как стартовый бит и далее “тишина” (она-же пауза) в 10 бит. Пауза в 1.5 символа – это 1.5*11 = 16.5 бит тишины.
Значит, если фрейм заканчивается значением 0xFF, то “истечением паузы 1.5 символа” будет считаться место 17-того бита после вывода сигнала старта последнего символа при случае его значения 0xFF? :)
Но это для принимающего устройства анализирующего шину означает, что после вывода последнего символа (или помехи) прошло всего 6 бит тишины, т.е. всего 0.5 символа, а не 1.5 ? Ну и куда эти 10/11-ых символа девать к 1.5 и 3.5 ?
Зашел случайно, тема интересная, т.к. сам не так давно вылизал высокоскоростной Modbus RTU на PIC и в принципе все получилось. Выражу свои мысли по поводу, может кому пригодится, может чего нового узнаю.

Итак. По поводу ляпов Modbus RTU, на самом деле в самом протоколе ляпов то и нет, есть неправильное понимание документа и как следствие практическая реализация. Единственный минус самого протокола - отсутствие регламентации на максимальные задержки между пакетами, или хотя бы на строгую необходимость их указании в документации на устройство с заявленным Modbus.

Нюанс №1:
Протокол Modbus RTU очень четко оговаривает: между символами (концом предыдущего и началом нового) не более 1.5 символа, между пакетами не менее 3.5 символа (но по хорошему с 3.5 символами в сети каждое устройство работать обязано, даже если оно само не может отвечать так быстро). И в этом главный подвох: в алгоритме нельзя ждать 3.5 символа и начинать обрабатывать пакет, т.к. через 3.5 символа по протоколу уже допускается новый пакет и нужно быть к нему готовым. Т.е обрабатывать пакет нужно уже через 1.5 символа и это четко указано на Figure 14 Modbus_over_serial_line_V1_02. Там видно, что обработка пакета идет через 1.5 символа, а через 3.5 символа уже нужно быть готовым ждать новый пакет.

Нюанс №2:
На практике возникает проблема высчитать 1.5 символа. Например в PIC в UART есть только прерывание по окончанию приема символа. И он срабатывает в любом случае ровно через 11 бит после получения стартового (неважно был стоповый бит или нет). После успешного приема символа запускаем таймер, но не 1.5 символа, а 2.5 символа, т.к. UART не информирует о приеме стартового бита, только об окончании. Таким образом если через паузу 2.5 символа с момента предыдущего символа UART так и не получил новый символ , то 1.5 символа гарантированно прошло, хоть мы и простояли зря символ, но таков уж UART.

Нюанс №3
После паузы 1.5 символа (а по факту 2.5 символа) нужно переходить к обработке всего пакета. Т.к. через 3.5 символа нужно уже быть готовым к новому пакету, то на обработку пакета и CRC времени остается лишь 1 символ. При 19200 - это 0.573 мс, ну а для скоростей выше 19200 это даже по более 0.714 мс (1.75 мс - (0.75 мс+1 символ)).
За это время вычислить CRC довольно сложно, особенно если пакет большой. Однако стандарт дает простую рекомендацию: сначала проверить адрес устройства в начале пакета, если адрес не наш, обнуляем пакет без проверки CRC и тогда должны успеть до окончания таймера 3.5 символа. А если адрес наш, то можем вычислять CRC хоть 50-100 мс ведь Modbus этого и не запрещает, сеть ведь ждет нашего ответа.
Об этом комментарий №5 под Figure 14: After detection of the end of frame, the CRC calculation and checking is completed. Afterwards the address field is analysed to determine if the frame is for the device. If not the frame is discarded. In order to reduce the reception processing time the address field can be analysed as soon as it is received without waiting the end of frame. In this case the CRC will be calculated and checked only if the frame is addressed to the slave (broadcast frame included).
Итого, правильный Slave Modbus RTU не обязан отвечать быстро, но обязан не пропустить от мастера свой запрос, если параллельно с ним есть быстрые слейвы, которые могут отвечать с задержкой 3.5 символа. По факту, многие слейвы принимают пакет другого слейва и уходят на расчет CRC, а в это время мастер уже шлет следующий запрос именно ему, который тот естественно не принимает или начинает принимать где нибудь в середине.
И проявляется это очень просто - если подключение точка-точка - проблем нет, то как добавляется несколько слейвов - начинаются падения в сети и лечится увеличением задержки мастера на новый запрос.

По поводу помех:
Если была помеха хоть на одном символе, которая, например, исказила стартовый или стоповый бит, то проблем нет - обнуляем весь пакет и снова мгновенно запускаем прием UART с нуля, куски оставшегося сообщения будут неизбежно обнуляться на ошибочных символах, либо в конце пакета по паузе 1.5 символа (это уже маловероятно).
Если помеха (стартовый бит) проникла в паузу 1.5 символа в конце пакета, то если сообщение было нам, то за помехой новых пакетов не будет и будет опять задержка 1.5 символа (и можно даже эту помеху исключить, посчитав CRC без последнего байта). А если после помехи пошел новый пакет, который склеится с предыдущим, то значит это однозначно не нам и мы обнулим склеенный пакет (2-й пакет мог быть конечно адресован нам, но выцеплять его в сообщении долго, проще не ответить).

Таким образом Modbus RTU очень даже и неплохой протокол при грамотной реализации. В наших изделиях мы имеем возможность работать на частотах 230.4 кбод с задержками между пакетами от 0.3 мс (не используя ограничения t3.5=1.75 мс и t1.5=0.75 мс) стабильно обеспечивая до 500 транзакций в секунду без ошибок. Одна проблема - таких быстрых контроллеров на пальцах посчитать.
На практике есть контроллеры которые работают c Modbus RTU на скоростях до 4.5 Mbit т.е. это тот же Modbus RTU но с паузами 3.5 символа на всех скоростях (а не 1.75 мс) . По физике и скоростям такой Modbus RTU ничем не уступает Profibus DP, который работает до 12 Мбит,т.к. тот же RS-485.
 

pvvx

Активный участник сообщества
Зашел случайно, тема интересная, т.к. сам не так давно вылизал высокоскоростной Modbus RTU на PIC и в принципе все получилось.
Да, на PIC24 уже давно всё это было сделано, но пришлось "откатить" до более простой реализации из-за внешних устройств считающих что они работают по описанию, но на деле нет. А в EPS8266 другие проблемки с прерываниями и UART. По этому многое не решить. Из имеющегося аппаратного мы можем полагаться только на счетчик TOUT_INT, считающий паузу по 8 тиков UART от перепада на RX (с полным отсутствием документации про это).
Скоростной расчет CRC никому не нужен. Кладите принятые сообщения в стек и обрабатывайте хоть потом. Тут мы ограничены только размером "heap", чего нет в простейших PIC и других малых MCU. Как итог входит разная реализация и "портирование" описанного вами алгоритма на ESP8266 не катит. Мы не можем обрабатывать прием каждого байта по прерыванию, только скопом из fifo до 128 символов используя прерывание первой паузы от TOUT_INT и второй части паузы (только для передачи) по обычному системному таймеру. Это + анализ ошибок по прерыванию и сделано. Но пока зависло уровнем выше - на распределении событий и обработки приемов-ответов через события задаваемые драйверу с указанием стеков сообщений. Т.е. полноценном драйвере, который автоматически с очередью обрабатывает передаваемые ему блоки и получаемые по шине (сам разбирается когда вставлять ответ и т.д - задал стразу 10 заданий-пакетов и он их отработает согласно протоколу, т.е. он уже является многопользовательским - должен работать к примеру с несколькими одновременно открытыми шлюзами modbus TCP).
И данный низкоуровневый драйвер уже отрабатывает поток до 3Mbit/s (тестирование проходит и на 5Mbit/s) "(не используя ограничения t3.5=1.75 мс и t1.5=0.75 мс) " а используя межсимвольную паузу с джиттером в (N-1)*8..N*8 тиков времени передачи бита, где N - встроенный в UART аппаратный счетчик TOUT_INT от 1 до 127 с компаратором вызывающим прерывание.
Именно из-за его алго работы мы не можем ориентироваться на начало или конец символа, а только на уровень "активность" на RX с шагом данного счетчика по 8 тиков, что в принципе не столь критично.
Для уточнения - TOUT_INT возникает после истечения указанной в UART_RX_TOUT_THRHD паузы на RX. Счетчик синхронизован с генератором UART и тактируется с частотой 8 бит символьной передачи UART, от того внешний сигнал для него является асинхронным. Сброс на начало счета происходит по активному уровню на RX. От этого джиттер в 8 тиков символьной передачи бита для внешнего приемного потока (RX), но синхронными с выходящим (TX). Эти данные не являются точными, т.к. вычислены путем тестов - доков на ESP8266 нет.
Перед передачей через TX fifo и UART_TXFIFO_EMPTY_INT включаете UART_LOOPBACK, направление драйвера RS-485 и TOUT_INT сработает после вывода с указанной в нем паузой. Отключаете UART_LOOPBACK, направление драйвера RS-485 и принимаете до следующего TOUT_INT или заполнения UART_RXFIFO_FULL_THRHD. TOUT_INT будет означать что блок готов. Для начала передачи, если она требуется, придется выждать ещё паузу назначенную уже в таймере после события TOUT_INT и анализируя прием в fifo и ошибки... Это общий алго без учета мелочей. Пишите - алго дан и он уже проверен :)
Возможно задействовать и slc_register-ы, как DMA, но там наблюдается нехватка описания...
 
Последнее редактирование:

serg28serg

New member
Делаю проект типа "сетевой бридж Modbus TCP" c установками по WEB HTTP (и по порту modbus TCP со спец. адресом устройства). В дальнейшем предполагающий расширение на работу ESP8266 как простого ПЛК c панелью оператора по HTTP...
Возьмите простейший пример. 115200 Baud по спецификации один пакет это 0.00175 сек пауза + 8*11/115200 сек запрос/ответ одной ячейки. Итого 1/0.002514 = 397.772474 пакетов в секунду. Проверьте на своем устройстве :)
сколько реально получилось пакетов в секунду, на скорости 115200 к примеру ?
и какая была топология, если дошло до реализации ? PC-WiFiроутер- ESP8266-RTUslave ?
 
Сверху Снизу