RS-485 проверка на занятость канала?
- Войдите на сайт для отправки комментариев
Вс, 08/01/2017 - 16:41
Приветствую.
Есть-ли способ проверить канал на занятость?
Допустим две ардуинки запаралелены на одну линию через rs485 ttl конвертер. Будет ли работать метод DigitalRead для проверки, не занят ли в настоящий момент канал передачи, или это реализуется иным способом?
Проблема в том, что мне требуется пересылать данные по событию а не по запросу мастера (то-есть сесть децентрализованная).
Проверки на занятость нет. 485 полудуплекный канал. Если на нем нет мастера, то арбитраж шины определяется протоколом обмена. Выбирайте любой без мастера.
Так в этом то и вопрос, каким образом определить передачу или ее отсутсвие? Ведь прежде чем протокол описать, надо явление на котором его описывать. В данном случае надо понять, идет в настоящий момент передача, или нет. Я себе представлял это так. Все узлы ждут пакет (RX включен). Если данных нет - можно открывать передачу, если данные есть - ждем пока данные не прекратились. Если надо начать передачу, ждем отсутсвия данных и начинаем передачу. Другие в этот момент начать передачу не могут пока не прекратится прием. Я правильно все понимаю?
Посылаете пакет. Получает ответ что пакет получен. Не получили - через случайное время ещё попытка. И так пока не получим ответ. В конце концов всё получится.
Спасибо, буду пробовать. Интересно, на сколько быстрая там передача? Мне нужно каждые 100мс посылать 10 байт, и в ответ 1 байт. При этом устройств в сети больше 30.
Дык зависит от скорости обмена - если 9600 это 9600 бит в секунду со всеми служебными. 10 байт это 80 бит да ещё 3 бита на каждый байт служебных, итого 110 бит - чуть больше 10 мс. На 115200 это 1 милисекунда. И кстати, количество устройств на линии ограничено. Почитайте стандарт.
Делайте так, все приемники, которым сообщение не адресовано тоже его тихо принимают ничего больше не делая, обычно такое сделать просто. По завершению, после запроса и ответа они выдают сигнал канал свободен. Он будет у всех практически одновременно. Передачу начнет любой желающий, но спустя время T*N где T- некоторое время порядка времени передачи бита, а N-уникальній порядковый номер девайса в сети, можна адрес использовать в диапазоне 0..29 (или скоко их там). Попутно получаем еще и приоритеты устройств, что тоже как правило гуд. Признак канал свободен снимается по появлению активного уровня, т.е. стартового бита в канале.
Слепо кидать на авось - плохо, пропускная спасобность канала занижается в разы из-за того, что колизии занимают часть времени.
Как в RS-485 кинуть сигнал канал свободен? Как быть если два начали передачу одновременно? Ну так получилось. Люди много лет пытались решить эту задачу. С увеличением узлов сети коллизии будут по любому. Поэтому нужно брать стандартный протокол и не мучится.
Вы имеете ввиду Modbus или я что то путаю?
Нет. MODBAS это мастер однозначно. Вообще я пользую его. По принципу датчики накапливают значения, мастер раз в 100мс опрашивает все. В такой системеме невозможно прерывание в экстренном случае. Другие протоколы я не использовал, только ознакамливался, когда выбирал. MODBAS выбрал из за наличия открытой реализации и досточно простого програмирования на на МК так и на РС.
Как в RS-485 кинуть сигнал канал свободен?
Как быть если два начали передачу одновременно? Ну так получилось.
Смотрите: все устройства ведут одновременно прием, стоп-бит последнего байта они все вместе принимают одновременно, и одновременно приходят к выводу о том, что обмен завершен. Это синхронизация времени. Далее, при наличии необходимости передавать, каждое устройство отмеряет индивидуальный временной интервал и начинают передачу. Если таких несколько, то первый начнет передачу тот у кого временной интервал меньший из всех желавших. При этом как на линии появляется старт бит -остальные желающие передать в пролете, и сново все принимают и ждут завершения и т.д.. Одновременно исключается, нет колизий (почти нет, при ошибках обмена могут появится и т.д. но много реже чем при "слепой" передаче). Если контроль прихода старт-бита затруднен (такое в принципе возможно, но не у нас) то просто разницу между временными интервалами увеличивают до времени приема целого байта, его всегда можна обнаружить.
ПС. Привет людям которые "много лет пытались решить эту задачу." )))
Про временную синхронизацию тоже думал. Выделять интервалы по 15 - 30 мс от от основной для всех отсечки, которую они получают при подключении к сети (и раз в 5 минут от сервера), но опять же, где гарантия что синхро-бит все клиенты получат одновременно. Чем дальше точка будет от сервера, тем выше будет задержка. Можно конечно поправку ввести, но это уже усложняет. Затем надо будет решить вопрос с ватч догом (может точка ушла в момент синхронизации в ребут). В общем, проще будет решить вопрос с коллизиями, особенно, если речь идут о простых операциях с короткими пакетами.
где гарантия что синхро-бит все клиенты получат одновременно. Чем дальше точка будет от сервера, тем выше будет задержка.
Так они ж на одних проводах висят, это и гарантия. Ближе или дальше -какая разница? Или вы про скорость света имеете в виду. Так 100[м]/300000000[м/с]=3е-7[с] т.е. меньше мксек. Главное, и весьма серезное требование в сети rs485 - чтоб любое устройство всегда слышало все устройства, в большой сети сложной топологии с сопротивлениями линий, емкостями и терминаторами это не просто бывает.
Это же всё легко считается. 30 устройств на скорости 19200(стандарт для MODBUS на длинных проводах), 110 бит = 150 мс. При периоде опроса 100 мс загрузка канала 150% - по такому каналу всю информацию не передать ни как. Уже при загрузке более 70% колличество коллизий будет нарастать лавинообразно до полного отказ обслуживания. На 115200 загрузка 30%, но на длинных линях возможны проблемы.
Кроме того следует помнить, что у датчика приоритет не свободный канал, а полученные данные, которые нужно передать. Даже если канал свободен, а данных нет, то датчик будет ждать данные и если ранее получил извещение, что канал свободен - сразу будет выдавать данные. И менно поэтому сферические кони в вакууме, которые начинают передачу через фиксированную задержку от освобождения канала на практике среди датчиков не встречаются. Им просто нечего передавать сразу. Поэтому в промышленности так любят MODBAS. Гарантированное получение информации от всех датчиков. Для аварийной передачи сигналов используют другие протоколы.
А причем тут модбас вобще? "Что зню то и пою" чтоле?
В первом сообщении обозначена проблема "требуется пересылать данные по событию а не по запросу мастера (то-есть сесть децентрализованная)", а модбас всегда мастер-слейв. Там колизий быть не может. Потому и любят в прмышленности что простой, плюс старый как говно мамонта, распостраненный.
///что у датчика приоритет не свободный канал, а полученные данные,
Ни о чем. Датчики разные есть, с термопары хоть стопятсот раз можна снимать данные, шо ж их все сразу передавать? Очевидно, нет, должна быть продуманая политика этого вопроса, т.е. когда датчик считает что ему есть что сказать: обычно сильно надо когда резко данные поменялись или давно не говорил, или просто один важный и часто дает данные другой редко. Но самые ягодки начинаются в системе с резкой динамикой, когда резко меняется режим, и вбруг всем есть чего сказать, а канал один и если они все разом заговорят, то сплошные коллизии и никто ничего не узнает что происходит. Я с таким сталкивался на высоковольтных подстанциях, все работает пока ниче не происходит, собственно так систему и принимали, но как авария - сеть сбора инфы тоже падает )) И никто ниче не знает что творилось))) Наладилось как распределили приоритеты датчикам.
Еще раз - всего этого в модбасе даже близко нет, там мастер опрашивает, потому с опытом модбаса - не в эту тему.
Сколько раз эту тему уже поднимали. Поиск кто запретил? Существует интервально-маркерный метод, я уже и ссылку давал на литературу.
А если ввести понятие "таймаут между пакетами"? Пускай тот, кто хочет говорить, очищает входной буфер, ждет сначала это время и проверяет входной буфер. Буфер пуст - линия свободна, можно передавать. При передаче каждого байта проверяем свой входной буфер. Там должна быть копия только что переданного байта. Если нет - то возникла коллизия. Останавливаемся и ждем опять таймаут. Для каждого модуля величина таймаута, как выше предлагалось, зависит от айди. Должно работать, но только при двухпроводном подключении, когда есть возможность прослушать самого себя.
А в 485-м именно двухпроводка. Все верно. Но если есть свободный пин, то его тож на RX подключаем и настраиваем на прерывание при приходе старта, быстей отслеживаем начало чужой передачи и меньше в коллизии влетаем.
Нет, бывает еще четырехпроводка, когда пары прием-передача разделены.
Конечно, можно слушать линию постоянно и сбрасывать начало отсчета таймаута по приему любого постороннего байта. Просто чаще будем отвлекаться на посторонние разговоры.
Полный дуплекс на 485 - большая редкость. Но в стандарте есть такой. Я его только на бумаге и видел. Видел правда девайсы с выходом на 4 провода, но подключали всеравно на 2. Думаю четырехпроводка - не актуально для ТС.
При передаче каждого байта проверяем свой входной буфер. Там должна быть копия только что переданного байта. Если нет - то возникла коллизия. Останавливаемся и ждем опять таймаут. Для каждого модуля величина таймаута, как выше предлагалось, зависит от айди. Должно работать, но только при двухпроводном подключении, когда есть возможность прослушать самого себя.
А одновременная передача 2-х девайсов может существовать? Вот это и есть коллизия. Но она, и как её решать, действительно не описана. И это понятно, т.к 485-й протокол исключительно физ. уровня. В нем и не должно быть о колизиях больше чем физ. уровень, т.е. при возникновении колизии ни один элемент сети не сгорит.
О коллизиях уместно говорить в Ethernet, CAN, но не в RS-485.
в RS-485 бессмысленно "слушать" самого себя, т.к. кто "говорит", тот "слышит" только себя и ни кого больше, для него нет никаких коллизий.
А вы лично это проверяли? И на каких микрухах? На сколько я сталкивался с 485, так там даже неправильный терминатор не дает нормально работать. Жаль, у меня сейчас нет на чем проверить, но интересно было бы в реале все откатать. Но, исходя из даташитов на микрухи, я на 99% уверен, что вы ошибаетесь и коллизии таки будут и в собственном приемнике мы увидим не эхо посланого байта, а другие данные. Вот отмакетировал в Протеусе - так и есть. Когда BAD_ENABLE разрешает передавать помеху, то в MASTER_ECHO вместо сигнала SEND возвращается мусор. По спецификации 485 интерфейса сигнал воспринимается как 1 когда (А-В) больше 200мв, а как 0 когда (А-В) меньше чем -200мв. В случае одновременной трансляции несколькими микрухами итоговое напряжение на входе приемника будет суммой напряжений от всех передатчиков, что дает неопределенный результат, т.е. приемник его может распознать и как 1 и как 0. Но нам важно лишь то, что мастер не получит у себя на RX то, что послал в TX - соотв. он распознает коллизию.