РЕШЕНО Modbus без парсинга и ошибок.

Тема в разделе "Глядите, что я сделал", создана пользователем Алопеций Шнифт, 4 мар 2026.

  1. parovoZZ

    parovoZZ Гуру

    Только лишь надежность. В данном случае протокола. Если говорить про crc, то применяемая база в модбас не выдерживает никакой критики. На кадр в 256 байт всего 2 байта контрольной суммы. Сколько комбинаций можно насобирать с одинаковой контрольной суммой в таком случае - спрашивайте у ии.

    Если в документации к устройству будет указано, что соседний слейв или мастер для него не имеет права выдавать в потоке информации определенную последовательность чисел, то никакого отношения к модбас данное устройство не имеет. В самом протоколе модбас запрещенные последовательности отсутствуют.

    Мастер запросил, слейв собрал дискреты и выдал это для мастера:
    0x5AA5000A1C2D0405

    Твой алгоритм радостно принял и вставил свой ответ. Вообще не разобравшись, что это ответ соседнего слейва мастеру, а не ему.
     
  2. parovoZZ

    parovoZZ Гуру

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

    Вот кадр ответа от слева с адресом 2, отвечает на функцию 3:
    02 03 08 5A A5 00 0A 1C 2D 04 05 94 01
    Прочие устройства, которые в полной мере реализуют протокол, на этот кадр отвечать не будут. Ну просто потому, что это кадр с адресом два. Значит, этот кадр не для нас. Твой же алгоритм понятия не имеет, какой адрес у этого кадра ( паузы мы не отслеживаем, адрес не разбираем и все такое ) и приняв, как ты говоришь, "свой ключ", радостно начнет отвечать. Все. Какие ошибки? Твой алгоритм и есть генератор ошибок. К тому хрен уловимых. Таким устройствам в сети модбас делать нечего. Где-то там обособленно, на своих правилах - пожалуйста.
     
  3. parovoZZ

    parovoZZ Гуру

    Только сейчас заметил.
    Кадр:
    5A A5 00 0A 1C 2D 04 05
    мастер, работающий в сети модбас rtu, никогда такой кадр не сформирует. Поэтому это даже на modbus-based протокол, а вообще что-то свое.
     
  4. Я утверждаю, что такие данные (если это живые данные) в ближайший миллион лет в ключ точно не сложатся.
    Почему?
     
  5. parovoZZ

    parovoZZ Гуру

    Эти данные - упакованные биты (читай - дискреты). И да - это живые данные. Я их включу в юнит тест и этот тест предложенный алгоритм не пройдет. Приемочная комиссия акт не подпишет и устройство вернется производителю.
     
  6. parovoZZ

    parovoZZ Гуру

    Допустим, 5А - это адрес устройства, тогда А5 - код функции. но этот код функции по последней спецификации модбас находится в диапазоне зарезервированных. Максимальный код, доступный для использования - 110. Но там не весь диапазон доступен пользователю. А чаще промышленные мастера вообще владеют только стандартными кодами функций.
     
  7. Не с той стороны смотрите. 0x5AA5 - это crc. Адрес - 0x05. В общем, сдвигать можно в любую сторону, но тут так.
     
  8. В этом случае (только в этом!) поставлю всё же отлавливание задержки. Дело плёвое, и алгоритм практически не изменится. Просто чисто эстетически такое решение не нравится.
     
  9. parovoZZ

    parovoZZ Гуру

    тогда ОК

    а как иначе? Ну т.е. алгоритм для МК какой (для ПЛК он отличается) - спрашиваем у UART - а не занят ли ты? Если ответ да, то сбрасываем таймер. Если нет, то таймер тикает. Либо же, если МК (или CPU) продвинутый и есть прерывание на начало приёма пакета, то таймер останавливаем, а на прерывании полностью принятого (или освобождении занятости UART - что тоже самое) пакета его снова включаем. Как только он оттикал 3.5 бита, опять идём к UART и спрашиваем: занят? Если занят, то снова сбрасываем, если нет, то переходим на подпрограмму ожидания первого байта (таймер можно остановить, но может и тикать - на него мы никак не реагируем). И теперь первый же принятый байт - это всегда адрес. Всего по одному байту мы сразу поймём - к нам этот кадр относится или нет. А дальше принимай хоть ключи, хоть что. В зависимости от номера функции ветвление алгоритма может быть разным. И в этом вся гениальность модбаса rtu - любой кадр начинается с адреса.
     
  10. Ну приблизительно так, или десятком любых других способов.
    Я бы просто через 3.5 символа проверил приёмник (не выключая его, ессно, после приёма пакета), и если там есть байт(ы) - всё. не отвечаем. Врубились в чужой пакет или просто кто-то сошёл с ума и дует в линию мусор, в любом случае ответ в такую линию уже не имеет ни малейшего смысла. В общем, если уж использовать таймер и задержку, то проверять приёмник перед переключением направления передачи - правильная идея. Спасибо, что натолкнули, но...
    Дело не в этом. Обламывает необходимость тащить аппаратуру в чисто математический алгоритм, причём из-за гипотетического события, которое не произойдёт за всё время жизни вселенной. Хотя понятно, что уж миллисекундные-то тики уже есть практически на любой платформе бесплатно, и реализовать всё тем или иным способом очень просто, но тем не менее.
     
  11. parovoZZ

    parovoZZ Гуру

    проблема в том, что каждый байт может оказаться последним в кадре, а выжидать надо именно после приёма каждого байта. Впрочем, это уже дело реализации конкретного программиста.


    может я как-то плохо поясняю. Попробую ещё раз.
    Есть такой массив (язык ST):
    Код (Text):

    buf    : ARRAY [0..500] OF BOOL;
     
    мы его наполняем как-то битами (дискретами, статусами...). Как там биты лягут - мы не знаем. А если бы знали, то и смысла передавать нет. Дальше этот массив улетает как поток байт. Если у нас 10 слейвов с предложенным алгоритмом, то проще от таких устройств вообще отказаться, чем сидеть и высчитывать - а выстрелят или нет запрещённые комбинации. В промке и без этого головняка хватает.
     
  12. Нет. Последний байт ключа (как в Вашем примере, который должен сломать алгоритм) последним байтом корректного пакета быть не может никак и ни при каких обстоятельствах.То есть либо давайте другой пример, либо просто отметим, что проблемы не существует.

    Про остальное ей-Богу не понял. Времена наработки на ошибку в любом случае гигантские в сравнении с продолжительностью человеческой жизни. В 10 раз меньше (ну или больше) - вообще не вопрос. Семечки. А больше 250 и быть не может.
     
  13. То есть да, без задержки со стороны слейва (которая всё равно необходима по стандарту, хоть и не нужна по моему мнению), данный поток алгоритм поломает.
    С задержкой - алгоритм отловил ключ, приготовился отвечать. Проверил приёмник - а там аж три байта (как в Вашем примере). Всё, отбой. В такую линию отвечать нельзя.
     
  14. parovoZZ

    parovoZZ Гуру

    последним байтом в кадре может быть всё, что угодно. Отсчитывать интервал в 3.5 бита необходимо после приема стоп-бита (или последнего стоп-бита, если их два). Если включена проверка четности и она пройдена либо же она не включена (что гораздо чаще), то UART именно в этот момент снимет флаг занятости и отрапортует о приёме байта (или нет, если четность не пройдена). Мой пример к этой ситуации не имеет никакого отношения.

    мы договорились, что никаких сторонних ошибок у нас нет. Всё работает штатным образом.

    проблема исчезнет, когда алгоритм будет работать согласно требованиям стандарта. А если оно отвечает невпопад (это не я утверждает, так утверждает автор алгоритма), то к этому стандарту оно не имеет никакого отношения.
     
  15. parovoZZ

    parovoZZ Гуру

    откуда там три байта, если абсолютно все UART однобайтные (точнее от 6 и до 9 бит, в зависимости от настроек)? У мелкозявых МК DMA нет. Соответственно, где они копятся - не понятно.
     
  16. 02 03 08 5A A5 00 0A 1C 2D 04 05 94 01
    Я выделил байты, о которых говорю. За время задержки приёмопередатчик примет 2 или 3 байта, в зависимости от.
    Хотя на самом деле достаточно просто того факта, что за время задержки принят хотя бы один байт, даже без знания значения этого байта. То есть без буферов и ISR - если через 3.5 мс (ну или символов) RXNE == 1, всё, не отвечаем.
     
  17. parovoZZ

    parovoZZ Гуру

    отсчитывать необходимо после каждого принятого байта. Если за время отсчёта таймера не принято ни одного байта - всё, линия свободна. А это значит, что следующий байт однозначно будет адресом. Если UART принял байт, а таймер ещё не натикал, значит сбрасываем таймер и снова ждём.
     
  18. В Вашей парадигме - возможно.
    В моей просто достаточно не отвечать (не ответить) и продолжать принимать байты, пропуская их через окно и механизм приёма.
    Когда и если в линии появится валидный (ожидаемый, то есть совпадающий с ключом) пакет, он будет неизбежно принят.
    ... а Ваши боевые пляски вокруг таймера вселяют в меня ужас и вызывают уважение: я бы забоялся так-то. Ну разве что если уж очень-очень нужно.
     
  19. parovoZZ

    parovoZZ Гуру

    Я просто показал те места в алгоритме, которые не удовлетворяют требованиям стандарта, хотя автор алгоритма говорит, что есть поддержка.
    Профессионально так модбас устройства не пишутся. Никому не хочется лететь за свой счет на какой нить Ямал из за того, что там вдруг отвалилось модбас устройство.
     
  20. parovoZZ

    parovoZZ Гуру

    В самом дешманском мк аппаратных тамеров как минимум 3. Но для работы реально нужен всего один rtc таймер, который в прерывании генерирует системный тик. Все остальные таймеры (хоть тысяча) базируется на этом системном тике. То что вы используете дурину и лишаете себя доступа ко всему.... хотите стрелять себе в ногу- стреляйте себе в ногу в одиночестве.