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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отправить запрос в COM порт, подождать, прочитать, Общение с устройством 
:(
    Опции темы
mr_smit
  Дата 26.3.2015, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть железка которая через переходник USB-RS485 подключена к компьютеру. Протокол простейший. 

Пример
Отправляем: AB CD 01 01 86
Ответ: DC BA 01 01 68
и т.д.

Через терминал всё прекрасно работает. Задача отобразить получаемые данные в программе. Поставил компонент AsyncFree. Но не понимаю как подождать ответа от железки? Она отвечает сразу после получения запроса.

Код

var
  Form1: TForm1;
  Zapros: array[0..4] of byte = ($AB,$CD,$01,$01,$86);
  ReadBuffer: array[0..254] of byte;
  CurrentPos: integer;

...

procedure TForm1.AfComPort1DataRecived(Sender: TObject; Count: Integer);
begin
  AfComPort1.ReadData(ReadBuffer[CurrentPos], Count);
  Inc(CurrentPos, Count);
  
  Label1.Caption:= IntToHex(ReadBuffer[3],2);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  CurrentPos:=0;
  AfComPort1.WriteData(Zapros, length(Zapros));
end;


Я посылаю запрос по таймеру раз секунду.
1-й запрос -> значение в label1 ноль
2-й запрос -> значение в label1 из 1-го запроса
3-й запрос -> значение в label1 из 2-го запроса
4-й запрос -> значение в label1 из 3-го запроса

Надо:
1-й запрос -> значение в label1 из 1-го запроса
2-й запрос -> значение в label1 из 2-го запроса
3-й запрос -> значение в label1 из 3-го запроса

Я понимаю что читаю данные до того как железка ответила. Но как подождать ответа??

Перечитал кучу статей, но нигде этот момент подробно не описан. Как можно сделать? Другой компонент, руками, всё равно. Лишь бы заработало. Спасибо.

Это сообщение отредактировал(а) mr_smit - 26.3.2015, 11:55
PM MAIL   Вверх
CynicRus
Дата 26.3.2015, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Руками, с помощью WaitCommEvent.

MSDN

Ну и чтобы не тормозило, поместить обработку в тред. При этом работать с портом при помощи WinAPI.
PM MAIL   Вверх
mr_smit
  Дата 26.3.2015, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хочется простой готовый пример. MSDN не по силам. Программа из одной кнопки "Старт" и Label. Я точно знаю какой длины должен быть ответ. Но не понимаю как его принять.

Т.е. получается:
1. Один раз в секунду тикнул таймер и мы отправляем запрос;
2. Сидим и ждем пока нам придет 5 байт... Ответ всегда приходит после того как полностью передастся запрос;
3. Пришло? Считаем контрольную сумму и т.д...
4. Если всё хорошо, то отображаем 4-й байт в Label;
5. Повторяем пункты 1-4 до бесконечности.

Это сообщение отредактировал(а) mr_smit - 26.3.2015, 13:07
PM MAIL   Вверх
Beltar
Дата 26.3.2015, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Гонять чтение, пока не дождешься ответа, это порядка 100-200 мс, если совсем по-тупому:

Код

repeat
AfComPort1.ReadData(ReadBuffer[CurrentPos], Count);
Application.ProcessMessage;
Sleep(10);
until <УсловиеВыхода>;


Я себе вот такую штуку делал когда-то, на основе слизанного откуда-то кода, здесь чтение в потоке.

Проект я маленько подредактировал в XE6 (явно объявил ANSIString вместо String), но там бэкапы от 2007 и XE (12.2) есть, да и вообще нет ничего, что не подошло бы даже для D7, ибо в ней изначально писалось.

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  Копия_RTUCOMPort.rar 212,81 Kb


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
mr_smit
Дата 26.3.2015, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

procedure TForm1.AfComPort1DataRecived(Sender: TObject; Count: Integer);
begin
  AfComPort1.ReadData(ReadBuffer[CurrentPos], Count);
  Inc(CurrentPos, Count);
  
  if CurrentPos >= 3 then Label1.Caption:= IntToHex(ReadBuffer[3],2);
end;

Всё гениальное просто! Работает.
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.1155 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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