Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наставьте на путь истинный! Работа с устройством через "синий зуб" 
:(
    Опции темы
beard42
Дата 6.2.2010, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.7.2009

Репутация: нет
Всего: нет



Суть проблемы:
Есть устройство, с которого нужно переодически получать данные. Связь осществляется через Bluetooth. Для получения ответа от устройства ему нужно сначала послать запрос. Данные необходимо получать ежесекундно и соотносить их со временем.
При работе, когда устройство находится на пределе устройчивого соединения (т.е. расстояние между устройством и компьютером большое), наблюдаются нарушенияя связи (либо не доходит запрос, либо "мусор" приходит в ответе). Поэтому принимаемые данные приходится дополнительно обрабатывать. 
Сейчас все организовано так:
В отдельном процессе устанавливается таймер (через CreateWaitableTimer) и через WaitForMultipleObjects в методе Execute оживается. После этого устанавливается флаг, отправляется запрос на одну порцию данных и ждем, пока флаг не сбросится. При получении ответа, производится попытка его разбора (т.е. определяется что за данные пришли) и сбрасывается флаг. Далее увеличиваем счетчик запросов, выставляем флаг и отправляем запрос на вторую порцию. По тому же алгоритму ждем сброса флага. При разборе второй порции данных результаты первого и второго разбора отправляются в основной поток программы (через Synchronize), время отправки запоминается, счетчик запросов уменьшается. Если после разбора второй порции данных устанавливается, что счетчик запросов больше одного, то данные делятся на несколько порций, в соответствии со счетчиком запросов и каждая порция отправляется в основной поток. После отправки возвращаемся в Execute. 

Вот мы и добрались до сути вопроса. 
Проблема в том, что весь процесс отправки запросов, ожидания ответа и его разборки, ну и отправки полученного результата в основной поток, длится иногда больше, чем секунду. При этом, естественно, программа никак не отлавливает данный факт. :( 
Связь через ком-порт ведется при помощи модуля SerialNG (http://www.domis.de/serialng.htm).

Подскажите идею как все это лучше организовать. 

Я пока вижу только один выход. Разделить отправку/прием данных и их разбор/отправку в основной поток по разным потокам. Вот только как соотносить данные со временем и отслеживать "провалы" в принятых данных?
PM MAIL   Вверх
kami
Дата 6.2.2010, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(beard42 @  6.2.2010,  21:03 Найти цитируемый пост)
процесс отправки запросов, ожидания ответа и его разборки

А зачем ожидать ответ, если когда что-нибудь придет из порта, то возникнет событие OnRXчего_то_там?
Отправлять запросы ежесекундно, а принимать - когда получится.
PM MAIL WWW   Вверх
beard42
Дата 6.2.2010, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.7.2009

Репутация: нет
Всего: нет



Цитата(kami @  6.2.2010,  21:44 Найти цитируемый пост)
Отправлять запросы ежесекундно, а принимать - когда получится. 

А как определить к какому запросу относится ответ? А если он (ответ) только через секунду придет?

PM MAIL   Вверх
kami
Дата 7.2.2010, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(beard42 @  6.2.2010,  23:45 Найти цитируемый пост)
А как определить к какому запросу относится ответ?

Вот этого я не знаю, зато можете знать Вы. У Вас же в руках протокол обмена компьютер <=> устройство.
Цитата(beard42 @  6.2.2010,  23:45 Найти цитируемый пост)
А если он (ответ) только через секунду придет?

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

Есть ли разница, какой ответ какому запросу соответствует?
Если да - в качестве примера могу предложить следующее:
заводим буфер запросов FIFO (к примеру - в TStringList).
Отправляя очередной запрос в порт, помимо этого добавляем в stringList последним элементом.
Получив ответ - забираем первый запрос из списка в StringList и удаляем его оттуда. Полученный ответ и "выдернутый" запрос отдаем основному потоку.

Добавлено @ 01:00
Ну и в дополнение - Syncronize "отдает управление" основному потоку и ожидает окончания его работы в этой процедуре. Ибо основывается на SendMessage.
Если тип данных позволяет, я бы лучше воспользовался PostMessage, что позволит добиться бОльшей асинхронности. (то есть - отдали данные в основной поток, а когда он их получит и что будет с ними делать - уже не проблема потока, занимающегося транспортной частью. Его это не колышет и не приостанавливает работу на время, пока основной поток обработает данные).

Это сообщение отредактировал(а) kami - 7.2.2010, 01:03
PM MAIL WWW   Вверх
beard42
Дата 25.2.2010, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.7.2009

Репутация: нет
Всего: нет



Во-первых, спасибо за советы.
Во-вторых, извиняюсь за задержку с ответом.

Цитата(kami @  7.2.2010,  00:55 Найти цитируемый пост)
Syncronize "отдает управление" основному потоку и ожидает окончания его работы в этой процедуре. Ибо основывается на SendMessage.
Если тип данных позволяет, я бы лучше воспользовался PostMessage, что позволит добиться бОльшей асинхронности.

Да, у меня тоже были такие подозрения (что все дело в 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
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0636 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.