avatar_i

Универсальный протокол обмена между микроконтроллерными устройствами

Автор i, 04 Июнь 2011 в 13:34

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

detoxic

Цитата: zap от 07 Июнь 2011 в 16:59
У I2C перед LIN одни преимущества и никаких недостатков.
Теперь буду смотреть Modbus RTU.
а идвацэ на несколько метров протянете?
товарищи, все уже придумано и умнее нам с вами не сделать
если вы предпримите попытку выкинуть пусть 2 метра медной проволки с порта мк на улицу то готовтесь получить кучу сбоев, статика и ваша новая антенна все сделают, если будет жить, то засыплет ошибками, или будет досить всю шину
в сухом остатке только лин или rs485+modbus rtu - дешевле не куда, для работы по modbus достаточно сделать пару функций , а не поддержку всего протокола, +ваши поделки с компа будут видны
про модбас - 2 прерывания тх rx, служба времени  и + небольшой обработчик сообщений и ответов. все просто и коротко, листа 2-3 на си
равноправия не добъетесь - прямой хайвэй к коллизиям
для bms нужно использовать микросхемы специальные, у тогоже атмела есть
ATA6870 Li-Ion, NiMH Battery Measuring, Charge Balancing and Power-Supply Circuit
ATA6871 Li-Ion Battery Management Monitoring, Emergency and Backup Circuit
подобное есть у техаса и т.д.





трехфазный вентильный привод без магнитов - это реальность

zap

ATA6870 стоит $10 (это ещё без доставки, и хер достанешь) и таких надо три штуки на 16-ячеечную BMS. И с серией BQxxx от TI то же самое.
Всё как обычно - богатым и здоровым, или бедным и больным :)

Что же касается LIN и I2C, то они оба используют недифференциальную шину с открытым коллектором. Если у LIN и есть преимущество по помехозащищённости, то за счёт бОльших токов на шине, только и всего. И протокол там реально слишком сложный, одних ошибок штук двадцать разных. Их ещё и обработать надо, не? Ещё и мастер-мегамозг нужен чтобы рулить всей шиной. Ну и где здесь простота и дешевизна?
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

i

Цитата: zap от 07 Июнь 2011 в 18:38
....всё уже придумали до нас..
Вот это совершено точно.
Придумать, что то действительно новое, очень трудно (а порой мне кажется, что и невозможно.  :al: Сколько раз уж было, что придумаешь "конфетку", угробишь кучу времени, а радость недолгая получается - буквально на следующий день натыкаешься на старую статью, где всё это уже разжёвано).
Цитата: zap от 07 Июнь 2011 в 18:38
...обновляться данные на экране (по максимуму) где-то 4 раза в секунду...
Мне с такой скоростью не совладать - мельтешение получится. Пусть лучше каждый мк сам ведёт свою статистику, а уж потом, большим компом, можно не спеша вытянуть её, проанализировать, принять решение, внести изменения..
Да и много данных на оперативном экране  - это перебор. Ведь этот экран служит в основном для информирования водителя, что всё ОК (а решение об отключении при критических токах, все равно принимает предохранитель  :bk:). На дорогу надо смотреть, а не экран ИМХО.
Цитата: zap от 07 Июнь 2011 в 18:38
...шины должна быть занята не более чем на 10%, чтобы МК успевали заниматься ещё и другими делами кроме передачи данных...
А какие у него особые дела? Полиномы считать? (Не раз у меня получался пустой главный цикл, а вся работа делалась в прерываниях.) Можно ведь для рисования экрана взять крутую мегу и гонять её на полной скорости, а для измерения напряжения ячейки достаточно тихой тиньки, да и то, основное время она будет спать, единственная радость - по шине поболтать.
Не надо пугать себя чертями раньше времени. Вот встретится, тогда и поглядим... как ему пятачок начистить.

zap

Цитата: i от 08 Июнь 2011 в 10:30
Придумать, что то действительно новое, очень трудно (а порой мне кажется, что и невозможно.  :al: Сколько раз уж было, что придумаешь "конфетку", угробишь кучу времени, а радость недолгая получается - буквально на следующий день натыкаешься на старую статью, где всё это уже разжёвано).
Именно поэтому я и проверяю всё, что нам сюда подкидывают знающие люди :) Может даже если и не всё, то частично можно использовать куски других стандартов, или хотя бы идеи.

Цитата: i от 08 Июнь 2011 в 10:30
Цитата: zap от 07 Июнь 2011 в 18:38
...обновляться данные на экране (по максимуму) где-то 4 раза в секунду...
Мне с такой скоростью не совладать - мельтешение получится. Пусть лучше каждый мк сам ведёт свою статистику, а уж потом, большим компом, можно не спеша вытянуть её, проанализировать, принять решение, внести изменения..
Ну, представьте себе ситуацию: создали машину, теперь надо проехать на ней 1000 километров в режиме глубокого тестирования. Подключаем лаптоп к шине, и едем себе, а он себе складывает на винт данные со всех устройств на шине в реальном времени. А потом уже не спеша сидим и разбираемся - в каком месте чего глюкнуло.

Или, например, по некоторым параметрам можно рисовать графики. Глаз воспринимает график куда легче цифр, четыре раза в секунду - в самый раз. А некоторые параметры (к примеру, тяга) меняются достаточно резко - кому-то ещё и 4 раз в секунду будет мало :) Но я согласен, что это многовато - я специально подчёркивал, что беру требования по самой верхней планке, которую могу только себе представить.

Цитата: i от 08 Июнь 2011 в 10:30
Цитата: zap от 07 Июнь 2011 в 18:38
...шины должна быть занята не более чем на 10%, чтобы МК успевали заниматься ещё и другими делами кроме передачи данных...
А какие у него особые дела? Полиномы считать? (Не раз у меня получался пустой главный цикл, а вся работа делалась в прерываниях.)
Ну да, а в прерываниях, видимо, процессорное время не тратится :-). У меня в BMS, например, опрос 32х ячеек (на самом деле пока 16, но есть возможность расширения) занимает весьма ощутимое время. Причём на время работы ADC неплохо бы процессор погрузить в Idle режим, чтобы повысить точность. А контроллер мотора, например, вообще постоянно занят - проверяет фазный ток, расчитывает новую скважность ШИМ, проверяет состояние ручек и кнопок и так далее - и всё это в очень тугом цикле, чтобы ток не успел выйти за рамки. Если в какой-то момент цикл прервётся надолго (потму что кому-то на шине скучно, и ему просто захотелось поболтать :)), фазный ток может выйти из-под контроля.

Цитата: i от 08 Июнь 2011 в 10:30
Можно ведь для рисования экрана взять крутую мегу и гонять её на полной скорости, а для измерения напряжения ячейки достаточно тихой тиньки, да и то, основное время она будет спать, единственная радость - по шине поболтать.
Это не радость, а лишняя трата ресурсов. Лучше бы спала, меньше энергии бы жрала :) И вообще, это аксиома - все МК, которым нечего делать, должны спать. В этом отношении мне всё-таки очень нравится I2C, можно спать с открытыми глазами - отдельная часть схемы бдит, что там на шине происходит, и если кто-то нас окликнет, сразу просыпаемся. Все остальные варианты, увы, приводят к тому, что любая активность на шине "будит" разом всех учаснегов.

Хотя, возможно, я придаю излишнее значение этой проблеме из-за того, что в данный момент меня волнует именно аспект BMS, а его особенность в том, что он подключён к питанию всегда. Остальные же устройства, по идее, будут отключаться "мастер-рубильником", поэтому их потребление на фоне мотора будет теряться.

Цитата: i от 08 Июнь 2011 в 10:30
Не надо пугать себя чертями раньше времени. Вот встретится, тогда и поглядим... как ему пятачок начистить.
Угу, а когда встретимся, то окажется, что святую воду дома забыли :) плаваем, знаем.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

i

Цитата: zap от 08 Июнь 2011 в 10:51
Угу, а когда встретимся, то окажется, что святую воду дома забыли :) плаваем, знаем.
И такое бывает. А бывает и наоборот: святой воды хоть залейся, а чертей всё нет и нет... Законы Мерфи рулят.  :ap:
По любому с первого раза не пройти, придется покружиться, набит шишек, попалить детали... ну это как всегда.

detoxic

Цитата: zap от 07 Июнь 2011 в 19:55
ATA6870 стоит $10 (это ещё без доставки, и хер достанешь) и таких надо три штуки на 16-ячеечную BMS. И с серией BQxxx от TI то же самое.
техас вроде бы как в компеле есть и привезут если попросите, и цены в 5$
в техасе любимый i2c.
не надо усложнять, нужно по максимуму использовать готовые решения
оглянитесь вокруг - асуп на rs485 и CAN развернуты, в транспорт и в космос CAN монтируют

PS писать логи с modbus очень удобно, плюс софт уже на пк есть с фиксацией времени
трехфазный вентильный привод без магнитов - это реальность

zap

Цитата: detoxic от 08 Июнь 2011 в 11:36
PS писать логи с modbus очень удобно, плюс софт уже на пк есть с фиксацией времени
Предлагаемые Вами решения в разы дороже и хуже (ни одно из них не удовлетворяет предъявленным критериям, см. мой пост). Единственный плюс в том, что их можно применить относительно быстро. Это хорошо, когда ты эту работу делаешь за деньги и тебя поджимают сроки.

В нашем же случае речь идёт о хобби. Времени у нас дофига, можем себе позволить посидеть, подумать. А Вы нас подгоняете как будто завтра проект сдавать :D
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

detoxic

трансивер rs485 стоит 30рублей в терре и 15 рублей в платане. например SN65176 SN75176, modbus сверху бесплатно,
если это дорого, то тогда надо начинать МК из песка детской песочницы самим печь. времени дофига садомазохобби,
но согласитесь, глупо время своей жизни оценить ниже 30 рублей!!! пусть вы убьете пару вечеров на свои поделки
когда выбирается интерфейс, то проектировщиком определяют объемы скорость расстояния, и уже все стает ясно, что и как надо  - потом уж просто или не просто дорого или не дорого
требования к равноправию участников в шине - путь в тупик, потому-что  это фактически мультимастеринг. над арбитражем вы голову сломаете и не получите ничего полезного ибо
по физике на одной линии два и более источников сигнала будут влиять друг на друга, каша в линии будет а не данные


трехфазный вентильный привод без магнитов - это реальность

i


detoxic

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

zap

Мне-то как раз в данный момент RS485 больше всего и нравится. И, скорее всего, протокол который бы мне понравился будет весьма близок к Modbus, но меня не устраивает схема ведущий-ведомые. Это и необходимость в дополнительном арбитре шины (а это уже не 30 рублей), и тормоза при инициации передачи со стороны устройств и так далее. Вообще, Modbus весьма похож на мой протокол (см. первый пост), только он бессмысленно усложнён (а простота протокола это залог короткой реализации) и многословнее (а это залог пропускной способности).

CAN и I2C в режиме multi-master это равноправие с приоритетами. "Все звери равны, но некоторые равнее". Это гораздо лучше, чем патриархальная схема, по которой пацаки говорят только по кивку чатланина (а если чатланин сгорел? завис? отвалился участок шины?).

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

Кстати, в схеме "автоматического" арбитража на шине CAN/I2C меня всегда смущала одна вещь: что будет, если два устройства начнут "говорить" не со смещением в ровное количество бит (как это красиво выглядит на картинках), а со смещением в дробное количество бит (как оно и происходит в реальности).
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

i

2detoxic
Приоритет присваивается не устройству, а сообщению. Сигнал "Пожар!" должен иметь бОльший приоритет, чем сигнал "Температура за бортом..".
2zap
Передача разрешена только при свободной шине. После фиксации этого состояния, два оратора могут начать бубнить, смещение у них может быть только на долю первого старт-бита (на время реакции мк на перепад на шине), далее они уже синхронизируются. Оба будут бубнить хором до тех пор пока их биты совпадают, после кто-то попытается передать "1", а получит "0" и прекратит передачу, а оставшийся и не заметит, что кто-то ему пытался мешать.

detoxic

трехфазный вентильный привод без магнитов - это реальность

zap

Ладно, в общем вот что пока придумывается. Рабочее название шины: e-Bus (по аналогии с e-Bike и e-Vehicle :bj:)

Во-первых строках сего письма хотелось бы разобраться с терминологией. Чтобы не было путаницы, предлагаю использовать термины из стандартной модели OSI. В этой терминологии интересующий нас протокол обмена покрывает уровни 1 (физический т.е. электронную реализацию) и 2 (канальный т.е. физическая адресация и первичный контроль целостности). Для наших целей реализация уровней со второго по шестой не имеет смысла, нам нужны только уровни 1, 2, 7.

Из всех вариантов физической реализации шины мне ближе всего стандарт RS-485, в двухпроводном (полудуплексном) режиме. Во-первых, трансиверы RS-485 существенно меньше жрут (отдельные трансиверы вообще по ~200 мкА), во-вторых здесь больше пространство для манёвра (канальный уровень не стандартизован, можно городить что-нибудь своё не нарушая ничьего покоя). В-третьих, RS-485 изначально подразумевает подключение большого количества клиентов к одной шине (соотв. трансиверы имеют функцию "перехода в Z-состояние" чтобы не мешать другим). В-четвёртых для любителей "заката солнца вручную" (;)) физический уровень RS485 можно симулировать без трансивера (голым микроконтроллером), дрыгая двумя ножками в противофазе (а в некоторых МК есть ещё и встроенный компаратор, который можно использовать для работы с настоящими дифф сигналами).

Со стороны микроконтроллера для управления такой шиной минимально необходимы три сигнала: RX, TX и сигнал переключения выхода в Z-состояние DE (Driver Enable). Сама шина, как говорилось выше, двухпроводная дифференциальная. Для сопряжения с шиной USB можно использовать стандартные USB->UART переходники, на торец которой насажен RS-485 трансивер. Для управления сигналом DE можно использовать сигнал RTS (Ready To Send), который есть у любой USB->UART микросхемы (к сожалению, не всегда выведено на штырьки, но это лечится несложной паяльной операцией).

Единственный минус RS-485 - отсутствие штатного механизма разрешения конфликтов в случае равноправного доступа клиентов к шине.

Здесь можно поступить следующим образом.

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

Тем не менее, каждое устройство следит за состоянием шины и поддерживает флаг занятости шины. Старт передачи возможен только в случае, если шина не занята. Шина считается занятой в течении двух символьных интервалов (т.е. времени, достаточного для передачи двух символов) после того, как любое устройство выдало какой-нибудь байт на шину (даже с ошибкой). Проще говоря, при получении приёмником любого символа (даже с ошибкой) микроконтроллер взводит таймер на длительность передачи двух символов (проще всего это сделать отключив вывод, DE=0, и передав самому два символа "в пустоту"). Если за это время на шине не обнаружено новых передач, МК взводит флаг "шина свободна". Если пауза >= 2 символа возникла во время приёма пакета, пакет считается оборванным и игнорируется.

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

Если же ему выпала "1", он выжидает 2 пустых интервала для того, чтобы все устройства, слушающие шину, сбросили пакет как оборванный. Затем он начинает передачу своего блока данных с самого начала.

Если во время повторной передачи опять возникает коллизия, устройство берёт кубик уже второго порядка (четыре грани, на трёх "0", на одной "1"), вероятность успеха 25%. После третьей коллизии берём кубик третьего порядка (8 граней, вероятность 12.5%) итд до какого-то разумного предела.

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

И ещё одно преимущество - возможность вмешаться в чужую передачу в случае необходимости передачи сообщения повышенной важности. Например, какие-то два устройства "от скуки" переписываются (по аське), а тут внезапно сигнал "Пожар!" а линия занята. В этом случае передающее устройство нагло влезает в разговор ("Аллё, это Рабинович"). Охреневшие переписчики замолкают и приступают к подбрасыванию кубика. А устройство у которого важное сообщение берёт на такой случай "читерский" кубик нулевого порядка, который всегда выдаёт единицу. Таким образом, он будет пытаться передать данные пока остальные не откажутся от своей дурной затеи. Правда, если два "Пожара" сцепятся рогами, то их потом от шины не оттащишь, тут тоже надо настойчивость проявлять в меру :) Кстати, таким образом вообще можно выстроить систему приоритетов сообщений - скажем, "обычные" сообщения начинают с кубика второго порядка, "важные сообщения" - с кубика первого порядка, "страшно важные" - с кубика нулевого порядка. И наоборот - "маловажные" сообщения начинают с кубика третьего порядка, например. Тут можно просимулировать всю эту катавасию программно, и посмотреть что получится.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

i

Возможно я ещё не проникся, но на первый взгляд выглядит несколько кудряво. Хотелось бы "взвесит" реализацию...

zap

Релизация будет минимальная (по сравнению с аналогичными протоколами). Я специально многие моменты продумывал так, чтобы можно было использовать один код на все случаи.
Для начала я попробую написать небольшую програмку, которая будет симулировать шину и энное количество клиентов, которые обмениваются данными. Чтобы можно было задавать частоту "регулярных" обменов и вероятность "случайных" обменов. Симулировать время с точностью до доли бита, возможностью симулировать шину "пошагово" и "как процесс".
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

jeka

Я бы подошел к вопросу протокола с формализации требований/функционала для конечного пользователя. И далее под эти требования создавал бы шину и протокол.
По поводу помехозащищенности - не было у меня проблем при торчащем 3.3v uart между контроллером и LCD при использовании обычного телефонного провода на скорости 150кбод. Точнее были, но это касалось неграмотной разводки земли на плате, когда GND пляшет и помехи прут независимо от внешних воздействий.

Например, для ячейки BMS важным требованием будут низкие энергозатраты, оптоизоляция и желательно без кварца. Еще чтоб код ячейки влез в 1 (максимум 2) кб.
Сейчас я использую для ячеек BMS 1-проводный протокол, где 1 импульс - 1 бит. Заполнение 25% и 75% - 0 и 1, 50% - синхронизация. В начале идет несколько синхронизаций, slave настраивается на скорость мастера. Далее идут байты данных (первый байт - адрес). Ячейка отвечает на той же скорости, на которой был принят запрос. Реализуется просто с одним каналом таймера.

При обмене между контроллером и ЖК наоборот, нужен более скоростной протокол. Тут я использовал обычный uart.
LiFe A123 40AH/78v, max-e, крошка 3 витка.
На форуме бываю нерегулярно, поэтому лучше звонить чем писать в личку. Телефон adaptto: +7 495 215 2878.

Althair

RS485, имхо, тут самый приемлемый вариант, что бы кто не говорил.
У меня есть доступ к документации промышленного газоперерабатывающего комплекса (вернее - его системы управления/контроля Honeywell), где используется RS485, и никто (несколько сотен устройств на километрах полевки) друг с другом не ругается.
Попробую выудить оттуда описание аудита шины, завод - это не велик, там все намного серьезнее.
Куплю удлинитель для коротких замыканий, а так же волшебный дым для заправки радиодеталей.
Ноунейм Сяоклон 250W + 36V 15Ah
Самовар Cats Threat 2х1000W (придушено до 250W) + злые 14x5.0 + 2хВектор + 16S1P MpCO 21Ah