Перейти к содержанию
    

Помехозащищенный RS-485

Так подключите MAX485 прямо к FT232R или CP2103 или возьмите готовый переходник, а всю обработку делайте на компьютере. Зачам там еще МК?

А этот преобразователь, он же только данные отправляет? А счетчик USB фрейма?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мне удобнее COBS преобразование сделать в датчике, а в МК1 добавить байт - номер датчика.

А почему датчик не может сразу добавить свой номер и CRC, а потом закодировать сообщение?

 

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

 

почему? данных же мало, всего то 12 байт.

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

 

А этот преобразователь, он же только данные отправляет? А счетчик USB фрейма?

SOF-ы автоматически считаются "на нижнем уровне". А накой вам этот счетчик?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему датчик не может сразу добавить свой номер и CRC, а потом закодировать сообщение?

а как? датчик же не знает какой у него номер. все датчики одинаковые, воткнул в 1-е гнездо, значит датчик №1, если в о 2-е, то №2

 

SOF-ы автоматически считаются "на нижнем уровне". А накой вам этот счетчик?

Для синхронизации. У меня в USB МК отправляется сначала счетчик фрейма (2 байта), потом данные

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а как? датчик же не знает какой у него номер. все датчики одинаковые, воткнул в 1-е гнездо, значит датчик №1, если в о 2-е, то №2

Тогда пусть все датчики ставят в нужное место номер 1, кодируют и отправляют. А ваш МК1 просто заменит номер 1 в этом месте на действительный номер датчика. Если он не будет равен 0, то на COBS это никак не повлияет.

 

Однако при этом придется обойтись без CRC на все сообщение, поскольку CRC надо добавлять до того, как кодировать по COBS. Можно, конечно, CRC считать в датчике, а "1" добавлять потом, но при этом номер датчика не будет охвачен CRC. Это не очень хорошо, но работать будет.

 

Для синхронизации. У меня в USB МК отправляется сначала счетчик фрейма (2 байта), потом данные

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

 

Специфиkация USB:

 

5.12.4.1.1 Asynchronous

Asynchronous endpoints cannot synchronize to SOF or any other clock in the USB domain.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда пусть все датчики ставят в нужное место номер 1, кодируют и отправляют. А ваш МК1 просто заменит номер 1 в этом месте на действительный номер датчика. Если он не будет равен 0, то на COBS это никак не повлияет.

 

Однако при этом придется обойтись без CRC на все сообщение, поскольку CRC надо добавлять до того, как кодировать по COBS. Можно, конечно, CRC считать в датчике, а "1" добавлять потом, но при этом номер датчика не будет охвачен CRC. Это не очень хорошо, но работать будет.

Хорошая идея, я подумаю...

Нет смысла охватывать номер датчика CRC, он же все равно будет переписан. Хотя может быть испорчен дальше, но дальше все таки дифф пара RS-485.

 

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

 

Специфиkация USB:

 

5.12.4.1.1 Asynchronous

Asynchronous endpoints cannot synchronize to SOF or any other clock in the USB domain.

я использую изохронный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет смысла охватывать номер датчика CRC, он же все равно будет переписан. Хотя может быть испорчен дальше, но дальше все таки дифф пара RS-485.

А вы этот номер передавайте в самом байте дважды: в младших 4 битах сам номер, а в старших четырех битах - его инверсию. Так вы любые одиночные ошибки в этом байте обнаружите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы этот номер передавайте в самом байте дважды: в младших 4 битах сам номер, а в старших четырех битах - его инверсию. Так вы любые одиночные ошибки в этом байте обнаружите.

Понятно, спасибо.

А еще Вы писали, что в Википедии "сложный" вариант перекодировки COBS. Где тогда можно простой посмотреть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опять товарища =AK= куда-то понесло - предложил для RS485 с шумами в паузах протокол канального уровня, позволяющий отловить конец пакета, но не его начало после шума. А потом еще предложил всунуть между канальным и физическим уровнями кусок транспортного (номер пакета). Аплодисменты.

 

Atlantis-, почитайте про сетевую модель OSI. У вас есть физический уровень - RS485. Поверх него вы строите канальный, отвечающий за разбивание потока вашей информации на пакеты и контрольную сумму. COBS тут не подходит по указанной выше причине - малейший шум в паузе и пакет вы потеряли. Посмотрите на SLIP, реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета. Далее строите сетевой уровень - добавляете в протокол адреса ваших датчиков. Если у вас каждый датчик воткнут в свой отдельный интерфейс - сетевой уровень на этом участке вам не нужен. Далее сверху накладываете транспортный уровень - добавляете в протокол номер пакета. И сверху водружаете прикладной уровень - собственно ваши данные.

 

При передаче идете по модели сверху вниз: берете данные (прикладной уровень), добавляете к ним номер пакета(транспортный уровень), добавляете адрес(сетевой уровень), считаете контрольную сумму и обкладываете все это байт-стаффингом (канальный уровень, SLIP-подобные протоколы позволяют делать это побайтно, прямо в процессе передачи, не видя пакета целиком) и в конце передаете получившийся пакет данных через UART в RS-485 (физический уровень).

На приемной стороне вы двигаетесь по модели снизу вверх: принимаете байты из RS-485 (физический уровень), обрабатывая SLIP-подобный протокол убираете байт-стаффинг и выделяете начало/конец пакета, считаете контрольную сумму (канальный уровень), далее отделяете и обрабатываете адрес (сетевой уровень), следом номер пакета (транспортный уровень) и в результате получаете ваши исходные данные очищенные от всей этой шелухи, т.е. в том виде, в котором эти данные поступили из прикладного уровня на передающей стороне.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в Википедии "сложный" вариант перекодировки COBS. Где тогда можно простой посмотреть?

 

"а это уж вы сами" © Щербаков

 

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

 

COBS тут не подходит по указанной выше причине - малейший шум в паузе и пакет вы потеряли.

 

К сожалению, вы ничего не поняли, даже какой-то "номер пакета" вдруг выдумали и приплели ни к селу ни к городу.

 

Никакой шум в паузе не повлияет на прием пакета из-за того, что передатчик передает два 0 до начала пакета. После паузы приемник гарантировано получит хотя бы один 0, после чего "шумовой" пакет будет проверен и отвергнут из-за несовпадения CRC, а также из-за несоответствия правилам COBS. А следующий сразу же вслед за этим истинный пакет будет принят без искажений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите на SLIP, реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета.

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

 

 

 

Никакой шум в паузе не повлияет на прием пакета из-за того, что передатчик передает два 0 до начала пакета.

Совет неверный. Нужен один 0xFF.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет неверный. Нужен один 0xFF.

Что-то мне эта тема напомнила... Ага, вот эту тему.

Там долго выясняли способ гарантированно восстановить битовую синхронизацию при непрерывной передаче потока. =AK= описал применяемый им способ посылки двух подряд символов 0x0F, при котором второй символ гарантированно ловится. Потом выяснилось, что это не так, по крайней мере, не со всеми контроллерами UART.

Символ же 0xFF, переданный перед началом пакета, гарантированно восстановит битовую синхронизацию:

post-29684-1448648923_thumb.png

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Символ же 0xFF, переданный перед началом пакета, гарантированно восстановит битовую синхронизацию:

Байтовую :) Битовая, если надо, захватывается по 0x55.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SLIP использует разделитель фреймов, который используется и в начале и в конце пакета

Как-то неразумно называть признак начала кадра именем "END".

 

RFC 1055:

The SLIP protocol defines two special characters: END and ESC. END is

octal 300 (decimal 192) and ESC is octal 333 (decimal 219) not to be

confused with the ASCII ESCape character; for the purposes of this

discussion, ESC will indicate the SLIP ESC character. To send a

packet, a SLIP host simply starts sending the data in the packet. If

a data byte is the same code as END character, a two byte sequence of

ESC and octal 334 (decimal 220) is sent instead. If it the same as

an ESC character, an two byte sequence of ESC and octal 335 (decimal

221) is sent instead. When the last byte in the packet has been

sent, an END character is then transmitted.

Про признак начала ничего не сказано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как-то неразумно называть признак начала кадра именем "END".

Это не ко мне :). В реальные реализации протокола ПРАВИЛЬНО отрабатывают и одиночные разделители и начало-конец и любое количество "END" в качестве разделителей. Что совершенно ествественно и соответственно никаких "реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета" не требуется.

 

RFC 1055 Про признак начала ничего не сказано.

Из этого-же RFC:

 /* SEND_PACKET: sends a packet of length "len", starting at
    * location "p".
    */
   void send_packet(p, len)
           char *p;
           int len; {

     /* send an initial END character to flush out any data that may
      * have accumulated in the receiver due to line noise
      */
        send_char(END);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Предлагаю конец теме — передаём, после получения TC=1 отключаем драйвер, делаем задержку, устанавливаем RE=1, немного попринимали, далее сразу устанавливаем RE=0, включаем драйвер, делаем задержку и снова передаём.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...