Страница 1 из 5

avr modbus вопросы

Добавлено: Пт сен 02, 2016 06:10:42
alex38779
Добрый день!

Столкнулся с проблемой, хочу реализовать сеть rs-485, т.е будет мастер и слейв, мастер - примерно atmega328(либо какая по мощней), слейвы - около 25 шт атмег8(будут считывать температуру и слать когда нужно раз в минуту или две). В данный момент мне нужно сделать заготовку мастер и 4 датчика, проверить в работе.

Это все будет на предприятии, система управления отоплением.

Протокол выбран modbus, т.к. очень распространен.

В качестве реализации протокола для слейв устройств выбран FreeModbus http://www.freemodbus.org/index.php , ее скачал, примеры есть, документация есть. Разберусь.

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

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 06:25:34
Vov123
По моему мнению, реализация modbus на микроконтроллере оправдана когда подключается к стандартному устройству работающему в данном режиме, PLC, например.
А если используются не стандартные устройства, то, вероятно, и подойти к этой проблеме можно нестандартно, то-есть упрощённо.
Сидит slave в режиме ожидания прерывания. Приходит запрос с определённым именем (адресом) от master, slave сравнивает и, если это адресовано ему, отправляет необходимую информацию.
А самоё главное, на производстве надо использовать лицензированное, заводское оборудование. А то, не дай Бог...

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 07:01:24
tuxxas
Можно использовать SimpleModbusMaster.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 08:20:10
Alkul
alex38779 писал(а):Протокол выбран modbus, т.к. очень распространен.
данная библиотек не может реализовать функцию мастера
Выше правильно сказали, зачем именно Modbus? Зачем какая-то библиотека?

Разрабатываете протокол обмена, например, такой:

Мастер посылает команду вида

| ADR | CMD | LEN | DATA | CRC | , где

ADR - адрес слейва, CMD - код команды, LEN - длина пакета, DATA - массив данных (могут отсутствовать), CRC - циклический избыточный код для контроля корректности пакета

Эту команду получают все слейвы, но отвечает только тот, чей адрес совпал с полем ADR. Формат пакета ответа слейва может быть точно таким же, что и формат пакета команды, а может отличаться, имея, к примеру, вид:

| ADR | CMD | LEN | STAT | DATA | CRC | , где

ADR - адрес отвечающего слейва, CMD - код команды, на которую отвечает слейв, LEN - длина пакета, STAT - байт статуса, в котором биты могут обозначать текущее состояние слейва (исправен/неисправен термодатчик, целостна ли EEPROM и т.д.). DATA - данные, если они есть (например, передаваемая температура или иной параметр).

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

Например, код команды 0x01 - это код проверки наличия слейва.
В начале работы мастер последовательно передает пакеты вида
| ADR | 0x01 | 0x05 | CRC | (считая CRC двухбайтным)
при этом мастер в поле ADR перебирает все адреса от 0х01 до 0хFF.

Слейв, получив пакет со "своим" адресом, отвечает
| ADR | 0x01 | 0x06 | STAT | CRC | , указывая в поле STAT текущую информацию о своем состоянии.

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


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


Ну вот примерно как-то так... Если нужны подробности - спрашивайте.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 08:26:52
alex38779
Модбас выбрал потому что это как бы стандарт, и много устройств работают на этом протоколе.

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

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 08:44:54
Alkul
alex38779 писал(а):Модбас выбрал потому что это как бы стандарт, и много устройств работают на этом протоколе.
Верно, но Modbus - это протокол, "заточенный", главным образом, под АСУТП. Команды Modbus запрашивают информацию из регистров со стандартизированными адресами.
И реализовывать именно Modbus есть смысл, если в сети уже есть другие устройства, работающие по этому стандарту.
Если же вы делаете свою сеть, сами делаете и мастера, и слейвы, то какой смысл в точном следовании стандарту?

Тот пример, что я Вам показал, я называю Modbus-подобный протокол.

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

Самый простой пример - в реализации обмена не сделан учет времени приема пакета. Тогда возможна следующая ситуация - если в процессе ожидания слейвом команды из-за помехи в линии был детектирован ошибочный байт, он записался у слейва первым в буфере приема. После этого начался прием нормального пакета, при этом первый байт пакета записался в буфере приема вторым и т.д. Тогда при приеме предпоследнего байта пакета количество принятых байт станет равным длине пакета, для него рассчитается CRC, естественно, возникнет ошибка и пакет будет отброшен, как неверный, но после этого придет последний байт пакета и запишется первым в буфере приема. Все. Дальше обмен работать не будет, ибо абсолютно все пакеты будут отбрасываться по показанному выше алгоритму.
alex38779 писал(а):В теории можно сделать свой протокол
Не думаю, что это будет сложнее, чем адаптировать ваши данные и команды под стандартный Modbus.
alex38779 писал(а):но у меня возникнут трудности в написании программы
Возникнут трудности - всегда можно задать вопрос.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 10:01:46
alex38779
С программной частью стало более менее понятней) А как быть с железом.

В общем длина линии RS-485 будет примерно ~500-600 м, через каждые 50 м будут стоять датчики. около 25 штук, точно еще не известно. На концы линий по резистору 120 Ом.

Планирую так микроконтроллер - max487 - сеть.

Взять витую пару экранированную, по двум жилам пустить A и B, по 2м другим 5 вольт для питания датчиков, по остальным минус. Max 487 в момент передачи будет кушать большой ток, поэтому для датчиков отдельный мощный бп на 5 вольт.

Что скажете по этому поводу?

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 10:02:19
Jack_A
Модбасов мне известно как минимум 3: ASCII, RTU, Modbus+, и от того, какой выбран, зависит реализация. Согласен с Alkul : к Modbus'у в чистом виде стремиться не стоит, он заточен на работу с конкретными линейками АСУТПшного оборудования. а Modbus - подобный по 485-му, и по 232-му у меня успешно работал на добром десятке проектов. Только у меня начало по другому было: ДЛИНА - АДРЕС -....
alex38779 писал(а): Что скажете по этому поводу?
Я не возражаю :)

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 10:23:33
Alkul
alex38779 писал(а):В общем длина линии RS-485 будет примерно ~500-600 м, через каждые 50 м будут стоять датчики. около 25 штук, точно еще не известно. На концы линий по резистору 120 Ом.
По стандарту интерфейс RS-485 допускает работу при длине линий связи до 4000 футов (1200 м).
На каком расстоянии друг от друга стоят устройства - неважно.
alex38779 писал(а):Планирую так микроконтроллер - max487 - сеть.
Чем не устраивает старая добрая ADM1485?
alex38779 писал(а):Взять витую пару экранированную, по двум жилам пустить A и B, по 2м другим 5 вольт для питания датчиков, по остальным минус.
Нормально. Только сеть должна быть без разрывов.
Вот здесь посмотрите мое сообщение от 15.08.2015, там я давал рисунок - схему сети. Если используете UTP, удобно сделать так, как я нарисовал. Чтобы не делать "штаны", когда из одного разъема два кабеля выходят.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 10:29:03
Alkul
Jack_A писал(а):Только у меня начало по другому было: ДЛИНА - АДРЕС -....
Ну, тут не суть важно, когда корректировать длину принимаемого пакета - на первом байте или на третьем :)

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 10:42:40
alex38779
Alkul писал(а): Чем не устраивает старая добрая ADM1485?
Есть такие ADM485AN.
Взял какие были в интернет магазине..
Нормально. Только сеть должна быть без разрывов.
Глянул, хорошая идея! Буду делать так же!

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 11:57:30
Alkul
alex38779 писал(а):хорошая идея! Буду делать так же!
Пользуйтесь. Удачи!

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 12:14:45
alex_
Тоже собираюсь заняться этим интерфейсом
Alkul писал(а):Самый простой пример - в реализации обмена не сделан учет времени приема пакета. Тогда возможна следующая ситуация - если в процессе ожидания слейвом команды из-за помехи в линии был детектирован ошибочный байт, он записался у слейва первым в буфере приема. . .
Ну тут всё же лучше сделать ограничение по времени на пакет, можно ещё добавить преамбулу(любой символ, лучше из спец: $# чтоб не часто встречался) с которого будет начинаться пакет. И при приёме пакет начинать именно с этого символа, а всё что пришло до этого символа просто откидывать. :)

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 12:22:19
Alkul
alex_ писал(а):Ну тут всё же лучше сделать ограничение по времени на пакет
Не на пакет. Нужно делать ограничение, равное полуторному времени приема байта для выбранной скорости передачи.
Прием каждого следующего байта перезапускает таймер снова на 1,5 времени приема байта. Время обработки при приеме байта, в том числе и последнего байта, когда подсчитывается CRC пакета, должно быть меньше 0,5 времени приема байта.
Если с момента приема байта прошло 1,5 времени, то вызванное прерывание таймера сбрасывает буфер приема и обнуляет кол-во принятых байт.
При штатной же работе этот таймер вызываться не должен, ибо после расчета CRC пакета этот таймер должен быть остановлен.
alex_ писал(а):любой символ, лучше из спец: $#
Решение пригодно только для ASCII- формата кадров. Если передаются бинарные данные, то там возможны любые комбинации , особенно в блоках данных.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 12:24:06
Jack_A
Alkul писал(а): Ну, тут не суть важно, когда корректировать длину принимаемого пакета - на первом байте или на третьем :)
У меня конец пакета определялся по тайм-ауту. Что касается 1,5 времени приема байта - я выбирал этот интервал побольше. Если обмен идет в сети МК - нормально, но если в сети ПК с не-реалтаймовой виндой, то шевеление мышкой или еще что -- может тормознуть передачу. Не спорю - скорость обмена не била рекорды, но для моих задач сеть была не первостепенного значения. Могут возразить - задаче работы в сети нужно присвоить наивысший приоритет, но тут мы уже лезем в системные дебри.
Длина - дополнительный признак, позволяющий, к примеру, разделять "слипшиеся" пакеты.
СпойлерНа первом этапе "апупеи" РС-шную часть писал другой молодой вьюноша, и для него это оказывалось нужным. Когда затем мое участие в проектах плавно переросло от написания прог для МК к " с нуля - до 'под ключ' " без существенного улучшения "суммы прописью" :( , менять работающий протокол не было резона.
Если передаются бинарные данные, то там возможны любые комбинации , особенно в блоках данных.
Это тоже решаемо, к примеру, байт-стаффингом, но чересчур уж замысловато получается; и без того передавать бинарные данные HEX-парой чересчур затратно.

Re: avr modbus вопросы

Добавлено: Пт сен 02, 2016 12:29:31
Alkul
Jack_A писал(а):У меня конец пакета определялся по тайм-ауту
Я раньше также делал. Потом перешел на побайтный контроль. Минус первого решения - время приема пакета априори больше, чем время приема байта. Соответственно, ошибочно принятый байт будет распознан и ликвидирован позже.
Например, при скорости передачи 9600 и 10-ти байтном пакете при побайтном контроле ошибка будет исправлена через 1,5 мс, а при тайм-ауте по приему пакета - минимум через 10 мс. Если же после приема "ложного" байта прием корректного пакета начнется раньше, чем 10 мс, то этот пакет не будет корректно принят.
Побайтный контроль быстрее "очищает" интерфейс от помех и сбоев.

Re: avr modbus вопросы

Добавлено: Сб сен 03, 2016 07:15:40
Z_h_e
Alkul писал(а):По стандарту интерфейс RS-485 допускает работу при длине линий связи до 4000 футов (1200 м).
На каком расстоянии друг от друга стоят устройства - неважно.
СпойлерИзображение
Допустимая длина линии будет ограничена в основном емкостью линии и скоростью передачи.
alex38779 писал(а):Взять витую пару экранированную, по двум жилам пустить A и B, по 2м другим 5 вольт для питания датчиков, по остальным минус.
Не упустите такой важный момент. Пускай каждое устройство потребляет 0,1 А. В итоге 0,1*25=2,5А. Пускай сопротивление жилы витой пары 0.1 Ом/м. Итого сопротивление спаренного провода +Пит длиной 600 м будет 30 Ом. Падение напряжение при токе 2,5А будет 75В. У Вас еще есть нулевой проводник, на котором будет тоже какое-то падение напряжения, добавочно. Падение напряжения на нулевом проводе плохо тем еще, что получается каждый МК у Вас будет сидеть на разном значении нулевого потенциала. Т.е. "0" первого МК и последнего может отличаться на много вольт. Этот расчет конечно неверный, т.к. потребители раскиданы по кабелю, а не на концах его. Но цифры все равно могут быть большими.

Re: avr modbus вопросы

Добавлено: Сб сен 03, 2016 18:15:46
Alkul
Z_h_e писал(а):
Alkul писал(а):По стандарту интерфейс RS-485 допускает работу при длине линий связи до 4000 футов (1200 м).
Допустимая длина линии будет ограничена в основном емкостью линии и скоростью передачи.
Читать теорию - это очень похвально. Но, кроме теории, есть и практика.
Надо читать даташиты на конкретные микросхемы драйверов. Вот Вам примеры из даташитов разных микросхем:
ADM1485.jpg
(185.88 КБ) 610 скачиваний
MAX1480.jpg
(148.18 КБ) 587 скачиваний
Везде черным по белому указана максимальная длина линии связи, на которой производитель гарантирует работоспособность интерфейса. Безусловно, что чем выше длина линии связи, тем меньше максимальная скорость передачи.
Z_h_e писал(а):Пускай каждое устройство потребляет 0,1 А. В итоге 0,1*25=2,5А.
Автор упомянул, что собирается делать термодатчики. Если он будет использовать распространенные DS18B20, то у них ток потребления единицы миллиампер, столько же у МК. Еще на сам драйвер десяток миллиампер добавить. В итоге вряд ли больше 30 мА один слейв будет потреблять, и то только в момент передачи, а передавать одновременно слейвы не будут по определению.

А если суммарный ток потребления слейвов будет приближаться хотя бы к 1 А, то это уже надо индивидуальное питание слейвам делать.

Re: avr modbus вопросы

Добавлено: Сб сен 03, 2016 18:23:20
Z_h_e
Alkul писал(а):Читать теорию - это очень похвально. Но, кроме теории, есть и практика.
Надо читать даташиты на конкретные микросхемы драйверов. Вот Вам примеры из даташитов разных микросхем:
Несомненно надо учитывать элементную базу и прочие факторы. Никто вроде прочего не заявлял. Просто Вы заявили "по стандарту", а это не так.
Alkul писал(а):Автор упомянул, что собирается делать термодатчики. Если он будет использовать...
Я просто указал ТС важный момент, который нельзя упускать.

Re: avr modbus вопросы

Добавлено: Сб сен 03, 2016 18:48:24
Alkul
Z_h_e писал(а):Просто Вы заявили "по стандарту", а это не так.
Простите, откуда Вы взяли приведенный скрин "стандарта"?
В нем указаны какие-то странные вещи. Например, максимальное количество устройств указано как 32.
Но, простите, драйверы RS-485/422 характеризуются т.н. "нагрузочной способностью". Драйверы "единичной нагрузки", действительно, допускают существование только 32 устройств на одной шине.
Но, например, драйвер ADM2484, который мне приходилось использовать в разработках, имеет "одну четвертую нагрузки" (простите за жаргон) и допускает существование 256 устройств на шине
ADM2484.jpg
(148.19 КБ) 315 скачиваний
Вы хотите сказать, что эта микросхема не соответствует стандарту?