Вверх ↑
Этот топик читают: Гость
Ответов: 499
Рейтинг: 1
#1: 2010-01-15 05:09:00 ЛС | профиль | цитата
имеется железка, которая раз в 20мс шлет пакетик длительностью 1.5-2.0мс (18 байт) по com-порту. собрал схему (код прилагается):

по таймеру раз в 50мс (точнее не нужно) опрашивается порт, читается 18 байт, скидывается в символьный массив, затем посимвольно передается на обработку (на схеме не показано). первые два символа должны быть с кодами 85, 252, если это не так - строка забраковывается.

проблема в том, что как не игрался с задержками и таймаутами процент ошибок довольно велик, 10-15% всех принятых строк начинаются не с ключевых символов. причем если просматривать строку целиком, то видно, что ловится конец одной посылки и начало второй. вопрос: можно как-то точнее синхронизировать сей процесс?

вторая ситуация, эта же железка в другом режиме посылает подряд 5 пакетов с разной длиной (13, 12, 12, 12, 15 байт), причем маркер начала есть только в первом пакете, а контрольная сумма только в последнем. из-за вышеописанной потери строки приходится долго ждать правильно принятых пакетов, ибо какая-нить одна строка возьмет и скосячится.
может есть более точный механизм чтения com-порта?

code_16508.txt
карма: 0

0
файлы: 1code_16508.txt [2.2KB] [134]
Разработчик
Ответов: 26160
Рейтинг: 2127
#2: 2010-01-15 09:05:25 ЛС | профиль | цитата
После окончания времени кадра (если это не непрерывная последовательность), автоматически выставляется пустой символ, почему нельзя его использовать Это первое, второе: строка должна читаться всегда целиком, а затем браковаться, а не останавливаться накопление в середине цикла чтения, что у тебя сделано, иначе -- будет полная рассинхронизация в твоем случае, тк ты не используешь пустой символ для дополнительной синхронизации с концом посылки
карма: 22

0
Ответов: 8926
Рейтинг: 823
#3: 2010-01-15 10:08:32 ЛС | профиль | цитата
HikeR, кроме того, если читать именно по 18 байт, да через 50 мсек, нечего удивляться, что попадает окончание предыдущей строки и начало следующей
Всё принятое в этом случае надо сцеплять в одну строку и уже её парсить, удаляя просчитанное
карма: 19

0
Разработчик
Ответов: 26160
Рейтинг: 2127
#4: 2010-01-15 10:13:30 ЛС | профиль | цитата
Вот такой модуль у меня работает для синхронизации по пустому символу



Add(ArrayRW,6457832,546,336)
{
link(Array,7493369:Array,[])
}
Add(Case,15358791,469,294)
{
Value=String()
link(onNextCase,6457832:doAdd,[(537,300)(537,356)])
link(onTrue,10885940:doEvent1,[])
}
Add(Hub,10885940,511,301)
{
link(onEvent1,7493369:doGetStr,[])
link(onEvent2,7493369:doClear,[])
}
Add(CharArray,7493369,546,294)
{
link(onGetStr,6051039:doCase,[])
}
Add(Case,6051039,588,301)
{
Value=String()
}

------------ Дoбавленo в 10.16:
Леонид писал(а):
кроме того, если читать именно по 18 байт, да через 50 мсек, нечего удивляться, что попадает окончание предыдущей строки и начало следующей

Брехня. Я считываю 21 байт каждые 10 msес и никуда у меня ничего не пропадает и нет никакой рассинхронизации. Ты забыл про буфер FIFO, который автоматически накапливает принятую информацию, а уже ты ее считывешь из этого буфера
карма: 22

0
Ответов: 499
Рейтинг: 1
#5: 2010-01-15 13:24:49 ЛС | профиль | цитата
nesco писал(а):
строка должна читаться всегда целиком, а затем браковаться, а не останавливаться накопление в середине цикла чтения

строка и так читается целиком, а прерывается только ее обработка, т.к. обрабатывать некорректные данные бесмысленно.
Леонид писал(а):
если читать именно по 18 байт, да через 50 мсек, нечего удивляться, что попадает окончание предыдущей строки и начало следующей

сама посылка длится 2мс максимум, попасть в ее середину - это намного меньше 10-15%.

с пустым символом надо пробовать.
карма: 0

0
Администрация
Ответов: 15295
Рейтинг: 1519
#6: 2010-01-15 13:52:59 ЛС | профиль | цитата
nesco писал(а):
Ты забыл про буфер FIFO, который автоматически накапливает принятую информацию, а уже ты ее считывешь из этого буфера

наличие или отсутствие fifo буфера в данной проблеме ни при чем(насколько я понимаю данные не пропадают, а выдаются порциями не в той комбинации, которая ожидалась), и как правильно говорит Леонид, необходимо в своей схеме накапливать строку, после чего уже искать в ней последовательность длинною в 18 байт с началом 85, 252.
карма: 27
0
Ответов: 8926
Рейтинг: 823
#7: 2010-01-15 13:54:58 ЛС | профиль | цитата
nesco, так и я про буфер из которого считываются по 18 байт
карма: 19

0
Разработчик
Ответов: 26160
Рейтинг: 2127
#8: 2010-01-15 14:16:31 ЛС | профиль | цитата
Dilma писал(а):
необходимо в своей схеме накапливать строку, после чего уже искать в ней последовательность длинною в 18 байт с началом 85, 252

Не надо у себя ничего накапливать, оно и так в буфере висит. Достаточно считать 18 байт до пустого символа, проверить ее на валидность и пропустить дальше или забраковать. У меня похожая система, и не на один канал, уже три года тарахтит и никаких рассинхронизаций я не наблюдал. С пакетами история похожая, надо считать все 5 пакетов, проверить валидность и дальше по теме. Сложность в данном случае, тут только в том, что если накапливать инфу в буфере FIFO, то нет никакой гарантии, что у нас не обрежется конец посылки, те, попадет нечетное количество кадров, тогда кусок последней посылки обратно уже в буфер не вернешь и его надо сохранять у себя, а к нему дальше уже приклеивать данные, это потребует усложненния контроля длины оставшегося массива после обработки кадра. Самое простое, это не допускать чтения в FIFO больше, чем длина кадра, тогда появиться гарантия, что следующий кадр не обрежется. В данном случае, делается, как описано ниже
------------ Дoбавленo в 14.22:
HikeR писал(а):
по таймеру раз в 50мс (точнее не нужно)

А вот с эти я не согласен, для нормальной синхронизации по пустому символу читать надо быстрее, нежели устройство подает свои данные, но медленне, чем сама посылка, тогда гарантировано будут пустые символы на выходе и ничего никуда не пропадет
------------ Дoбавленo в 14.26:
Если пытаться читать по 50 мсек, то получится, что за это время устройство выдаст 2,5 кадра информации (вот откуда и получается, что попадаем, где-то, в середину, и прет рассинхронизация)

HikeR, короче, тебе надо менять концепцию схемы, иначе -- ничего у тебя не получится
карма: 22

0
Администрация
Ответов: 15295
Рейтинг: 1519
#9: 2010-01-15 15:22:52 ЛС | профиль | цитата
"пустой" символ это с кодом 0 видимо? И откуда информация о том, что им заканчиваются 18ти байтные пакеты?
карма: 27
0
Разработчик
Ответов: 26160
Рейтинг: 2127
#10: 2010-01-15 15:28:04 ЛС | профиль | цитата
Dilma писал(а):
И откуда информация о том, что им заканчиваются 18ти байтные пакеты?

Я этого не говорил, что им закончится посылка в 18 байт, и описал, как получать пустые символы
nesco писал(а):
для нормальной синхронизации по пустому символу читать надо быстрее, нежели устройство подает свои данные, но медленне, чем сама посылка, тогда гарантировано будут пустые символы на выходе и ничего никуда не пропадет
HikeR писал(а):
имеется железка, которая раз в 20мс шлет пакетик длительностью 1.5-2.0мс

Вот тут, при потере кадра, если установить время меньше, чем длительностть между посылками (это время у нас в компоненте определяет и тйамаут потери кадра, оно на все у нас там стоит), устройством будет обнаружена потеря кадра и выставлен нулевой символ конца посылки
карма: 22

0
Гость
Ответов: 17029
Рейтинг: 0
#11: 2010-01-15 17:30:15 правка | ЛС | профиль | цитата


Редактировалось 1 раз(а), последний 2017-03-05 04:42:42
карма: 0

0
Ответов: 499
Рейтинг: 1
#12: 2010-01-15 17:32:27 ЛС | профиль | цитата
вобщем, это я был.
про изменение SetLength(Buffer,256); можно не читать, это дезинформация ;)
карма: 0

0
Разработчик
Ответов: 26160
Рейтинг: 2127
#13: 2010-01-15 17:41:31 ЛС | профиль | цитата
HikeR писал(а):
вобщем, это я был

Ты хочешь сказать, что у тебя, при интрвале <20 мсек и длине считывания буфера 18 байт (кстати, а у тебя сколько стоит), не появляются пустые символы, такого быть не может. При считывании буфера FIFO, автоматически происходит его уменьшение на количество считанных байт, и если их только 18, и считываем их только 18, то в буфере FIFO будет 0, до следующей посылки.
Ты можешь дать последовательность твоего устройства, записей, этак, на 100, ну на крайняк -- 50, естественно, разных. Специально врублю виртуалку, сделаю эмулятор посылок и проверю, но вечером, дома. Если тебе, конечно, это очень интересно и нужна моя помощь. Можешь еще и схемку прицепить, что бы меньше возни было
карма: 22

0
Ответов: 499
Рейтинг: 1
#14: 2010-01-15 18:37:44 ЛС | профиль | цитата
пустые символы не появляются. идет бурст в 18 байт, через ~20мс он повторяется, в перерывах - ничего нет. если не обнулять буфер порта через точку doRXClear - он будет просто увеличиваться.
nesco писал(а):
можешь дать последовательность твоего устройства, записей, этак, на 100

а есть какой-нить порт-монитор, который в лог накидал бы все что идет с порта с временными отметками? без него только так последовательность могу описать:
...
85 252 (еще 16 байт) ~20 мс пауза
85 252 (еще 16 байт) ~20 мс пауза
85 252 (еще 16 байт) ~20 мс пауза
85 252 (еще 16 байт) ~20 мс пауза
...

если быть точнее, то вот что я захватываю (выборка из сотни пакетов):
55,FC,04,3E,04,38,07,92,05,E7,05,E9,04,43,00,9D,03,D5,
55,FC,04,41,04,38,07,90,05,E8,05,E9,04,46,00,9E,03,DB,
55,FC,04,41,04,38,07,90,05,E8,05,E9,04,46,00,9E,03,DB,
...
однако иногда возьмет да появится нечто подобное:
55,FC,04,41,04,38,07,90,05,E7,05,E9,04,46,00,9E,03,DA,
04,37,07,92,05,E8,05,E9,04,43,00,9D,03,D8,
55,FC,04,3E,04,38,07,92,05,E7,05,E9,04,43,00,9D,03,D5,
...
то есть потерялось 4 первых байта. или вот так:
55,FC,04,40,04,37,07,92,05,E7,05,E8,04,44,00,9D,03,D6,
E9,04,44,00,9D,03,D7,
55,FC,04,40,04,37,07,92,05,E7,05,E9,04,44,00,9D,03,D7,
то почти полстроки обрезалось.

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

карма: 0

0
Разработчик
Ответов: 26160
Рейтинг: 2127
#15: 2010-01-15 19:46:30 ЛС | профиль | цитата
HikeR писал(а):
пустые символы не появляются. идет бурст в 18 байт, через ~20мс он повторяется

20mc пауза же есть, значит, можно выловить пустой буфер

А что, терминалку подключить не вариант и записать потом полученные данные
карма: 22

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)