|
Modbus RTU подобный протокол, проблема реализации, Может есть готовый с описанием. |
|
|
|
Jul 29 2007, 18:18
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Alex ma @ Jul 29 2007, 20:34)  Вся фишка в проблеме определения стартовой последовательности, в Modbus – это пауза 3,5 кадра вроде, другой вариант уникальная стартовая последовательность, проблема исключения стартовой последовательности в данных, для МК мне кажется проще всего отслеживать паузу чем обрабатывать массив с поиском и заменой стартовой последовательности, чтоб она не встретилась в данных. Да, но на PC таймер под Windows только 1 мс дискретность. Отслеживание стартовой последовательности (начальная метка) реализуется весьма просто и используется очень широко. Например вводится метка "FF" за ней следует комманда. В потоке данных при встрече "FF" она удваивается. А на приёме, при приёме FF смотрится байт следом. Если "FF", то удаляется если нет, то принимается комманда. Такие вещи используются при непрерывном потоке данных. В протоколе Modbus используется кадрирование. И паузы. Я бы вам рекомендовал использование пауз. Использование уникальных стартовых последовательностей - это из другой оперы. Это когда вы не можете не передовать. То есть вообще отсутствует понятие молчания в линии. Гарантированно получить 1мс таймером под PC вам не удастся. Дискретность 1мс - это объявленная дискретность. Если использовать стандартный таймер, например из DELFI, то вам не удастся получить паузу менее 20мс. При использовании таймера типа Код procedure TimeProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD) stdcall; я умудрился получить порядка 10мс. Меньше не пробовал - не требовалось, но со стабильностью что-то есть проблемы. Наверное точное время можно получить только в режиме ядра или в каком-нибудь монопольном режиме или приоритет как-то выставить. Здесь я плаваю. Но вам это и не надо. Там надо чтобы пауза была "не меньше".
|
|
|
|
|
Jul 29 2007, 19:23
|
Местный
  
Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621

|
А разве в спецификации MODBUS RTU есть определение стартовой последовательности по детерминированному набору байт? MODBUS ASCII стартует по escape символу, а RTU - по разрыву между пакетами. Не совсем понятен состав оборудования - где мастер, а где слэйв? Если слэйв на МК( как обычно), то выделить 3.5 байта, зарезервировав под это отдельный таймер, нетрудно, если же на РС, то между РС и MODBUS RTU проще поставить МК, поскольку у Виндозы дискретность не 1 мс, и не 10, это значение не знает никто, кроме планировщика задач, работа которого не документируется. Если Мастер на РС, то за паузами можно не следить, поскольку мастер сам их и формирует.
|
|
|
|
|
Jul 29 2007, 19:55
|
Частый гость
 
Группа: Новичок
Сообщений: 81
Регистрация: 9-08-06
Пользователь №: 19 445

|
У ведущего МК два USART один мастер второй слейв, один к PC, второй к другим МК, PC – мастер. Определение старта склоняюсь к паузе как в MODBUS RTU, использовать в чистом виде MODBUS RTU, цели нет. Сообщение: пауза, адрес, команда, данные, кс. пауза. Точно, нужно использовать паузу для разделения посылок, смущала реализация пауз на PC, но действительно не что не мешает сделать 20 – 30 мс, а между контроллерами меньше.
|
|
|
|
|
Jul 29 2007, 20:10
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
При реализации RTU-ных протоколов в контроллере надо закладывать настраиваемые паузы. Особенно когда для коммуникации используется RS485. Как минимум: - минимальная пауза перед началом ответа, - максимальное время отведенное для ответа. Для RS485 еще дополнительно: - пауза перед переключением драйвера RS485 на передачу, - пауза перед началом передачи после переключения драйвера RS485 на передачу, - пауза перед переключением драйвера RS485 на прием после окончания передачи. Манипулируя этими временами, можно настроить любую связь хоть с PC, хоть с другим сегментом RS485, подключенного через один или цепочку репитеров RS485 (которые вносят задержку распространения пакета). Для связи с PC времена паузы можно удлиннить вне стандарта того же ModBus RTU, но зато на PC не нужно будет рвать ж@пу для ловли 1мс пауз и связь будет устойчивая. В то же время драйвер связи в целевом МК и для связи с PC и для межконтроллерного обмена будет использоваться один и тот же. P.S. кстати, при выборе протокола (если конечно вы не связаны ТЗ) нужно анализировать эффективность траффика и уже в зависимости от этого выбирать между RTU-ными протоколами, ASCII-ными, протоколами использующими байт-стаффинг и т.п. Ну и немаловажное значение имеет наличие уже готовой реализации какого-либо протокола в вашей коллекции.
|
|
|
|
|
Jul 30 2007, 10:58
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(upc2 @ Jul 30 2007, 09:46)  Это все условно. Никто на практике паузу в 3,5 символа не анализирует. Все под контролем мастера. Подчиненный контроллер должен сразу ответить.Согласен с rezident необходимо только правильно организовать минимальную паузу перед началом ответа ,чтобы РС успел отреагировать на ответ и максимальное время отведенное для ответа, чтобы долго не ожидать ответа.Обычно это около 1 сек. Естественно минимальная пауза зависит от того какой у вас драйвер СОМ-порта в РС и времени переключения RS-485 преобразователя. Простите, а зачем вы за всех отвечаете? Я например брал и полностью реализовывал весь протокол. И все паузы выдерживал. Насколько я помню там ни одна а несколько пауз определяющих. Потом брал программу тестирующую и проверял свой протокол на работоспособность. Кстати когда я делал, то тоже считал всё это не очень важным. Потому что пользовал 232 интерфейс. Потом когда переходил на rs485 понял зачем паузы и почему они такие. Они ведь не из головы взяты, а банально расчитаны. И я считаю что надо именно придерживаться стандарта или использовать свой протокол. Просто потому, что иначе это Modbus не назовёшь. Мастером вы можете и увеличить паузы. Например указание по 3.5символа, там "не меньше". То есть если пауза превысила данный таймаут, то пошла новая посылка, а предыдущая оборвана. Не знаю сбрасывал ли кто. Попробую сбросить я. Прога на PC для тестирования Modbus. Возможно есть более новая версия - не знаю. Я с этим работал лет 7 назад ещё на х51. Да кстати ещё один момент. Если у вас один мастер на PC и несколько слэйвов на МК, то не надо транслировать. Вы можете подать паралельно на все МК. Будет меньше обработки, а ПО на МК будет однотипное. Просто разные адреса и/или команды. У меня к примеру сейчас 7 слэйвов.
|
|
|
|
|
Jul 30 2007, 11:35
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Делать задержки на таймере не самое лучшее решение,используйте API функцию SLEEP из KERNEL32. Типа так обьявляем Код Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) и пользуемся Sleep 1 Sleep 100 и т.д.
|
|
|
|
|
Jul 30 2007, 13:06
|
Знающий
   
Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063

|
Цитата(SasaVitebsk @ Jul 30 2007, 13:58)  Простите, а зачем вы за всех отвечаете? Я например брал и полностью реализовывал весь протокол. И все паузы выдерживал. Насколько я помню там ни одна а несколько пауз определяющих. Потом брал программу тестирующую и проверял свой протокол на работоспособность. Кстати когда я делал, то тоже считал всё это не очень важным. Потому что пользовал 232 интерфейс. Потом когда переходил на rs485 понял зачем паузы и почему они такие. Они ведь не из головы взяты, а банально расчитаны. И я считаю что надо именно придерживаться стандарта или использовать свой протокол. Просто потому, что иначе это Modbus не назовёшь. Мастером вы можете и увеличить паузы. Например указание по 3.5символа, там "не меньше". То есть если пауза превысила данный таймаут, то пошла новая посылка, а предыдущая оборвана. Не знаю сбрасывал ли кто. Попробую сбросить я. Прога на PC для тестирования Modbus. Возможно есть более новая версия - не знаю. Я с этим работал лет 7 назад ещё на х51. Да кстати ещё один момент. Если у вас один мастер на PC и несколько слэйвов на МК, то не надо транслировать. Вы можете подать паралельно на все МК. Будет меньше обработки, а ПО на МК будет однотипное. Просто разные адреса и/или команды. У меня к примеру сейчас 7 слэйвов. Когда будет 2 и более мастера на шине, тогда я может-быть с вами и соглашусь.А сейчас все просто Мастер дает запрос и ждет ответа. И RS485 здесь не причем.Не имею в виду реализацию Slave на РС. Мой мастер прекрасно работает со стандартными датчиками и приборами ..Микрол,Элемер,Метран, весы SBS и пр. Реализация мастера на МК проще чем на РС. Больше хлопот доставляет Slave на микроконтроллере.Здесь есть много алгоритмов реализации. Главное зависит от того , какую основную функцию выполняет МК. Главное не зацикливаться на Modbus.Modbus для него не главная задача. С успехом в своих разработках применяю смешанный протокол.Посылка с начальным и завершающим символом, а передаются байты.Все остальное от RTU .Это более скоростной протокол и проще программый код.
|
|
|
|
|
Jul 30 2007, 13:26
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(bodja74 @ Jul 30 2007, 15:35)  Делать задержки на таймере не самое лучшее решение,используйте API функцию SLEEP из KERNEL32. Sleep штука очень не надежная. Вот результаты работы Sleep на моем компе. Измеряется реальная задержка в микросекундах. 20 замеров: Код Freq=3579545Hz <--частота счетчиков ядра
Sleep results in microseconds
Sleep( 0) Sleep( 1) Sleep( 2) Sleep( 3) Sleep(10) Sleep(16) Sleep(20) ---------------------------------------------------------------------- 5 5356 12438 12255 11406 22897 19093 681 8942 13977 2635 12385 23951 24992 130 4358 6315 2524 6867 17958 21907 37 2867 7162 12062 14896 29876 28462 56 6997 549 12618 5641 23522 16793 59 10294 12313 8269 9699 29652 25246 121 7651 459 14255 985 23322 24873 5 13259 13542 7584 5488 19888 24991 278 6649 1428 5654 1686 30749 27801 164 14435 14506 14269 14127 27618 22679 235 6621 12149 6513 6758 25621 16563 139 9536 13358 2018 15205 22122 17909 60 8184 11817 14828 721 24907 29682 125 7033 403 151 412 18126 17158 5 6331 865 8556 8092 28302 22481 11 1372 3209 593 5084 26241 22725 493 14089 737 13325 14392 19364 25576 666 11077 4232 5808 7581 25980 15803 97 4534 470 10276 5433 19632 20555 147 2997 1649 15627 15497 18517 30676 заметьте, что при значениях Sleep < 16 результат непредсказуем.(16 это такт оперционки на моем компе) например Sleep(10) дает значения от 412 до 15497 микросекунд. Sleep(3) дает значения от 151 до 15527 микросекунд. Так что для задержки "не менее" 3,5 символов в модбас, Sleep явно не подходит. Да, замечу еще, измерения проводились на "ненагруженном" компе. Если запустить несколько жрущих ресурсы задач, то все становится еще хуже
|
|
|
|
|
Jul 30 2007, 16:16
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(singlskv @ Jul 30 2007, 16:26)  Sleep штука очень не надежная. Вот результаты работы Sleep на моем компе. ГЫ ,а счего вы взяли ,что сама ваша прога не делает выборки значений с переменны успехом  ,или вы думаете что Винда забьет на все дрова и ваш процесс будет пропускать вне очереди Если говорить из практики ,то если бы у меня был такой разброс значений ,то моя бы прога ,или страшно бы глючила или бы вообще не работала Ладно,вообще я другое имел ввиду  ,3.5 кадра естественно мерять Sleep нет смысла ,просто я предложил более простую реализацию задержки ,так как если делать через встроеный таймер нужно постоянно опрашивать его значение до получения необходимого результата или делать событие по его периоду и там что то решать.
|
|
|
|
|
Jul 30 2007, 16:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(bodja74 @ Jul 30 2007, 20:16)  ГЫ ,а счего вы взяли ,что сама ваша прога не делает выборки значений с переменны успехом  ,или вы думаете что Винда забьет на все дрова и ваш процесс будет пропускать вне очереди Если говорить из практики ,то если бы у меня был такой разброс значений ,то моя бы прога ,или страшно бы глючила или бы вообще не работала  Ну если Вы не верите счетчикам ядра, то тады, я Вас вероятно не смогу убедить что приведенные мной значения это правда погуглите по таким функциям: QueryPerformanceFrequency QueryPerformanceCounter Возможно после этого Вы лучше поймете как все устроено у Windows, и поймете как правильно измерять задержки под ней.
|
|
|
|
|
Jul 30 2007, 17:41
|
Участник

Группа: Validating
Сообщений: 56
Регистрация: 15-10-06
Пользователь №: 21 335

|
Ну Sleep как-то не кошерно для _таких_ задержек пользовать ... Тогда-уж лучше в сторону multimedea timer'ов посмотреть .... там и четче можно ...
|
|
|
|
|
Jul 30 2007, 18:01
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Maddy @ Jul 30 2007, 21:41)  Ну Sleep как-то не кошерно для _таких_ задержек пользовать ... Тогда-уж лучше в сторону multimedea timer'ов посмотреть .... там и четче можно ... Miltimedia Timers намного лучше чем Sleep, по крайней мере они, насколько я помню, не дают при задержке например 3мс, задержку 150мкс  Правда точность мультимедейных таймеров тоже не "блестящая", примерно 1-3 мс. Так что если нужен полный контроль - PerformanceCounters, в остальных случаях мультимедиа таймеры, а Sleep это только на на случай если нашему процессу действительно нужно поспать по крайней мере 20 мс (максимальное время такта операционки которое я лично встречал)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|