Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USB-UART и радиосеть
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > RS232/LPT/USB/PCMCIA/FireWire
fiim
Собственно, предлагаю обсуждение еще одного варианта USB(HID)-UART- переходника, а также связанного с ним протокола передачи данных, и использование этого протокола в построении простой радио-сети.
Проект совсем новый, поэтому много недочетов, но уже сейчас переходник обеспечивает передачу на скоростях до 500кбит, годен для очень слабых микроконтроллеров(<2кБ), и очень удобен: достаточно нескольких строк кода что в компьютерной программе, что на микроконтроллере, чтобы передать данные. Вот здесь вводное описание и там же ссылка на сайт с документацией и видеоуроками:http://bextensions.wix.com/be-bdn#!history/cipy. Тухлые помидоры тоже приветствуются wink.gif
zltigo
QUOTE (fiim @ Jun 11 2015, 13:34) *
Собственно, предлагаю обсуждение...

Осуждать собственно нечего. Вы, в процессе рассуждений придя к очень правильному выводу, что фреймы нужно оформлять бит/байт стаффингом а не маяться фигней таймаутами и/или заголовками фрейма с размерами и опять-же таймаутами.... , тут-же ничтоже сумняшеся начали байтстаффинг уродовать "улучшениями" - выбором байта ломающим надежность и гробящим саму идею байтстаффинга всовыванием волшебного байта 0xFF являющегося де-факто маркером начала фрейма sad.gif, добавлением НЕНУЖНОГО для НОРМАЛЬНОГО байтстаффинга размера фрейма.
Слово "радиосеть" вообще к "изобретенному" протоколу вообще отношения не имеет, ибо кто-то там еще оформляет полученный по описанному протоколу фрейм в эфирный фрейм.
Ну а то, что Вы начали загаживать ссылкой на эту тему другие темы форума, это вообще плохо.
jcxz
Цитата(zltigo @ Jun 14 2015, 11:40) *
Осуждать собственно нечего. Вы, в процессе рассуждений придя к очень правильному выводу, что фреймы нужно оформлять бит/байт стаффингом а не маяться фигней таймаутами и/или заголовками фрейма с размерами и опять-же таймаутами.... , тут-же ничтоже сумняшеся начали байтстаффинг уродовать "улучшениями" - выбором байта ломающим надежность и гробящим саму идею байтстаффинга всовыванием волшебного байта 0xFF являющегося де-факто маркером начала фрейма sad.gif, добавлением НЕНУЖНОГО для НОРМАЛЬНОГО байтстаффинга размера фрейма.
Слово "радиосеть" вообще к "изобретенному" протоколу вообще отношения не имеет, ибо кто-то там еще оформляет полученный по описанному протоколу фрейм в эфирный фрейм.
Ну а то, что Вы начали загаживать ссылкой на эту тему другие темы форума, это вообще плохо.

a14.gif
+1
fiim
Цитата(zltigo @ Jun 14 2015, 08:40) *
...Ну а то, что Вы начали загаживать ссылкой на эту тему другие темы форума, это вообще плохо.

Оу, я всегда лезу куда не стоило бы)
По поводу байта 0xFF: зря вы на него так нападаете. Его не стоит использовать там, где нужно отделять байт от байта. А вот при разделении пакета от пакета он ведёт себя просто отлично. Не знаю, как у вас, а я делал началом пакетов разные байты, а не только фыфы, и количество ошибок ни помехоустойчивость от этого не зависят. В конце-концов никто не мешает вам у себя заменить его на любой другой. Но не стоит: ничего не изменится, я проверял -все очень чётко работает.
Цитата
...выбором байта ломающим надежность и гробящим саму идею байтстаффинга

-!)))
Цитата
...добавлением НЕНУЖНОГО для НОРМАЛЬНОГО байтстаффинга размера фрейма

-Размер фрейма добавлен здесь не для байтстаффинга, люди, байтстаффинг в этом ВООБЩЕ не нуждается. Размер добавляется в любом случае, если у вас фрейм может иметь разный размер. Вот USB пакеты имеют стандартную длину -64 байта, поэтому там размер указывать не надо. А если, как у меня, пакет может быть от 0 до 247 байт, тогда будьте бобры, укажите длину)
Ну и третий помидор:
Цитата
...ибо кто-то там еще оформляет полученный по описанному протоколу фрейм в эфирный фрейм

-Это уж как кому угодно. В том и прелесть, что можно передавать данные и привязываясь и не привязываясь к эфирному фрейму, при этом простота передачи не изменится.
zltigo
QUOTE (fiim @ Jun 26 2015, 15:06) *
Его не стоит использовать там, где нужно отделять байт от байта...
Размер добавляется в любом случае, если у вас фрейм может иметь разный размер.

Я плакаль sad.gif. Байтстафиговым байтом выделяется и начало и КОНЕЦ фрейма. Вот и получаем размер какой угодно. Им-же можно забивать гапы между фреймами для минимизации проблем пропадания байтов и потерь на раймауты. Таким образом эта Ваша фраза показывет еще большую глубину непонимания Вами содеянного sad.gif
QUOTE
В том и прелесть, что можно передавать данные и привязываясь и не привязываясь к эфирному фрейму, при этом простота передачи не изменится.

Вы просто совершенно НЕ понимаете что ЗА ВАС делает используемый Вами модуль и что ИМЕННО ОН, а СОВСЕМ НЕ Вы со всякими уродиливыми протоколами занимается именно ПРОТОКОЛОМ эфира помиаемым Вами всуе.
fiim
Цитата(zltigo @ Jun 26 2015, 16:07) *
Я плакаль sad.gif. Байтстафиговым байтом выделяется и начало и КОНЕЦ фрейма. Вот и получаем размер какой угодно. ...Таким образом эта Ваша фраза показывет еще большую глубину непонимания Вами содеянного sad.gif

-Байтстафиговым байтом МОЖЕТ выделяться и начало и конец фрейма. Да, это неплохой вариант, он даже использовался в самых первых версиях. Но использование его только в начале или только в конце плюс байт размера абсолютно равнозначный вариант.
Цитата
Вы просто совершенно НЕ понимаете что ЗА ВАС делает используемый Вами модуль и что ИМЕННО ОН, а СОВСЕМ НЕ Вы со всякими уродиливыми протоколами...
-Да я не настаиваю называть свой простенький проект каким-то "протоколом", так просто удобнее. Можно назвать "горшком", главное, что работает отлично. Любой, даже начинающий программист может сделать в 10(с половиной) раз лучше, чем я, и делают, и у них тоже все хорошо работает. А вы намного лучше меня понимаете, что делает используемый мной радиомодуль. Это же здорово! Если что, буду спрашивать у вас, уважаемый. Опять же, не обязательно использовать радиомодули для связи. Можно, например, юзать rs485. Правда, загвоздка: вы тогда не сможете сказать, что всю работу делает "именно он".
zltigo
Уже все сказано. Думайте. Повторять в третий раз не вижу сысла.
jcxz
Цитата(zltigo @ Jun 27 2015, 09:41) *
Уже все сказано. Думайте. Повторять в третий раз не вижу сысла.

Зря распинаетесь, пациент безнадёжен - в морг.

ЗЫ: Кстати я иногда модифицирую стандартный байт-стаффинг - в качестве флага использую не один спец-символ как в байт-стаффинге, а последовательность из N символов 'F'. Так минимизируется недостаток классического байт-стаффинга состоящий в удвоении объёма кодированного потока при передаче исходного потока состоящего сплошь из сигнальных символов.
Работа энкодера при кодировании кадра в выходной поток:
Энкодер в начале кадра вставляет маркер "начало кадра" (последовательность N символов 'F', затем символ 'B'). Затем - передача символов исходного кадра. Если среди символов кодируемого кадра встречается последовательность из N символов 'F', то после них энкодер вставляет в вых. поток дополнительный символ 'D' (который будет удалён декодером). Также после последнего символа кадра вставляется один доп. символ не равный 'F' (который также будет удалён декодером). После конца кадра энкодер вставляет в вых. поток маркер "конец кадра" (последовательность N символов 'F', затем символ 'E'). Если после маркера "конец кадра" на вход энкодера сразу поступает новый кадр, то маркер "начало кадра" может не передаваться. Для сигнализации "канал жив" между кадрами энкодер может передавать любой символ заполнения, не равный 'F'.
Символом 'F' может выбираться любой удобный, вероятность появления которого минимальна во входном потоке.
Символы 'B', 'E', 'D' - также любые удобные.
Работа декодера думаю ясна. Могу только сказать, что при подключении декодера к потоку, он имеет начальное состояние "не синхронизирован". При получении маркеров "начало кадра" или "конец кадра", он переходит в состояние "синхронизирован" и начинает принимать кадр. В состояние "несинхронизирован" он переходит при любых ошибках приёма (переполнение буфера при приёме кадра, таймаут и т.п.).
При получении "конец кадра", из буфера удаляется последний символ, кадр передаётся на следующий уровень обработки, обнуляется приёмный буфер и приёмник остаётся в состояние "синхронизирован".
Такой алгоритм полезен для каналов с ограниченной пропускной способностью, которые могут переполниться при передаче произвольного потока байт с использованием стандартного байт-стаффинга. У этого алгоритма меньший коэффициент увеличения размера кадра (при условии что кадры довольно большие) при передаче флаговых байт в исходном потоке.
fiim
Цитата(jcxz @ Jun 27 2015, 11:03) *
Зря распинаетесь, пациент безнадёжен - в морг.

ЗЫ: Кстати я иногда модифицирую стандартный байт-стаффинг - в качестве флага использую не один спец-символ как в байт-стаффинге, а последовательность из N символов 'F'. Так минимизируется недостаток классического байт-стаффинга состоящий в удвоении объёма кодированного потока при передаче исходного потока состоящего сплошь из сигнальных символов...
-Да, это классический байтстаффинг. У вас хорошее решение. Я тоже не боюсь менять классику так, как мне вздумается. В моем варианте байтстаффинга объем кодированного потока вообще не увеличивается, даже если сплошь состоит из сигнальных символов.
jcxz
Цитата(fiim @ Jun 29 2015, 10:57) *
В моем варианте байтстаффинга объем кодированного потока вообще не увеличивается, даже если сплошь состоит из сигнальных символов.

Это невозможно.
fiim
Цитата(jcxz @ Jun 29 2015, 08:35) *
Это невозможно.
Вряд ли это моё изобретение. Наверняка кто-то использует этот способ уже 100лет. В классическом варианте начало пакета обозначается байтом 0хС0, а если он встречается в самом пакете, то его заменяют на 0хDBDC. А если в пакете встречается 0xDB, то он заменяется на 0xDBDD. Собственно, не особо важно какие именно выбраны байты, но, заметьте, что замена идет заранее определенными байтами, которые тоже могут встретиться в последовательности. Поэтому их и приходится заменять на двойные последовательности, от чего и разрастается исходная последовательность. А вот если вы не будете использовать для замены константу, которая может тоже встретиться в вашей последовательности, а возьмёте для замены байт, которого просто нет в пакете, тогда этим байтом вы можете спокойно заменить все стартовые 0xC0, если они вдруг встретятся внутри пакета. Единственное, что вам нужно -это указать приёмнику(декодеру), каким байтом вы заменяете стартовый. Пример. Пусть вам надо переслать последовательность DB-C0-DC-DD. В начале пакета вы ставите C0, а потом просматриваете весь пакет, чтобы определить, какой байт там НЕ встречается. В нашем случае там не встречается много байт, берём любой, например 0xAA, и вставляем его сразу за стартовым байтом, получаем C0-AA. Далее передаем саму последовательность, но в ней встречающиеся С0 меняем на АА. В итоге получаем: C0-AA-DB-AA-DC-DD. Всё! Приёмник(декодер)читает байт, следующий за стартовым байтом, то есть АА, и далее все байты АА меняет на С0, восстанавливая таким образом всю последовательность. Попробуем взять еще один пример, где необходимая для передачи последовательность содержит очень много управляющих символов, например C0-DB-C0-C0-AA-C0-DC-C0-C0. Определяем, какого байта здесь нет, берем любой из них, например, 0х77, и добавляем его к стартовому байту. В итоге для отправки получим С0-77-77-DB-77-77-AA-77-DC-77-77.
jcxz
Цитата(fiim @ Jun 29 2015, 12:37) *
...
В итоге для отправки получим С0-77-77-DB-77-77-AA-77-DC-77-77.

И что?
Сами себе противоречите... Пишете, что не увеличивается и тут же сами же пишете, что добавляете байт...
Во-вторых - представить случай, что в пакете могут быть все байты 0...255 можете?
Байт-стаффинг имеет очень важное достоинство: кодонезависимость (мой метод тоже кодонезависим). В Вашем методе кодонезависимости нет.
fiim
Цитата(jcxz @ Jun 29 2015, 12:26) *
И что?
Сами себе противоречите... Пишете, что не увеличивается и тут же сами же пишете, что добавляете байт...
-Как же вы правы!
Цитата
Во-вторых - представить случай, что в пакете могут быть все байты 0...255 можете?
-Да, этот вариант годится только для пакетов длиной меньше, чем 256. В моем протоколе максимальная длина пакета 247байт, то есть этот вариант вполне годится. Если же вам необходимо формировать более длинные пакеты, то можно использовать 2 байта для "стартсимвола", и также два байта для кодирования. В итоге, длиннющий пакет, например в 16тысяч байт, и притом состоящий сплошь из управляющих символов, удлинится всего на 4 байта. В классическом байтстаффинге он удлинился бы на несколько тысяч байт.
jcxz
Цитата(fiim @ Jun 29 2015, 16:11) *
Если же вам необходимо формировать более длинные пакеты, то можно использовать 2 байта для "стартсимвола", и также два байта для кодирования. В итоге, длиннющий пакет, например в 16тысяч байт, и притом состоящий сплошь из управляющих символов, удлинится всего на 4 байта.

Интересно - как это??? Поясните.
fiim
Цитата(jcxz @ Jun 29 2015, 13:18) *
Интересно - как это??? Поясните.
Принцип тот же самый. Можно перенести этот принцип и на двубайтный вариант. Там, правда, есть пара нюансов, я о них скажу. Проще всего показать на примере. Пусть нам нужно передать последовательность из таких байт: C0-DB-C0-DB-C0-DB... длиной в 15 тысяч байт. И пусть стартовое слово(2 байта) у нас тоже будет C0-DB. То есть допустим, что последовательность вся состоит из стартовых слов. Нам нужно всего лишь найти подходящее 2байтное слово для кодировки. Для этого точно также проходимся по последовательности, и смотрим, какое 2байтное сочетание там НЕ встречается. В нашем случае таких полно. Возьмем, например, слово 77-АА, и поставим его следом за стартовым словом, получаем первые 4 байта: C0-DB-77-AA. А в самой последовательности всё, что совпадает со стартовым словом(C0-DB) заменяем на кодовое(77-AA). В итоге получаем: C0-DB-77-AA-77-AA-77-AA... итого 15004 байта. Теперь, как и обещал, о нюансах. Первое: желательно, чтобы из последнего байта предыдущего пакета и первого байта стартового слова следующего пакета не получилось стартовое слово. Это решить очень просто: достаточно стартовое слово сделать из разных байт, то есть нельзя С0-С0, нельзя DB-DB, а можно C0-DB или DB-C0 и т.д. Второй нюанс: нельзя, чтобы любой байт у кодировочного слова совпадал с любым байтом стартового слова, иначе в процессе кодировки это может породить стартовое сочетание. То есть выбор кодировочного слова у нас уменьшается на 512+512+1. Ах, да, еще байты кодировочного слова желательно сделать разными. Поэтому максимальная длина пакета для такого байтстаффинга не 65535 байт, как могло показаться на первый взгляд, а меньше. Но в любом случае такой 2байтный вариант позволяет формировать пакеты в много тысяч байт. Конечно никому не советую слать такие длинные пакеты))). Если вдруг в результате какой-нибудь помехи вам придется посылать пакет заново, то это будет обидно. А если пакеты маленькие, то заново его переслать -это не страшно. Для UARTа я стараюсь ограничиваться максимум в 200байт, а для радио и того меньше, поэтому однобайтный байтстаффинг лично для меня более предпочтителен. Тем более реализация программы для длинных пакетов тоже будет сложнее, что может сказаться на слабых микроконтроллерах.
Mihey_K
Преамбулу никто не отменял, даже самые дубовые передатчики используют ее для захвата эфира и синхронизации с приемником. Если реализовать прерывание по приему то и городить ничего не нужно. В пакет можно добавить заголовок с метрикой и длиной кадра, а в конец обязательно CRC.
Aner
QUOTE (fiim @ Jun 29 2015, 18:11) *
Принцип тот же самый.
... Конечно никому не советую слать такие ...
... может сказаться на слабых микроконтроллерах.

я б тоже не советовал никому использовать то что вы тут намутили, кошмар и только.
Ни объем передать, ни короткими пакетами поработать. Да и за пределами стандартов, все это у вас протокольное.
Про временную синхру, сбои ... никак, и много еще чего, что в реальных условиях нужно.
Подвис у вас один узел-транслятор, которого не обойти, пошли теряться пакеты, сеть из 200 подвисла, как восстановить?
Никак, только перезагрузка всех и пере-синхронизацией заново. Кому это нужно?
От наведеной помехи повиснет треть оконечников в сети ... и проблема вашего протокола очевидна. Итд ...
jcxz
Цитата(fiim @ Jun 29 2015, 20:11) *
Принцип тот же самый. Можно перенести этот принцип и на двубайтный вариант.
...

Всё это больше похоже на алгоритм сжатия с построением словаря и заменой лексем на более короткие. Это не делается на этапе канального кодирования, а делается предварительно (если нужно) для сжатия исходного кадра.
Для канального кодирования здесь сразу видится минус - очень времязатратный алгоритм. Поиск последовательности байт, не встречающейся в кадре - может съедать очень много процессорного времени.
И время обработки кадра недетерминированное - очень сильно зависит от содержимого.
Если уж идти по такому пути, то тогда обычно пропускают кадр через алгоритм сжатия, а потом делают его канальное кодирование.
fiim
Цитата
Преамбулу никто не отменял, даже самые дубовые передатчики используют ее для захвата эфира и синхронизации с приемником. Если реализовать прерывание по приему то и городить ничего не нужно. В пакет можно добавить заголовок с метрикой и длиной кадра, а в конец обязательно CRC.
-Здесь я описал только ту часть протокола, которая касается байтстаффинга(по просьбам зрителей))). Конечно кроме байтстаффинга в протоколе есть и длина кадра и CRC16 и адресация... Кто удосужился пройти по ссылке вначале, очень надеюсь, всё это увидели laughing.gif А вот преамбулы и синхронизации там нет. Если кто-то читал статейку, то увидели, что главная первоначальная задача была связать 2 микроконтроллера по УАРТу. Синхронизацией вам для этого заниматься не надо. Протокол лишь дает удобство общения между микроконтроллерами по УАРТу(с проверкой CRC и другими приятными мелочами(см. видео по ссылке). И вот к такому микроконтроллеру, опять же ПО УАРТу, вы можете подключить стандартный радиомодуль, который имеет свой протокол, и вам до него дела нет. У него есть и преамбула и все остальное для эфирной передачи, но, повторяю, вам до этого дела нет, вы на этом не заморачиваетесь: подключили к УАРТу и кидаете данные. Или, например, если речь идет о применении моего протокола в переходнике УАРТ-ЮСБ: мой протокол НЕ ЗАМЕНЯЕТ протокола ЮСБ, так же как НЕ ЗАМЕНЯЕТ эфирный протокол радиомодулей. Вы просто кидаете данные по УАРТу в переходник и не заботитесь о том как ЮСБ передает все это в компьютер. А то некоторые, не разобравшись, понавесят на мой протокол функций, которых я не заявлял, а потом говорят "фу". Ну разве вы требуете, например, от МОДБАСа, чтобы он имел преамбулу для захвата эфира? Вот и от моего не стоит требовать. А почему я написал про радиосеть? Да просто потому, что я подключил к нескольким микроконтроллерам радиомодули, это все отлично заработало и я понял, что более удобной системы я не встречал: три строчки кода- и готов полноценный обмен данными. С помощью МОДБАСа, например, так просто не получится.(Но я не уничижаю МОДБАС:он имеет свои достоинства, до которых мне далеко) Кроме того мой протокол дает возможность ретрансляции(то есть нечто типичное именно для радиосвязи). Причем никаких специальных ретрансляторов городить не надо. Неужели после этого я не мог в название этой темы добавить слово"радиосеть"?
Цитата
Всё это больше похоже на алгоритм сжатия
-Никакого сжатия, просто модифицированный байтстаффинг.
Цитата
Для канального кодирования здесь сразу видится минус - очень времязатратный алгоритм
-Скачайте библиотеку(по ссылке вначале):даже AVR8 на частоте всего 1 МГц справляется с максимальными пакетами(247байт) и бОльшую часть времени отдыхает.
Mihey_K
Цитата
Кто удосужился пройти по ссылке вначале, очень надеюсь, всё это увидели

Уж простите, но я прошел по ссылке и увидел там только портянку sm.gif
Касательно подключил и забыл - модули как минимум придется конфигурировать, а если брать CC430 и аналоги то и вовсе для них прошивку нужно ваять
jcxz
Цитата(fiim @ Jun 30 2015, 12:45) *
-Скачайте библиотеку(по ссылке вначале):даже AVR8 на частоте всего 1 МГц справляется с максимальными пакетами(247байт) и бОльшую часть времени отдыхает.

Мы говорили о кадрах размером >255 байт.
Берём в руки обычный калькулятор, считаем сколько времени потребуется для поиска 2-байтовой последовательности, отсутствующей в кадре.
Допустим размер кадра == 1000байт. Допустим поиск 2-байтовой последовательности идёт просто прямым сравнением подряд от начала кадра.
Допустим искомые последовательности генерим начиная от 0 и далее (если найдена) инкремент.
Получаем:
1.Для проверки вхождения одной 2-байтовой последовательности в кадр потребуется от 1 до 999 сравнений. Среднее кол-во == ~500.
2.В худшем случае придётся выполнить 501 генерацию новых последовательностей (с их последующей проверкой).
Это в случае если кадр состоит из слов: 0000, 0001, 0002, ... .
Итого получаем: 500*500 = 250000 сравнений. И это без учёта ещё сравнений с последовательностями границы кадра.
Сколько Ваш AVR8 будет кодировать такой кадр? Особенно учитывая что он 8-битный и на одно сравнение тратит кучу команд. Думаю - несколько секунд. При полной загрузке CPU.
Жесть короче.

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

А байт-стаффинг тем и хорош, что он малозатратен ресурсам - памяти и времени выполнения (мой метод - тож).
Кодирование/декодирование кадра можно проводить хоть прямо на лету в ISR не расходуя на это драгоценное ОЗУ - записывать в выходной буфер уже декодированный кадр,
а на в буфере передачи хранить исходный кадр и кодировать его на лету при записи собственно в порт в ISR.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.