Вопросы про RS485 вообще и MAX485 в частности

Чечако
Offline
Зарегистрирован: 15.06.2018

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

 

1. Топология. Везде рекомендуется последовательная шина. Беда в том, что для меня она неудобна по компоновке. Вот прям вообще. Нужна звезда. Лучей будет до десяти, максимальная длина одного луча метра три. Возможно такое, или при таком раскладе о RS485 можно забывать сразу? На передатчике будет использоваться аппаратный Serial, на приемниках - Software, если это важно.

 

2. Правильно ли я понимаю, что если у меня один модуль всегда только передает, а другие только принимают - на передатчике мне достаточно управлять ногой DE, не трогая RE, а на приемниках соответственно достаточно только RE, не трогая DE? На практике оно так работает, но правильно ли это?

 

3. Какая МИНИМАЛЬНАЯ обвязка нужна чипу MAX485 для корректной работы? Конкретно смотрю на исполнение MAX485EPA+. Я погуглил - кто-то вообще голый чип использует. Габариты мне критичны, но только на приемниках, на передатчике места вагон. 

 

4. Все-таки два или три провода гнать? Сейчас тестирую на двух, но встречал рекомендации объединять и землю на модулях для лучшей помехоустойчивости. 

 

Заранее спасибо за ответы. :)

GarryC
Offline
Зарегистрирован: 08.08.2016

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

2. Что такое управлять ? Если дергать, то необязательно обе ноги, но к потенциалу обязательно притянуть обе.

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

4. Если соедините земли, то уменьшится синфазная помеха, что может повысить устойчивость работы. Но может возникнуть контур  земли, что снизит устойчивость работы. Если разность земель на превосходит 1В, лучше не надо.

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

3. Минимально это кондёр по питанию (обязательно), рядом с МС. Остальное при необходимости. У меня сеть
из пяти устройств  работала без терминаторов, длина шины метров 20.
 4. Для лучшей помехоустойчивости ещё рекомендуют подтянуть шины к + и - , это есть в описании.

sadman41
Offline
Зарегистрирован: 19.10.2016

В каком-то патенте на соединение звездой CAN-шины, я видел схематический чертеж соединения. На нем лучи заходят через ферритовые бусины на один общий терминатор, который висит в районе центрального узла. В принципе и в CAN и в RS-485 диффпара - так что можно взять способ на заметку.

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

 Для RS485 есть повторители и разветвители.

Чечако
Offline
Зарегистрирован: 15.06.2018

GarryC пишет:

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

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

Чечако
Offline
Зарегистрирован: 15.06.2018

sadman41 пишет:

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

По идее у меня и получится один общий терминатор. Без феррита разве что. А как оно будет жить - тестить надо. 

ВН
Offline
Зарегистрирован: 25.02.2016

1. решается двумя витыми парами в кабеле, одна прямая вторая возвратная

2. это собственно половина  RS-422, где она пара на прием, вторая на передачу, передатчики 485 могут вполне использаоваться. как описано

3. если передатчик всегда активен, можно обойтись только терминаторами на концах линии.

4. зависит от конфмгурации "земли" , развязаны гальванически источники питания модулей или нет. Обычно соединяют не проводом, а экраном и тоже через 100-120 ом. 

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

3 метра??? Это смешно.
Народ собирает в звезду десятки-сотни метров.
PTZ камеры и системы доступа.
Скорости обычно 2400 у камер и 9600 у доступа.
Сам недавно собрал:
40 метров вверх по шахте витой парой 12 контроллеров,
затем развилка на 2 кабеля вниз тоже метров 50 уже по плоскому силовому подвесному кабелю 20х0.75 квадрата.
В кабеле рядом и 220 и всё что угодно
На каждом конце по контроллеру и по 120 Ом.
Хотя и без них работало, но раз надо то и установил для порядка...

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Очень много делаю на MAX485 всяких устройств на ATMEGA собирая их в единую шину на скорости 9600

Особых проблем нет,можно ничего не делать по железу , если ваше ПО будет следить за посылками по принципу

1.Запрос с контрольной суммой от мастера.

2.Прием слейвом , проверка на контрольную сумму , при совпадении ответ тоже с контрольной суммой

3.Прием мастером ответа (или его отсутствие), проверка контрольной суммы, принятие решения (посылка повтора, следующий пакет и т.д) 

По железу рекомендую, совершенству тут нет предела

1. Подтяжка к питанию на главном контроллере 20К для пущей убедительности 

2. Резистор 120 Ом на два саммых удаленных устройства в сетке (стараюсь ставить их на всех устройствах с микровыключателем),  обнаружил что МАХ485 имеют большой разброс по шумам и способностью бороться с отраженными волнами в сети . 

Поэтому для тестирования сети напишите простейшую программу где главный контроллер поочередно спрашивает всех клиентов , а те отвечают на запрос. Считаете корректно принятые запросы-ответы Потом смотришь кол-во выпавших посылок по каждому устройству + посмотреть шину/пины TX-RX на процессорах устроств осцилографом при серьезных сбоях и там где большее кол-во потерь. 

Если есть сбои, повыбирать оптимальный вариант из 2 устройств в сети где активирован 120 Ом и/или найти "шумящую" МАХ485.  

3. На растояниях до 20 метров от центрального устройства смело можно собирать в звезду.

Чечако
Offline
Зарегистрирован: 15.06.2018

Подниму свою же тему, с одним вопросом - правильно ли я понимаю, что в моем случае - один передатчик в роежиме "все для всех" и десяток приемников и топология типа "звезда" при длине лучей не более 3 метров, резисторы 120Ом мне нужно ставить только у приемников, передатчику он нафиг не сдался?

Еще раз уточняю - передатчик только передает и никогда не слушает, приемники только слушают и никогда не передают.

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Да в принципе можно ничего не ставить , особого эфекта на коротких линиях резистор 120 не дает.

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

То что у вас не контролируется получение команды приемником , не есть хорошо.

Хотя за 1 сек можно передать раз 10 команду на исполнителя , может и не критично

 

Чечако
Offline
Зарегистрирован: 15.06.2018

fimin пишет:

То что у вас не контролируется получение команды приемником , не есть хорошо.

Хотя за 1 сек можно передать раз 10 команду на исполнителя , может и не критично

Раз 30, я бы сказал. :) Там не исполнитель, а устройство отображения данных. Некоторый процент потерь пакетов вообще не критичен. 

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

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

Я в свое время расковырял несколько протоколов у американских систем контроля и управления и взял на вооружение их технологии организации работы сеток   

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

Чечако
Offline
Зарегистрирован: 15.06.2018

fimin пишет:

Ну тогда и не заморачиваться .  Там есть только еще один тонкий вопрос - а если приемник начал принимать по каким то причинам не с 1 байта посылку.  

Над протоколом я как раз сейчас думаю. На данный момент у меня есть два символа начала пакета, потом сам пакет, потом символ окончания пакета.

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

Надо будет добавить какой-то контроль целостности пакета, типа контрольного байта, который вычисляемый.

Вариант с паузами не подходит, поскольку у передатчика есть другие функции, кроме непосредственно передачи. Выдержать их (паузы) точно можно будет только в ущерб другому функционалу. А он не менее важен.

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Я использую структуру постоянного пакета  8 или 12 байт

2 первых стартовые 255,255 , третий - адрес приемника . Потом передаю данные и последний байт сумма всех байтов  без стартовых , как контрольное число

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

Если посылка длинная , я бы разбил ее на куски  и потом срастил на приемнике.   

Чечако
Offline
Зарегистрирован: 15.06.2018

fimin пишет:

Если посылка длинная , я бы разбил ее на куски  и потом срастил на приемнике.   

16 байт без учета признаков начала и конца пакета. Так что можно не бить, imho. По идее могу ужаться в 8, но пока не понимаю, есть ли необходимость. Контрольную сумму вероятно также сделаю.

Логика у меня чуть сложнее. У меня в этих 16 байтах первым идут 4 байта названия пакета. На приемнике выбирается, какие именно пакеты ему нужны в данный момент, и если это не то, то дальше он все пропускает мимо ушей до начала следующего пакета.

Но вообще, это мы уже в программные вопросы свалились. :)

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Не советую так же (сложением) делать. Возьмите хотя бы далласовский CRC8. 

Чечако
Offline
Зарегистрирован: 15.06.2018

sadman41 пишет:

Не советую так же (сложением) делать. Возьмите хотя бы далласовский CRC8. 

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

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Так основные проблемы возникают именно с протоколом а не 485 сетью , Хорошая земля MAX485, кондер на 0,1 uF  рядом и все само поедет. А с протоколом я в свое время намучался. К примеру ваша ситуация . Посылка в 16 байт займет примерно 16,4 мСек, Буфер в 328 проце насколько я помню 64 байта , подтверждения от приемника нет. Мастер постоянно шлет пакеты, а приемник в силу длинног цикла (например 1 сек) не успевает их забирать из буфера. Буфер забивается и все встает, новым посылкам некуда залесть.Хорошо если у вас кратность 4-8-16 и т.д. байтов.  А если как у вас 16+3 служебных байта , то в буфере останется осколок посылки , который собьет работу  узла проверки стартовых байтов и надо будет делать сдвиговую коректировку. В начале пути с 485 я на временных интервалах здорово подорвался , пытаясь найти брак в железе, имея дырку в своей голове. Цикл приемников должен быть быстрее чем у мастера  или мастер посылает посылки  по расписанию. Контрольный бит создавайте любым удобным способом/методом, лишь бы он был. Американцы не парятся в своих протоколах и применяют на коротких посылках банальное сложение , если надо то просто задваивают байты. Мы же не делаем передачу команды на пуск балистической ракеты :-) 

Чечако
Offline
Зарегистрирован: 15.06.2018

fimin пишет:

Буфер в 328 проце насколько я помню 64 байта , подтверждения от приемника нет. Мастер постоянно шлет пакеты, а приемник в силу длинног цикла (например 1 сек) не успевает их забирать из буфера. Буфер забивается и все встает

Интересно. Так а в буфере будут не последние 64 байта, а первые? Я думал, он перезаписывается, если его не чистят.

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

Про сдвиг так и не понял, ну если раз сбой произойдёт -  один раз сдвинется , КС не совпадёт, принимающий игнорирует это сообщение. (т.е. опять будет искать заголовок, вычитывая байты просто так, тем самым освободит буфер). Как этот сдвиг дальше то будет влиять? дальше МК  успешно найдет заголовок, вычитает сообщение и всё пойдёт хорошо. 

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Насколько я знаю , все внутренние буфера работаю по принципу FIFO, если кто то знает как это можно изменить , был бы признателен

Прямой команды очистки буфера я не нашел , хотя для меня это просто хобби , может плохо искал. Я просто вычисляю сколько байт забрать из буфера и выкинуть , чтобы следующий байт в буфере был стартовым, командой  Serial.readBytes ( _ buf, x),  где х - кол-во байт которые надо вытянуть. При правильных временных задержках , о которых я писал выше , все просто замечательно работает.

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

СНачала я так и делал , но напрягало что делаешь несколько циклов чтобы поймать стартовый байт. Процессор обычно чем то еще занят помимо приема данных.

ПОтом придумал другую схему. Читаю сразу пакет (например 8 байтов) , если первый байт не стартовый , ищу в посылке , где он оказался и сразу за одно действие вытягиваю лишнюю информацию из буфера. СЛедующий байт в буфере гарантировано первый.

ТРачу всего 1 цикл 

sadman41
Offline
Зарегистрирован: 19.10.2016

Возьмите CAN и не напрягайтесь. А коль связались с тупым байтстримом - пишите весь транспортный уровень самостоятельно.

 

Чечако
Offline
Зарегистрирован: 15.06.2018

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

В качестве старт и стоп байтов встречал в сети рекомендацию использовать 0xAA и 0x55, поскольку случайно помехе так углючится сложно, а вот повредить легко.

Вот тут встречал:

http://www.avrki.ru/articles/content/protokol/

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

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

Печальный мужчина 41

Шина CAN хороша , но слабо используется в промышленной автоматике. 485 шина дереванная и довольно надежная, не зря ее взяли за промышленный стандарт. То что нет нормальной библиотеки в Ардуино, которая сама решает все эти мелкие проблемы, так это вопрос к проффесионалам. Мы то так, мыши серые, ковыряемся потихоньку ,чтобы водку не пьянствовать и безобразия не творить

Для меня это точно не бизнес  

Чечако
Offline
Зарегистрирован: 15.06.2018

fimin пишет:

 485 шина дереванная и довольно надежная, не зря ее взяли за промышленный стандарт. То что нет нормальной библиотеки в Ардуино, которая сама решает все эти мелкие проблемы, так это вопрос к проффесионалам. 

Вот как раз для профессионального оборудования есть Modbus, и библиотеки под него для arduino также есть, причем в количестве.  Но мне он банально избыточен.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Да я не против протокола ModBus, он может использовать ту же сеть 485 . Мне только его негде использовать , да и избыточен он для меня. К сожалению нигде его не встречал в профоборудовании. Обычно каждая фирма использует свой , чаще всего закрытый протокол

 

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

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

Про промышленные применения посмотрите здесь https://www.owen.ru/manuals

Например https://www.owen.ru/uploads/122/re_trm212_1ru-20892-1.3.pdf .

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

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Я же писал выше, что начинал все это с американским оборудованием Aplied Digital ,  у них свой протокол, 8 байт посылка из которой 3 служебных ( 2 старта, 1 контроль), байт адреса, байт команды, 3 байта данных.  Да он похож на модбас , но они все похожи, суть то передачи данных не меняется. Нужем старт, адрес,команда, данные , контроль.  В модбасе большой пакет данных , он избыточен для меня и не совместим с тем чем я занимаюсь.

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

Да нет, что вы. Я не настаиваю. Меня коробит от слов "В модбасе большой пакет данных". Там размер данных настраиваемый в момент посылки. Можно отсылать одно 16 битное слово. В сумме получится 6 байт посылки со всеми служебными полями.   

MaksVV
Offline
Зарегистрирован: 06.08.2015

fimin пишет:

СНачала я так и делал , но напрягало что делаешь несколько циклов чтобы поймать стартовый байт. Процессор обычно чем то еще занят помимо приема данных.

както тестил один блок управления. Дак вот он в диагностику периодически сыплет таким сообщением:

55 40 04 25 00 00 05 5A 48 45 00 00 0E 43 91 90 43 00 58 00 AA 00 0B 0B 80 02 85 09 00 1C 00 04 C1 00 BA 52 01 01 90 02 4A

Я выделил жирным необходимые байты для приёма ардуиной такого сообщения. 

Первые три - стартовые байты, далее 0x25 - количество последующих байт. последний байт - КС - просто сложение. На коленке был сделан скетч, но работает вроде стабильно, к тому же не задерживает (delay отсутствует) основную программу атмеги. 

Может кому пригодится такой алгоритм обмена данными. 



#include <SoftwareSerial.h>

SoftwareSerial K_LINE(7,8 ); // RX, TX


byte header = 0;          // сосояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 0;               // инкремент
const byte bufsize = 100; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения

byte waitbyte_time = 1;   // задержка, мс для успевания заполнения буфера RX (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
uint32_t timerdelay = 0;  // таймер ожидания байт (для успевания заполнения буфера УАРТ)
bool Delay = 0;           // таймер ожидания байт (для успевания заполнения буфера УАРТ)

byte crc =0;              // байт контрольной суммы 

#define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение таймера

void setup() {
Serial.begin(9600);
K_LINE.begin(9600);
}

void loop() {
 
 uint32_t curmillis = millis();
  
  if (K_LINE.available() ){
    

 // первый старт байт
 if (header == 0 && Delay){ if (K_LINE.read()==0x55){TIMER_DELAY ; header = 1; }}                  

 // второй старт байт
 if (header == 1 && Delay){ if (K_LINE.read()==0x40){TIMER_DELAY ; header = 2;} else header = 0; } 

 // третий старт байт
 if (header == 2 && Delay){ if (K_LINE.read()==0x04){TIMER_DELAY ; message_size = 0; header = 3; j=0; crc = 0;}else header = 0;}  

 // размер тела сообщения 
 if (header == 3 && Delay ) {message_size = K_LINE.read(); if (message_size > bufsize) message_size = bufsize; TIMER_DELAY ; header = 4;} 
 
 // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size) {
 buf[j] = K_LINE.read(); 
 if (j<message_size-1) crc+= buf[j]; // подсчёт КС
 if (j==message_size-1) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  Serial.println();  
if ( crc == buf[message_size-1]) {Serial.println("Received message is OK!" );}    // Если КС совпала, тут чёнибудь нужное  делаем
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; j=0; crc = 0;
}

if (!Delay && curmillis - timerdelay > waitbyte_time) Delay = 1; // таймер ожидания байт (для успевания заполнения буфера УАРТ)
  }


 

fimin
fimin аватар
Offline
Зарегистрирован: 24.01.2014

Еще раз предостережение о МАХ485. Может мне не повезло, когда то покупал 2 партии в Китае в разное время. При пуске очередного модуля обнаружил что теряется почти 75% пакетов. Это на отлаженном ПО (мастер -> запрос, приемник -> прием -> подтверждение , мастер - прием подтверждения,следующий цикл). Начал тупо передергивать микросхемы МАХ485(стояла панелька) и получил что 22 из 30 работают на любой линии без потерь хоть бухте 100 м , что на столе 30 см. 8 сбоят постоянно, никакие подтяжки и согласования не помогают. посмотрел осцилографом , очень большой шум приемника на стороне процессора, который сбивает пакеты . Такое ощущение что брателло с Китая продал просто отбраковку. (как то уже нарывался на конденсаторы,100% брак был). по внешнему виду разделить по партиям не смог, все вроде одинаково.

Seltvik
Seltvik аватар
Offline
Зарегистрирован: 24.10.2013

Есть вопрос по сети RS485. Можете помочь? Если вы еще обитаете на формуе то я опишу мистику в моей сети)