Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Свой протокол поверх RS-485
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Интерфейсы
kt361
Добрый день!

Для реализации своей задумки мне необходимо соединить порядка 20 устройств по общей шине в режиме Multi-Master.
В любой момент любое устройство независимо должно иметь возможность отправить свое сообщение в шину.
Если любое из устройств зависает или ломается, оно не должно никоим образом влиять на работоспособность других устройств в сети.
Ввиду стоимости и простоты переноса в различные среды я хочу использовать RS-485 на общей шине.

Исходя из условий, приходится отмести условно-стандартный для указанного физического уровня Modbus.
Соответственно, приходится выдумывать некую свою поделку, отправной точкой я хочу взять описание протокола от zap: http://electrotransport.ru/ussr/index.php?...12449#msg112449

Кратко: muli-master протокол с гарантированной отправкой над первичным протоколом, способным отправлять байты, но не биты.
Контроллер всегда слушает то, что творится в линии. Если линия свободна от передаваемых данных, котроллер может передавать свои данные. Если передаваемый байт не совпал с принятым, значит произошла одновременная отправка с другим контроллером. В этом случае оба затыкаются на время передачи двух символов и выбирают на рандом - начать отправлять снова, или ждать.
В описанном протоколе необходимо и для чтения, и для отправки необходимо знать время отправки одного символа (байта).

Реализовать передачу данных в преобразователь (st485/max485 итп) и измерять эти интервалы можно двояко:
1. Подключать встроенный в микроконтроллер UART. Интервал измерять временем выполнения функции uart_write в пустоту, с отключенным DE в преобразователе RS-485.
2. Реализовать UART программно на таймере и прерываниях, из прерываний таймера знаем время передачи одного символа.

Как лучше поступить?
В первой реализации используется меньше кода, ибо железная реализация uart. Но не очень нравится костыляция с пустой отправкой байтов.
Во второй реализации больше кода, зато полностью управляемая система с прерываниями, никаких костылей.

Благодарю за ответы и рассуждения!
stells
Цитата(kt361 @ Dec 2 2012, 18:08) *
Если передаваемый байт не совпал с принятым, значит...

... произошло КЗ... драйверы конечно с защитой от КЗ, но насколько корректно закладывать изначально такие конфликты?
_Pasha
ТС забыл указать физ. длину этой шины, потому что, для разруливания коллизий вполне может прокатить LIN-вариант управления передатчиком не через DI, а через TXE. Разумеется, если протокол будет способен гарантированно заткнуть мастеров на время длинной посылки, возникнет соблазн красиво переходить на максимально возможные скорости, тогда надо подумать о том, чтобы вернуть соединение TXD и DI обратно.
Lagman
похоже на CAN
kt361
На КЗ не стоит рассчитывать, шина предположительно защищена от внешних воздействий, если же такое произойдет из-за поломки одного из устройств, это будет заметно.

Длину шины я предполагаю метров на 300. RS485 разрешает на 1200 м делать.

Скорости 9600 бод вполне хватит. Особо длинных пакетов не будет. Если будет, можно будет и раздробить уже на более высоком уровне. Предположим максимум в 32 байта данных + заголовок
stells
Цитата(kt361 @ Dec 2 2012, 19:24) *
На КЗ не стоит рассчитывать...

если на выходе одного передатчика 1, а на выходе другого 0, то они в режиме КЗ
kt361
Точно. Но в драйверах ставят защиту от КЗ.
Я рассчитываю использовать ST485. Плюс можно поставить резисторы на выход в линию.
kt361
Цитата(Lagman @ Dec 2 2012, 19:15) *
похоже на CAN


CAN - дорого: Нужен Контроллер с CAN (120-200р) + драйвер шины .
RS-485: Контроллер за 50 р я присмотрел + RS485 (30 р).
=AK=
Цитата(kt361 @ Dec 3 2012, 00:38) *
Контроллер всегда слушает то, что творится в линии. Если линия свободна от передаваемых данных, котроллер может передавать свои данные. Если передаваемый байт не совпал с принятым, значит произошла одновременная отправка с другим контроллером. В этом случае оба затыкаются на время передачи двух символов и выбирают на рандом - начать отправлять снова, или ждать.


Используйте приемопередатчики CAN. Они представляют собой помесь RS485 и передатчиков с открытым коллектором, поэтому нечувствительны к столкновениям.

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

А для тех редких случаев, когда два узла начали передавать одновременно и потому не обнаружили столкновения в самом начале, там уже можно обнаруживать столкновения по несовпадению переданных и принятых байт, затыкаться и ждать рэндом интервал.
demiurg_spb
Цитата(Lagman @ Dec 2 2012, 19:15) *
похоже на CAN
+1
MrYuran
Есть такой лисапедег

Цитата
Имеется доминантный и рецессивный сигналы, как в CAN. В случае с проводами (кто знает, может я ещё и радио или ИК свет буду использовать) доминантный — это прижимание линии данных к земле. В обычном состоянии линия данных имеет подтяжку к +5В. Таким образом, когда устройство видит, что линия уже прижата к земле, оно понимает, что какое-то другое устройство уже шлёт данные, и ждёт освобождения линии. Сами данные кодируются длиною доминантных сигналов. 1T — ноль, 3T — единица, пауза между ними — 1T. Каждая передача начинается инициализацией в виде длинного сигнала в 10T.


CAN для нищебродов sm.gif
kt361
Так. ладно. разочаруюсь в RS485.

В CAN, как я понимаю, нет адресации, но есть непонятные мне пока фильтры сообщений (смотрю в сторону stm8s208). Даже можно постараться влезть в 8 байт данных для своих нужд.

Мне хотелось, чтобы устройства могли посылать широковещательные пакеты и направленные одному адресату.
Т.е. каждое устройство имеет свой идентификатор (0-254). Зашит в EEPROM, не меняется никогда и заведомо уникален в рамках одной сети.
Первый байт в пакете пусть будет отвечать за адресацию этого сообщения. если 0-254 - принимает ответственное устройство, если 255 - значит, широковещательный пакет, принимают все устройства.

В добавок мне нужно, чтобы была возможность перепрошить то или иное устройство в составе сети по этой же сети. Как понимаю из аппноута, стандартным бутлодером мне это не удастся - столкновение протоколов. Где прочитать о создании своего бутлодера для STM8?

Как наименьшей кровью реализовать такую или похожую схему? Для чего нужны фильтры, и помогу ли они мне?
редактор
раз уж речь зашла о CAN, и стандартные протоколы не устраивают (непонятно и т.д), то в заголовок CAN-сообщения можно вставить некоторую информацию (например адрес устройства, отправляющего пакет). Пакеты в CAN принимают все устройства, но используют только те, кому это необходимо. Остальные отбраковывают пакет с помощью фильтров (аппаратно) и программно.
Если использовать расширенные пакеты, то в 29 бит заголовка можно впихнуть очень много.
Ограничением в 8 байт на пакет не пугайтесь. Можно организовать мультипакетную передачу, и собирать из фрагментов единое сообщение.
ILYAUL
Цитата
если 255 - значит, широковещательный пакет, принимают все устройства.

Для этого существует 9-бит
Цитата
Так. ладно. разочаруюсь в RS485
.
Перед тем как разочаровываться , Вы разбритесь , что из себя представляет техническая сторона RS485 и протоколы для обмена
в сети.
kt361
Так помогите разобраться.
В RS ничего кроме физической реализации нет.
haker_fox
А нельзя протокол переделать так, чтобы в сети был один мастер, без запроса которого ни одно устройство бы не отправляло данных?) Тогда все по умолчанию только слушают, а когда всем одновреммено пришел некий пакет, то только то устройство, чей адрес был в заголовке пакета, начинает передаать данные в ответ?
kt361
Нельзя. Ибо выходит из строя мастер - вся сеть перестает работать. Это недопустимо.
Система может обойтись без какого-то члена, но всегда должна быть работоспособна.
редактор
Если зациклициваться на RS, то можно передавать управление между контроллерами по кругу, а при потере активности на шине установить фиксированное, но разное для всех блоков, время захвата шины, или фиксированное время от последней передачи.
Но CAN в данном варианте выглядит более предпочтительно.
stells
Цитата(kt361 @ Dec 4 2012, 10:13) *
Нельзя. Ибо выходит из строя мастер - вся сеть перестает работать.

Вы почитайте литературу, есть варианты передачи (перехвата) управления... например мастер постоянно кидает в сеть некоторый кадр, подтверждающий его работоспособность, если этого кадра нет в определенное время, то слейвы отсчитывают еще некоторый интервал (у каждого свой) и захватывают управление... таким образом мастером в сети становится тот, у которого этот интервал меньше
flakman
Позвольте добавить свой вопрос. Задача от части похожа на сабж от kt361, по этому прочитал весь топик и не стал создавать отдельный, да и назывался бы он точно также.
Нужно что-то вроде промежуточного варианта между мульти-мастер протоколом и традиционными. Сразу скажу что уйти от RS485 просто не могу - у меня готовое устройство с тем что есть, выбирать не из чего. Сеть может работать и с одним мастером, но особенность в том, что критично время реакции на запрос, счёт идёт на миллисекунды (сеть будет из устройств считывания RFID, всё сделать нужно за время, приемлемое для подноса человеком карты к считывателю). По этой причине хочется заменить опрос слэйвов на сигнализацию самими слэйвами о необходимости связи с мастером.

Есть такая идея. По сравнению с Modbus всё наоборот - мастер не клиент, а сервер. В тишине мастер не опрашивает слэйвов, а ждёт запроса на связь => wink.gif возникает проблема с коллизиями, которую попытаюсь объяснить как хочу обойти. Слэйвы в спокойном состоянии тоже слушают шину. Что-бы просигналить о необходимости связи, слэйв отсылает пакет определённого формата, включающий его собственный адрес. Мастер, если всё ок, в ответ отсылает пакет на широковещательный адрес, в котором содержится адрес запросившего слэйва. Данный пакет для инициатора связи означает что обмен разрешён, всеми остальными он должен распознаваться как "шина занята" (в пакете не их адрес), и нужно ждать широковещательного пакета означающего освобождение шины. Во избежании глюков можно периодически слать пакет "шина свободна" просто во время тишины. Это поможет и для распознавания вымершего матера. Но механизм поиска нового в моей задаче не стоит. Им в любом случае может быть только софт на ПК с совершенно другой логикой чем у остальных девайсов в сети.

Теперь если всё не ок. Если несколько слэйвов начинают передачу, то получившийся пакет мастер просто отбрасывает как не корректный пакет запроса на связь, в тишине он ждёт только его. Если при коллизии например модифицировался адрес запрашивающего, а формат пакета остался корректным, и мастер отправил широковещательный ответ, то обладатель этого случайного адреса просто не ответит, передача навернётся по таймауту, а мастер снова объявит о свободности шины. Настоящие же запросившие связь в случае не получения положительного ответа ждут объявления свободности шины, рандомят себе задержку и пробуют снова.
Пакеты запросов связи могут слушать и все слэйвы, что-бы затыкаться сразу же, пока не получат подтверждения свободности шины. Это избавит от влезания "желающих" во время уже начавшейся попытки установить связь, и сильно снизит вероятность коллизий.

На вскидку, в случае отсутствия коллизии, связь будет установлена за один запрос-ответ и самое главное - инициирована слэйвом, опрос не нужен. Правда рассматривал только логическую сторону вопроса. Физическую - кз передатчиков не рассматривал. Разработка внутренняя, не на продажу, и все конкретные девайсы добавляемые в сеть будут заранее известны с возможностью проверки наличия защиты драйверов RS485 на защиту от кз. Наверно это плохой тон конечно.

Возможно это велосипед какого-нибудь протокола вообще без фиксированного матера-сервера (прошу ткнуть носом sm.gif), возможно это вообще не будет работать (прошу обсуждения). Изначально рассматривал Modbus, но там как раз традиционный вариант с опросом. Если описанное выше имеет место быть, не знаю - стоит писать с нуля или быстрее будет модифицировать какую-нибудь реализацию Modbus. Это потому-что на самом деле после установки связи, она может происходить точно так-же как в Modbus, что избавляет от написания реализации самого обмена данными.
_Pasha
Цитата(stells @ Dec 4 2012, 09:45) *
Вы почитайте литературу, есть варианты передачи (перехвата) управления... например мастер постоянно кидает в сеть некоторый кадр, подтверждающий его работоспособность, если этого кадра нет в определенное время, то слейвы отсчитывают еще некоторый интервал (у каждого свой) и захватывают управление... таким образом мастером в сети становится тот, у которого этот интервал меньше

Сташин Урусов Мологонцева
Это книжка такая по 51-м была в 19затёртом году.2ТС: Гуглим-с.
=AK=
Цитата(flakman @ Dec 21 2012, 22:50) *
Нужно что-то вроде промежуточного варианта между мульти-мастер протоколом и традиционными. Сразу скажу что уйти от RS485 просто не могу - у меня готовое устройство с тем что есть, выбирать не из чего. Сеть может работать и с одним мастером, но особенность в том, что критично время реакции на запрос, счёт идёт на миллисекунды

Похоже что мало кто знает, что помимо "традиционных" протоколов "master-slave", в которых есть какой-то мастер, есть протоколы "producer-consumer", в которых мастера нет в принципе.

В протоколах "producer-consumer" (к которым, в частности, относится CAN) передачу начинает любой "производитель информации", которому "есть что сказать". А принимает информацию не какое-то одно устройство, а все, кому эта информация нужна. В результате этого информация передается очень быстро даже при малых бодовых скоростях. Суммарный выигрыш по скорости при раздаче информации получается на один-два порядка, хоть людям неискушенным в это трудно поверить.

В обычных "master-slave" мастер должен:
- все время опрашивать другие узлы на предмет наличия новой информации
- если у одного из узлов появилось что-то новое, мастер должен прочитать инфу
- после этого мастер должен по очереди разослать инфу тем узлам, которым она нужна

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

Основной проблемой протоколов "producer-consumer" является обнаружение и "разруливание" столкновений (CSMA/CD). Очень хорошим вариантом является предотвращение столкновений (CSMA/CA), для реализации которой как правило используют передатчики с открытым коллектором или их эквиваленты. CAN использует эквивалент открытого коллектора, гибрид ОК и RS485.
flakman
Цитата(=AK= @ Dec 23 2012, 14:20) *
Похоже что мало кто знает, что помимо "традиционных" протоколов "master-slave", в которых есть какой-то мастер, есть протоколы "producer-consumer", в которых мастера нет в принципе.
...
Основной проблемой протоколов "producer-consumer" является обнаружение и "разруливание" столкновений (CSMA/CD). Очень хорошим вариантом является предотвращение столкновений (CSMA/CA), для реализации которой как правило используют передатчики с открытым коллектором или их эквиваленты. CAN использует эквивалент открытого коллектора, гибрид ОК и RS485.


Спасибо за ответ, сейчас покопаем.
Smen
Тоже возникла похожая задача.
Сперва хотел реализовать именно "producer-consumer".
В принципе, даже, вроде, придумал как коллизии разруливать.
Однако возникло препятствие в виде компьютера с преобразователем USB-485 на FT232R, который сам не умеет определять занятость линии.
Т.е. это должен делать комп, который не является "реал-тайм".
Короче говоря, аппаратно проверять не получается, и надо всё реализовать на уровне команд протокола.
Кто может что-нибудь подсказать? Или, где в рассуждениях ошибся?
=AK=
Цитата(Smen @ Jul 16 2013, 18:01) *
Однако возникло препятствие в виде компьютера с преобразователем USB-485 на FT232R, который сам не умеет определять занятость линии.


А что, разве на FT232R свет клином сошелся? Возьмите любой микроконтроллер, у которого есть UART и USB, и сделайте на нем.
Smen
Цитата(=AK= @ Jul 16 2013, 16:49) *
А что, разве на FT232R свет клином сошелся?
В данном случае, сошёлся, ибо не я его делаю.
Fujitser
Не взлетит. RS-485 не поддерживает режим с возможными коллизиями шины (когда передают несколько устройств одновременно).

Используйте CAN.
ZASADA
+1, переходите на CAN, мы везде где можно от RS-485 избавляемся. С CAN гораздо проще жить.
редактор
Цитата
В данном случае, сошёлся, ибо не я его делаю.

В таком случае МК с 2-мя UART-ми. Один на FT232R - для "чистых данных", второй в линию - коллизии разруливать.
dac
имхо Ethernet полностью снимает проблемы коллизий. enc28j60 стоит недорого, есть PIC с набортным PHY. тоже недорого sm.gif это если CAN не устраивает sm.gif))
Kane
Цитата(редактор @ Jul 17 2013, 11:32) *
В таком случае МК с 2-мя UART-ми. Один на FT232R - для "чистых данных", второй в линию - коллизии разруливать.

Контроллера с одним UARTом в режиме full-duplex достаточно. В CAN трансиверах есть режим эхо (что отправили - должны сразу-же получить). Если принятое с полученым не совпадает то имеем коллизию, либо какой-то аппаратный сбой.
редактор
Только ПК оперативно эти коллизии не разрулит (передавать побайтно конечно вариант, но уж больно долго может получиться). Поэтому рекомендован МК в качестве проставки между каналом и ПК.
Smen
Цитата(ZASADA @ Jul 16 2013, 22:54) *
переходите на CAN, мы везде где можно от RS-485 избавляемся. С CAN гораздо проще жить.
А разве CAN 1,5 м сдюжит?

Цитата(редактор @ Jul 17 2013, 11:32) *
В таком случае МК с 2-мя UART-ми. Один на FT232R - для "чистых данных", второй в линию - коллизии разруливать.

Так говорю же, девайс уже изготовлен.

В общем пока решил сделать мастер-слейв, а потом убеждать свой девайс изготовить.
Fujitser
Цитата(Smen @ Jul 24 2013, 11:27) *
А разве CAN 1,5 м сдюжит?


CAN предназначен для передачи данных на расстояние до 5 км.
Smen
Цитата(Fujitser @ Jul 24 2013, 17:17) *
CAN предназначен для передачи данных на расстояние до 5 км.
Насколько помню, это - при скорости, не более, 10кбод.
Мне же надо 115, а желательно, и выше. Ну, и, собственно, как уже говорил, выбора нет.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.