![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
beard42 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 16.7.2009 Репутация: нет Всего: нет |
Суть проблемы:
Есть устройство, с которого нужно переодически получать данные. Связь осществляется через Bluetooth. Для получения ответа от устройства ему нужно сначала послать запрос. Данные необходимо получать ежесекундно и соотносить их со временем. При работе, когда устройство находится на пределе устройчивого соединения (т.е. расстояние между устройством и компьютером большое), наблюдаются нарушенияя связи (либо не доходит запрос, либо "мусор" приходит в ответе). Поэтому принимаемые данные приходится дополнительно обрабатывать. Сейчас все организовано так: В отдельном процессе устанавливается таймер (через CreateWaitableTimer) и через WaitForMultipleObjects в методе Execute оживается. После этого устанавливается флаг, отправляется запрос на одну порцию данных и ждем, пока флаг не сбросится. При получении ответа, производится попытка его разбора (т.е. определяется что за данные пришли) и сбрасывается флаг. Далее увеличиваем счетчик запросов, выставляем флаг и отправляем запрос на вторую порцию. По тому же алгоритму ждем сброса флага. При разборе второй порции данных результаты первого и второго разбора отправляются в основной поток программы (через Synchronize), время отправки запоминается, счетчик запросов уменьшается. Если после разбора второй порции данных устанавливается, что счетчик запросов больше одного, то данные делятся на несколько порций, в соответствии со счетчиком запросов и каждая порция отправляется в основной поток. После отправки возвращаемся в Execute. Вот мы и добрались до сути вопроса. Проблема в том, что весь процесс отправки запросов, ожидания ответа и его разборки, ну и отправки полученного результата в основной поток, длится иногда больше, чем секунду. При этом, естественно, программа никак не отлавливает данный факт. :( Связь через ком-порт ведется при помощи модуля SerialNG (http://www.domis.de/serialng.htm). Подскажите идею как все это лучше организовать. Я пока вижу только один выход. Разделить отправку/прием данных и их разбор/отправку в основной поток по разным потокам. Вот только как соотносить данные со временем и отслеживать "провалы" в принятых данных? |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
||||
|
||||
beard42 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 16.7.2009 Репутация: нет Всего: нет |
||||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Вот этого я не знаю, зато можете знать Вы. У Вас же в руках протокол обмена компьютер <=> устройство. Ну опять-таки, вопрос не по адресу - я же не знаю, сколько времени это устройство обрабатывает запрос. Есть ли разница, какой ответ какому запросу соответствует? Если да - в качестве примера могу предложить следующее: заводим буфер запросов FIFO (к примеру - в TStringList). Отправляя очередной запрос в порт, помимо этого добавляем в stringList последним элементом. Получив ответ - забираем первый запрос из списка в StringList и удаляем его оттуда. Полученный ответ и "выдернутый" запрос отдаем основному потоку. Добавлено @ 01:00 Ну и в дополнение - Syncronize "отдает управление" основному потоку и ожидает окончания его работы в этой процедуре. Ибо основывается на SendMessage. Если тип данных позволяет, я бы лучше воспользовался PostMessage, что позволит добиться бОльшей асинхронности. (то есть - отдали данные в основной поток, а когда он их получит и что будет с ними делать - уже не проблема потока, занимающегося транспортной частью. Его это не колышет и не приостанавливает работу на время, пока основной поток обработает данные). Это сообщение отредактировал(а) kami - 7.2.2010, 01:03 |
|||
|
||||
beard42 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 16.7.2009 Репутация: нет Всего: нет |
Во-первых, спасибо за советы.
Во-вторых, извиняюсь за задержку с ответом. Да, у меня тоже были такие подозрения (что все дело в Synchronize). В итоге сделал модуль для тестирования, показывающий, когда что происходит. В результате выяснилось следующее: ожидание ответа занимает около 200 мс (итого около 400 мс). Потом запускается Synchronize. Вот тут возникают основные проблемы. Сейчас сделал так. Запускаю поток-синхронизатор (поток 1). Он создает очередь (мой класс с критической секцией при доступе с TList), событие и запускает поток, работающий с прибором (поток 2). Поток 2 создает таймер (CreateTimer, с автосбросом и периодом в 1 сек.) и ждет его срабатывания. После этого посылает запрос прибору, ожидает ответа, посылает второй запрос, ожидает второго ответа, записывает принятые данные в очередь и выставляет событие. Поток 1 ожидает событие от потока 2 и через Synchronize отправляет данные из очереди в VCL-поток. Что еще пробовал. Пробовал отправлять оба запроса одновременно. Но проблема в том, что работа с ком-портом ведется асинхронно с Overlapped, и ответы приходят "мешаниной". Пробовал не ждать, пока придет ответ. Но проблема в том, что когда приходит "мусор", очень трудно парсить ответ (хотя над этим вопросом сейчас думаю, надеюсь, что может быть тут еще немного выиграю). Из проблем осталось следующее: при тестовом прогоне (порядка 2х часов) обнаружилось 4 места, когда один запрос был утерян, но программа его не обнаружила. PS В VCL-поток передаются 2хDouble, Integer и TDataTime (время, когда строка от прибора пришла в программу). Это сообщение отредактировал(а) beard42 - 27.2.2010, 13:26 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |