RS-485 проверка на занятость канала?

ctacb
Offline
Зарегистрирован: 03.01.2017

Приветствую.

Есть-ли способ проверить канал на занятость?

Допустим две ардуинки запаралелены на одну линию через rs485 ttl конвертер. Будет ли работать метод DigitalRead для проверки, не занят ли в настоящий момент канал передачи, или это реализуется иным способом?

Проблема в том, что мне требуется пересылать данные по событию а не по запросу мастера (то-есть сесть децентрализованная).

nik182
Offline
Зарегистрирован: 04.05.2015

Проверки на занятость нет. 485 полудуплекный канал. Если на нем нет мастера, то арбитраж шины определяется протоколом обмена. Выбирайте любой без мастера.

ctacb
Offline
Зарегистрирован: 03.01.2017

Так в этом то и вопрос, каким образом определить передачу или ее отсутсвие? Ведь прежде чем протокол описать, надо явление на котором его описывать. В данном случае надо понять, идет в настоящий момент передача, или нет. Я себе представлял это так. Все узлы ждут пакет (RX включен). Если данных нет - можно открывать передачу, если данные есть - ждем пока данные не прекратились. Если надо начать передачу, ждем отсутсвия данных и начинаем передачу. Другие в этот момент начать передачу не могут пока не прекратится прием. Я правильно все понимаю?

nik182
Offline
Зарегистрирован: 04.05.2015

Посылаете пакет. Получает ответ что пакет получен. Не получили - через случайное время ещё попытка. И так пока не получим ответ. В конце концов всё получится.

ctacb
Offline
Зарегистрирован: 03.01.2017

Спасибо, буду пробовать. Интересно, на сколько быстрая там передача? Мне нужно каждые 100мс посылать 10 байт, и в ответ 1 байт. При этом устройств в сети больше 30.

nik182
Offline
Зарегистрирован: 04.05.2015

Дык зависит от скорости обмена - если 9600 это 9600 бит в секунду со всеми служебными. 10 байт это 80 бит да ещё 3 бита на каждый байт служебных, итого 110 бит - чуть больше 10 мс. На 115200 это 1 милисекунда. И кстати, количество устройств на линии ограничено. Почитайте стандарт.

Logik
Offline
Зарегистрирован: 05.08.2014

Делайте так, все приемники, которым сообщение не адресовано тоже его тихо принимают ничего больше не делая, обычно такое сделать просто. По завершению, после запроса и ответа они выдают сигнал канал свободен. Он будет у всех практически одновременно. Передачу начнет любой желающий, но спустя время T*N где T- некоторое время порядка времени передачи бита, а N-уникальній порядковый номер девайса в сети, можна адрес использовать в диапазоне 0..29 (или скоко их там). Попутно получаем еще и приоритеты устройств, что тоже как правило гуд.  Признак канал свободен снимается по появлению активного уровня, т.е. стартового бита в канале.

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

nik182
Offline
Зарегистрирован: 04.05.2015

Как в RS-485 кинуть сигнал канал свободен? Как быть если два начали передачу одновременно? Ну так получилось. Люди много лет пытались решить эту задачу. С увеличением узлов сети коллизии будут по любому. Поэтому нужно брать стандартный протокол и не мучится. 

ctacb
Offline
Зарегистрирован: 03.01.2017

Вы имеете ввиду Modbus или я что то путаю?

nik182
Offline
Зарегистрирован: 04.05.2015

Нет. MODBAS это мастер однозначно. Вообще я пользую его. По принципу датчики накапливают значения, мастер раз в 100мс опрашивает все. В такой системеме невозможно прерывание в экстренном случае. Другие протоколы я не использовал, только ознакамливался, когда выбирал. MODBAS выбрал из за наличия открытой реализации и досточно простого програмирования на на МК так и на РС.

Logik
Offline
Зарегистрирован: 05.08.2014

nik182 пишет:

Как в RS-485 кинуть сигнал канал свободен? 

Куда кого кидать на сколько ;) Пишите ясней.

nik182 пишет:

 Как быть если два начали передачу одновременно? Ну так получилось. 

"так получилось" то девка маме докладывает откуда ляля ;)

Смотрите: все устройства ведут одновременно прием, стоп-бит последнего байта они все вместе принимают одновременно, и одновременно приходят к выводу о том, что обмен завершен. Это синхронизация времени. Далее, при наличии необходимости передавать,  каждое устройство отмеряет индивидуальный временной интервал и начинают передачу. Если таких несколько, то первый начнет передачу тот у кого временной интервал меньший из всех желавших. При этом как на линии появляется старт бит -остальные желающие передать в пролете, и сново все принимают и ждут завершения и т.д.. Одновременно исключается, нет колизий (почти нет, при ошибках обмена могут появится и т.д. но много реже чем при "слепой" передаче). Если контроль прихода старт-бита затруднен (такое в принципе возможно, но не у нас) то просто разницу между временными интервалами увеличивают до времени приема целого байта, его всегда можна обнаружить.

ПС. Привет людям  которые "много лет пытались решить эту задачу." )))

ctacb
Offline
Зарегистрирован: 03.01.2017

Про временную синхронизацию тоже думал. Выделять интервалы по 15 - 30 мс от от основной для всех отсечки, которую они получают при подключении к сети (и раз в 5 минут от сервера), но опять же, где гарантия что синхро-бит все клиенты получат одновременно. Чем дальше точка будет от сервера, тем выше будет задержка.  Можно конечно поправку ввести, но это уже усложняет. Затем надо будет решить вопрос с ватч догом (может точка ушла в момент синхронизации в ребут). В общем, проще будет решить вопрос с коллизиями, особенно, если речь идут о простых операциях с короткими пакетами.

 

Logik
Offline
Зарегистрирован: 05.08.2014

ctacb пишет:

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

Так они ж на одних проводах висят, это и гарантия. Ближе или дальше -какая разница? Или вы про скорость света имеете в виду. Так 100[м]/300000000[м/с]=3е-7[с] т.е. меньше мксек. Главное, и весьма серезное требование в сети rs485 - чтоб любое устройство всегда слышало все устройства, в большой сети сложной топологии с сопротивлениями линий, емкостями и терминаторами это не просто бывает.

nik182
Offline
Зарегистрирован: 04.05.2015

Это  же всё легко считается. 30 устройств на скорости 19200(стандарт для MODBUS на длинных проводах), 110 бит = 150 мс. При периоде опроса 100 мс загрузка канала 150% - по такому каналу всю информацию не передать ни как. Уже при загрузке более 70% колличество коллизий будет нарастать лавинообразно до полного отказ обслуживания. На 115200 загрузка 30%,  но на длинных линях возможны проблемы.

Кроме того следует помнить, что у датчика приоритет не свободный канал, а полученные данные, которые нужно передать. Даже если канал свободен, а данных нет, то датчик будет ждать данные и если ранее получил извещение, что канал свободен - сразу будет выдавать данные. И менно поэтому сферические кони в вакууме, которые начинают передачу через фиксированную задержку от освобождения канала на практике среди датчиков не встречаются. Им просто нечего передавать сразу. Поэтому в промышленности так любят MODBAS. Гарантированное получение информации от всех датчиков. Для аварийной передачи сигналов используют другие протоколы.    

Logik
Offline
Зарегистрирован: 05.08.2014

А причем тут модбас вобще? "Что  зню то и пою" чтоле?

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

///что у датчика приоритет не свободный канал, а полученные данные,

Ни о чем. Датчики разные есть, с термопары хоть стопятсот раз можна снимать данные, шо ж их все сразу передавать? Очевидно, нет, должна быть продуманая политика этого вопроса, т.е. когда датчик считает что ему есть что сказать: обычно сильно надо когда резко данные поменялись или давно не говорил, или просто один важный и часто дает данные другой редко. Но самые ягодки начинаются в системе с резкой динамикой, когда резко меняется режим, и вбруг всем есть чего сказать, а канал один и если они все разом заговорят, то сплошные коллизии и никто ничего не узнает что происходит. Я с таким сталкивался на высоковольтных подстанциях, все работает пока ниче не происходит, собственно так систему и принимали, но как авария - сеть сбора инфы тоже падает )) И никто ниче не знает что творилось)))  Наладилось как распределили приоритеты датчикам.

Еще раз - всего этого в модбасе даже близко нет, там мастер опрашивает, потому с опытом модбаса - не в эту тему.

alex_r61
Offline
Зарегистрирован: 20.06.2012

Сколько раз эту тему уже поднимали. Поиск кто запретил? Существует интервально-маркерный метод, я уже и ссылку давал на литературу.

sslobodyan
Offline
Зарегистрирован: 28.09.2016

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

Logik
Offline
Зарегистрирован: 05.08.2014

А в 485-м именно двухпроводка. Все верно. Но если есть свободный пин, то его тож на RX подключаем и настраиваем на прерывание при приходе старта, быстей отслеживаем начало чужой передачи и меньше в коллизии влетаем.  

sslobodyan
Offline
Зарегистрирован: 28.09.2016

Нет, бывает еще четырехпроводка, когда пары прием-передача разделены. 

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

Logik
Offline
Зарегистрирован: 05.08.2014

Полный дуплекс на 485 - большая редкость. Но в стандарте есть такой. Я его только на бумаге и видел. Видел правда девайсы с выходом на 4 провода, но подключали всеравно на 2. Думаю четырехпроводка  - не актуально для ТС.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

sslobodyan пишет:

При передаче каждого байта проверяем свой входной буфер. Там должна быть копия только что переданного байта. Если нет - то возникла коллизия. Останавливаемся и ждем опять таймаут. Для каждого модуля величина таймаута, как выше предлагалось, зависит от айди. Должно работать, но только при двухпроводном подключении, когда есть возможность прослушать самого себя.

Скажу больше, в приемном буфере всегда будет "копия только что переданного байта", вне зависимости от того, что кто-то еще пытался, что либо передавать. Такого понятия как колизия в RS-485 не существует, это не CSMA/CD.

Logik
Offline
Зарегистрирован: 05.08.2014

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

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Logik пишет:
А одновременная передача 2-х девайсов может существовать? Вот это и есть коллизия.
Если её существование невозможно определить, значит о ней нет смысла и говорить. Иначе это просто вопрос веры. Один верит в то, что коллизии существуют, но их нельзя увидеть, другой верит в то, что бог есть, но его нельзя увидеть. 1:1

О коллизиях уместно говорить в Ethernet, CAN, но не в RS-485.

в RS-485 бессмысленно "слушать" самого себя, т.к. кто "говорит", тот "слышит" только себя и ни кого больше, для него нет никаких коллизий.

sslobodyan
Offline
Зарегистрирован: 28.09.2016

А вы лично это проверяли? И на каких микрухах? На сколько я сталкивался с 485, так там даже неправильный терминатор не дает нормально работать. Жаль, у меня сейчас нет на чем проверить, но интересно было бы в реале все откатать. Но, исходя из даташитов на микрухи, я на 99% уверен, что вы ошибаетесь и коллизии таки будут и в собственном приемнике мы увидим не эхо посланого байта, а другие данные. Вот отмакетировал в Протеусе - так и есть. Когда BAD_ENABLE разрешает передавать помеху, то в MASTER_ECHO вместо сигнала SEND возвращается мусор. По спецификации 485 интерфейса сигнал воспринимается как 1 когда (А-В) больше 200мв, а как 0 когда (А-В) меньше чем -200мв. В случае одновременной трансляции несколькими микрухами итоговое напряжение на входе приемника будет суммой напряжений от всех передатчиков, что дает неопределенный результат, т.е. приемник его может распознать и как 1 и как 0. Но нам важно лишь то, что мастер не получит у себя на RX то, что послал в TX - соотв. он распознает коллизию.