Вверх ↑
Этот топик читают: Гость
Ответов: 36
Рейтинг: 7
#1: 2011-10-31 19:16:59 ЛС | профиль | цитата
Подскажите пожалуйста как сделать такую схемку:

По ком-порту приходят пакеты размером 10-20 байт, такого вида <02><n><data_byte_0><...><data_byte_n><crc><03>. Мне надо их как-то выдергивать из буфера и переводить каждый пакет в отдельную строку, чтобы легче было потом обрабатывать. Я так понимаю, надо взять массив, тип элементов которого беззнаковый int8 (0-255), скидывать туда все, потом перебирать и ловить начало пакета (02), потом отсчитывать n байт и ловить конец пакета (03). После этого перевести его в строку и удалить из массива. На си это выглядело бы примерно так:

code_25627.txt
а как сделать это на элементах в хай-асме пока не могу понять. Киньте плиз пару идеек.
карма: 0

0
файлы: 1code_25627.txt [633B] [88]
Ответов: 704
Рейтинг: 7
#2: 2011-10-31 20:14:33 ЛС | профиль | цитата
wasp, пакеты идут хаотично-резанно или: <02><n><data_byte_0><...><data_byte_n><crc>, <03><n><data_byte_0><...><data_byte_n><crc>...?
------------ Дoбавленo в 19.06:
В примере не понятно идут ли они строками по 10-20 байт, или строго отдельными пакетами?
------------ Дoбавленo в 19.14:
Каждый пакет начинается с <0#* и заканчивается <crc>?
карма: 0

0
Ответов: 8928
Рейтинг: 823
#3: 2011-10-31 20:16:17 ЛС | профиль | цитата
wasp, СОМ порт уже выдаёт строку, нет необходимости переводить её в байты, а потом в строку начало и окончание блока <02> и <03> -- это символы или два байта цифр? Есть компонент в Строках BlockFind
карма: 19

0
Ответов: 704
Рейтинг: 7
#4: 2011-10-31 20:26:11 ЛС | профиль | цитата
Если все так - на выходе из порта ставите эдакую заморочку:
code_25628.txt

Загонять полученные результаты можно в обычный список строк StrList и сохранять в файл (если нужно).
В примере первая кнопка - начало передачи пакетов, а вторая - продолжение передачи (если пакеты рваные).
карма: 0

0
файлы: 1code_25628.txt [1KB] [152]
Ответов: 36
Рейтинг: 7
#5: 2011-10-31 20:28:16 ЛС | профиль | цитата
Neo, пакеты могут идти как угодно, с большими или маленькими паузами, или вообще без пауз - сразу друг за другом. Но каждый пакет всегда начинается байтом 02 и заканчивается 03 (Т.е. это не аски, а хекс). Эти 02 и 03 могут также встретиться и внутри пакета.

Neo писал(а):
В примере не понятно идут ли они строками по 10-20 байт, или строго отдельными пакетами?


Не, не строками, а просто набором байт и длина может варьироваться от 10 скажем до 20 байт, не суть важно.

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

Леонид писал(а):
начало и окончание блока <02> и <03> -- это символы или два байта цифр? Есть компонент в Строках BlockFind

два байта цифр, все что в скобках <...> - по одному байту
карма: 0

0
Ответов: 704
Рейтинг: 7
#6: 2011-10-31 20:36:36 ЛС | профиль | цитата
[offtop]Леонид, а как этим BlockFind тут развернуться? Эти же <02> и <03> будут меняться. [/offtop] Подумал, что 02-03-04-05 считает счетчик. Если бы BlockFind поддерживал маску...
------------ Дoбавленo в 19.34:
Так ловите сразу <crc><03> как конец пакета. Считать байты - как-то муторно.
------------ Дoбавленo в 19.36:
Хотя, возможно, считать здесь надежнее всего, но и затратнее всего.
карма: 0

0
Ответов: 36
Рейтинг: 7
#7: 2011-10-31 20:41:34 ЛС | профиль | цитата
Neo, crc - это проверочная сумма, как ее поймаешь, ее считать надо. Надо по-любому ловить 02, потом отсчитывать н байт, и тогда уже ясно где конец пакета.
карма: 0

0
Ответов: 8928
Рейтинг: 823
#8: 2011-10-31 20:52:22 ЛС | профиль | цитата
wasp, если и внутри пакета есть <0><2> и <0><3>, то как ловить начало/окончание
wasp писал(а):
<02><n>
, а n уж не количество-ли байт данных (неужели так трудно представить незнающего Ваших проблем и обрисовать задачу для него, чтобы было "необходимо и достаточно" )
карма: 19

0
Ответов: 3889
Рейтинг: 362
#9: 2011-10-31 20:59:20 ЛС | профиль | цитата
wasp писал(а):
Надо по-любому ловить 02, потом отсчитывать н байт, и тогда уже ясно где конец пакета.

Снимать целый дамп в поток, преобразовывать в HEX. Начиная со второго пакета можно "ловить" 03,02,n , отсчитав n убедиться, что дальше, (отступая на размер суммы), идёт 03 (а если за ним идёт ещё и 02...) , делать вывод о нахождении пакета и т.д. по циклу. Затратно, но можно считать и сумму для (n) байт сразу после 02,n и сравнивать с тем, что нашли перед 03. В общем, из-за слабой ориентированности базовых компонентов на бинарные данные, работать, видимо, придётся с дампом.
карма: 1

0
Ответов: 36
Рейтинг: 7
#10: 2011-10-31 21:13:07 ЛС | профиль | цитата
Леонид писал(а):
неужели так трудно представить незнающего Ваших проблем и обрисовать задачу для него, чтобы было "необходимо и достаточно"


попробую еще раз.
В угловых скобках стоит один байт информации. Первым байтом в пакете всегда идет STX (Start of Text). Последним - ETX (End of Text):

Dec Oct Hex Binary Value
--- --- --- -------- --------------------------
002 002 002 00000010 STX (Start of Text)
003 003 003 00000011 ETX (End of Text)

Вторым байтом всегда идет позиция, где стоит чексумма, но она всегда на предпоследнем месте (перед ETX), поэтому из нее легко узнается длина пакета, или количество полезных байт. Все что между вторым и предпоследним байтом - полезная информация. Ее длина может варьироваться. Никаких строк, ASCII, все в цифре.

Короче все вышесказанное выглядит так:
<02><n><data_byte_0><...><data_byte_n><crc><03>

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

Надеюсь щас стало немного понятней
------------ Дoбавленo в 20.13:
1nd1g0, все правильно, так я себе в уме и представляю, но в дескретных элементах - напряг. В сях бы без проблем...
карма: 0

0
Ответов: 3889
Рейтинг: 362
#11: 2011-10-31 21:24:24 ЛС | профиль | цитата
wasp писал(а):
Как это сделать, пока не соображу, поэтому прошу помощи.

Я же сказал, у нас есть

Add(Stream2Hex,663500,497,245)
{
}
один из самых удобных способов работы с бинарными данными тут - работать с полученной после конвертирования строкой. Бинарные данные обрабатывать не так удобно, к сожалению.
------------ Дoбавленo в 20.24:
Если ну очень хочется именно с бинарными работать (и героически изображать на дискретных элементах с циклами простейшие операции вроде поиска сигнатуры), то, вероятно,
Add(DataToFile,2821097,280,455)
{
link(Stream,16048424:Stream,[])
}
Add(MemoryStream,16048424,280,399)
{
}
карма: 1

0
Ответов: 3851
Рейтинг: 159
#12: 2011-10-31 22:28:32 ЛС | профиль | цитата

я тоже сначала переводил в HEX, но остановился на поиске символов "02" и "03", правда в моей задаче это были единственные символы в блоке - содержимое содержало только текст, никаких нелитерных символов. простой blockfind справился..
карма: 0
начавший
0
Ответов: 36
Рейтинг: 7
#13: 2011-11-01 00:00:42 ЛС | профиль | цитата
Andrey, а как вы боролись с разрывами пакетов при приеме?
или у вас их не было?
карма: 0

0
Ответов: 704
Рейтинг: 7
#14: 2011-11-01 01:22:24 ЛС | профиль | цитата
Кстати, была у меня подобная идея, но в другом направлении. Нужно было перебирать массив данных и находить логические цепочки по маскам, но с допусками по времени записи данных. Эдакий примитивный мозг. Но пока решил окольными путями и всячески пытаюсь уйти от проблемы - чувствую тщетно, она когда-то меня настигнет и придется мне пройти Ваш,wasp, путь
------------ Дoбавленo в 00.17:
wasp, ну так оставшиеся после обработки (рваные окончания данных) склеивайте через это, после конвертации в строку

Add(StrCat,8454029,189,238)
{
link(Str1,8454029:Result,[(195,226)(183,226)(183,282)(195,282)])
}


------------ Дoбавленo в 00.18:
И, опять же, если я понял проблему склейки верно, то в первом моем сообщении пример именно со склейкой оставшейся после разделения строки.
------------ Дoбавленo в 00.19:
Вместо остатка разделения вставляйте свой остаток и получите склейку при поступлении новых данных.
------------ Дoбавленo в 00.21:
Или и вовсе склеивайте пока строка не примет целый вид (закончится байтами окончания передачи) - тогда отправляйте на обработку заведомо правильную строку целых пакетов.
------------ Дoбавленo в 00.22:
Хотя с байтами сильно не дружу и советы даю в силу моего понимания проблемы.
карма: 0

0
Ответов: 8928
Рейтинг: 823
#15: 2011-11-01 17:12:40 ЛС | профиль | цитата
wasp,
Neo писал(а):
Хотя с байтами сильно не дружу
СОМ порт выдаёт СТРОКУ и незачем переводить её в другой формат.
Вот как я понял условия задачи (и как изложил бы): "На СОМ порт поступают данные в формате -- первые два байта символы "0" и "2" начало блока, третий байт содержит количество байт данных от 1 до 255, далее обозначенное количество байт данных, далее ещё один байт с контрольной суммой, и последние два байта символы "0" и "3" окончание блока".
Под это понимание схемка: com_data.rar
1. Данные с СОМ склеиваются в строку (пустую строку из СОМ блокируем) и дважды запоминаются
2. Перебираем в цикле запомненную в первой ячейке строку в поиске "02"
3. Есть "02" -- читаем следующий байт и превращаем его в число n (1--255) и сохраняем
4. Читаем n следующих байт и сохраняем в памяти
5. Читаем следующий байт и превращаем его в число -- контрольную сумму, сохраняем
6. Читаем следующие два байта
7. Если это "03"
7.1 Запомненные данные склеиваем как хочется и выдаём куда нужно
7.2 Копируем часть строки после найденых "03" во вторую ячейку памяти
8. По окончании перебора строки копируем вторую ячейку памяти в первую.
карма: 19

2
файлы: 1com_data.rar [3.2KB] [105]
Голосовали:wasp, Neo
Сообщение
...
Прикрепленные файлы
(файлы не залиты)